描述你的问题
如下图,我在Activity中用到了Handler,然后在 Android Studio 中老是有一大块地黄色,主要是看不太明白。。。这是个warning吧。。。求大神翻译指导一下。。。 warning的内容是: This Handler class should be static or leaks might occur ... Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. if the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. if the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows : Declare the Handler as a staic class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakPreference object. 打完这段warning之后,是不是,建议把Handler弄成static,以方便其他的外部类直接访问这个Handler,以便更新UI线程?
贴上相关代码
//UI线程的Handler private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 0x01:{ destoryWaitDialog(); okLand(); break; } case 0x02:{ destoryWaitDialog(); waringLand(); break; } } } };
贴上相关截图
提示信息描述的相当清楚了,因为是内部类,可能会导致外部类无法被回收。关键在于handler使用的Looper和消息队列是否主线程所拥有,如果是的话,处理方式就是:
首先 handler声明为static;
然后 外部类使用弱引用的方式传递给handler;
最后 外部类的所有成员均使用弱引用的方式访问。
最最后,以上全部都在提示信息里,完全可以通过翻译搞明白...关键问题是持有引用没有释放导致内存无法回收
将 Handler
定义为 Activity
的 内部类
会容易导致 内存泄露
,解决的方法就是让 Handler
静态化,不直接引用 Activity
的实例。
这个warning是提示,这样使用Handler是不推荐的,因为会造成内存泄漏。
解决方法一如下:(我觉得比较好的一个方法)
使用静态的内部类去定义一个 MyHandler
使用弱引用传递
其中:
声明了为静态的,是为了断掉外部内持有Handler的引用:
private static class MyHandler extends Handler {}
但是,若我的 MyHandler 声明为 static,则,其内部的使用其他方法必须为
静态的(这怎么可能。。。),解决方法是使用弱引用WeakReference。。。
WeakReference的一个特点是它何时被回收是不可确定的, 因为这是由GC运行的不确定性所确定的. 所以, 一般用weak reference引用的对象是有价值被cache, 而且很容易被重新被构建, 且很消耗内存的对象.
我写的 MyHandler 如下:
private static class MyHandler extends Handler { private final WeakReference<RegisterLandActivity> mActivity; private MyHandler(RegisterLandActivity mActivity) { this.mActivity = new WeakReference<RegisterLandActivity>(mActivity); } @Override public void handleMessage(Message msg) { switch (msg.what) { case 0x01:{ //成功登录 mActivity.get().destoryWaitDialog(); mActivity.get().okLand(); mActivity.get().goToPlantGarden(); break; } case 0x02:{ //登录失败 mActivity.get().destoryWaitDialog(); mActivity.get().waringLand(); break; } case 0x03:{ //成功注册 mActivity.get().destoryWaitDialog(); mActivity.get().okRegister(); mActivity.get().goToPlantGarden(); break; } case 0x04:{ //注册失败 mActivity.get().destoryWaitDialog(); mActivity.get().waringRegister(); break; } } } }
其中,构造方法便使用了弱引入传递Activity,使用 mActivity.get() 能得到原来 activity 的引用。 定义好之后,这样声明即可: MyHandler handler = new MyHandler(this);