标签:
参考:http://www.cnblogs.com/kissazi2/p/4121852.html
为什么 内部自定义handler类要static类型?
原因:
1、当一个Android应用程序第一次启动时,Android框架为应用程序的主线程创建一个Looper对象。一个Looper实现了一个简单的消息队列,在一个循环中处理Message对象。所有主要的应用程序框架事件(如活动生命周期方法调用,单击按钮,等等)都包含在Message对象,它被添加到Looper的消息队列然后一个个被处理。主线程的Looper在应用程序的整个生命周期中存在。
2、当一个Handle在主线程被实例化,它就被关联到Looper的消息队列。被发送到消息队列的消息会持有一个Handler的引用,以便Android框架可以在Looper最终处理这个消息的时候,调用Handler#handleMessage(Message)。
3、在Java中,非静态的内部类和匿名类会隐式地持有一个他们外部类的引用。静态内部类则不会
解释:handler中的消息持有handler的引用,handler又是个匿名内部类持有activity的对象.如果msg是个延时操作那么当actvity finish的时候,act的引用被持有,造成 activity中的对象都不会释放 造成内存泄露.
正确的代码:
1.handler 和 runable方法都声明static 即 凡是在handler中使用的内部类(不能使用匿名类) 都要声明为static 类型
2.handler中要持有 activity或者 context对象需要使用 弱引用
public class SampleActivity extends Activity { /** * 匿名类的静态实例不会隐式持有他们外部类的引用 */ private static final Runnable sRunnable = new Runnable() { @Override public void run() { } }; private final MyHandler mHandler = new MyHandler(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 延时10分钟发送一个消息. mHandler.postDelayed(sRunnable, 60 * 10 * 1000); // 返回前一个Activity finish(); } /** * 静态内部类的实例不会隐式持有他们外部类的引用。 */ private static class MyHandler extends Handler { private final WeakReference<SampleActivity> mActivity; public MyHandler(SampleActivity activity) { mActivity = new WeakReference<SampleActivity>(activity); } @Override public void handleMessage(Message msg) { SampleActivity activity = mActivity.get(); if (activity != null) { // ... } } } }
标签:
原文地址:http://www.cnblogs.com/wjw334/p/4488427.html