首先咱们来看一段代码java
public class AutoActivity extends Activity { Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_auto); } }
上面这段低吗没有什么问题,可是在handler对象建立的时候却会报警告:This Handler class should be static or leaks might occur意思是:Handlerandroid
类应该为static类型,不然可能会形成内存泄漏。为何会形成这种状况呢?这种状况就是因为android的特殊机制形成的:当一个android主线程被创ide
建的时候,同时会有一个Looper对象被建立,而这个Looper对象会实现一个MessageQueue(消息队列),当咱们建立一个handler对象时,而handler的oop
做用就是放入和取出消息从这个消息队列中,每当咱们经过handler将一个msg放入消息队列时,这个msg就会持有一个handler对象的引用。所以当this
Activity被结束后,这个msg在被取出来以前,这msg会继续存活,可是这个msg持有handler的引用,而handler在Activity中建立,会持有Activity的引用,google
于是当Activity结束后,Activity对象并不可以被gc回收,于是出现内存泄漏。spa
这个根本缘由就是:Activity在被结束以后,MessageQueue并不会随之被结束,若是这个消息队列中存在msg,则致使持有handler的引用,可是又线程
因为Activity被结束了,msg没法被处理,从而致使永久持有handler对象,handler永久持有Activity对象,因而发生内存泄漏。可是为何为static类型就code
会解决这个问题呢?由于在java中全部非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持orm
有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却没法回收的状况。(至于为何强引用不可以被gc自动回收,而
弱引用对象为何会被gc回收,能够自行去google)。
因此解决这个警告就有几种方法:
一:将hanlder对象声明为静态的对象。
二:使用静态内部类,经过WeakReference实现对Activity的弱引用。具体实现看如下代码:
public class AutoActivity extends Activity { MyHandler handler = new MyHandler(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_auto); } static class MyHandler extends Handler{ WeakReference<AutoActivity> mactivity; public MyHandler(AutoActivity activity){ mactivity = new WeakReference<AutoActivity>(activity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 100: //在这里面处理msg //经过mactivity.get()获取Activity的引用(即上下文context) break; default: break; } } } }