安卓Handler内存泄漏

来源:互联网 发布:数据保密 编辑:程序博客网 时间:2024/06/10 16:42

     说来惭愧,工作这么多年,竟然一直忽略了这个问题,今天来讲讲,首先你要知道内存泄漏,相对于安卓来说“泄漏”就是添加,系统分配给每个应用的内存大小一定,如何利用好内存尤为重要,如果我们的对象不能被垃圾回收机制及时回收就会出现内存泄漏,导致最后内存占用越来越大,出现OOM(内存溢出)最后可能导致应用FC(强制关闭);

    垃圾回收机制原则:一个对象不被任何引用指向  会被GC发现回收

    Handler内存泄漏原因:内部类对象持有外部类对象的引用(Activity销毁时,Handler还有Activity的引用)  

    Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        mImageView.setImageBitmap(mBitmap);       }    }

     一般我们会这样用,这个时候Hanlder作为Activity的内部类,就会持有Activity的对象,(比如Handler需要处理很多的消息,但是这时候Activity退出了,那么垃圾回收不会回收他的对象,因为Hanlder需要处理消息,所以不会销毁,但是他不销毁又持有Activity的对象,所以Activity也不会销毁,导致内存泄漏)

     通用解决方法:用外部类

     首先直接实例Handler的子类,不在用匿名内部类,因为要操作Activity中的东西,所以构造方法中传入Activity

   private final Handler mHandler = new MyHandler(this);

    

   private static class MyHandler extends Handler {        private final WeakReference<HandlerActivity2> mActivity;        public MyHandler(HandlerActivity2 activity) {            mActivity = new WeakReference<HandlerActivity2>(activity);        }        public void handleMessage(Message msg) {            System.out.println(msg);            if (mActivity.get() == null) {                return;            }            mActivity.get().todo();        }

     其中mActivity.get()会获取到Activity对象,todo()是自己写的一个方法,可以在里面写自己的逻辑,在构造方法中传入Activity对象,用弱应用连接,当Activity销毁,弱应用连接断掉,if判断这儿拿不到activity对象,就会直接return,那么这个Handler的子类不再持有activity的引用,所以垃圾回收就能回收activity了,但是还有点问题,既然Activity已经退出,那么Handler发送处理消息就没必要了,所以还要停止Handler

public void onDestroy() {    //  If null, all callbacks and messages will be removed.    mHandler.removeCallbacksAndMessages(null);}

    上一个总体代码,宏观把控一下:

    

/** *  * 实现的主要功能。 *  * @version 1.0.0 * @author Abay Zhuang <br/> *         Create at 2014-7-28 */public class HandlerActivity2 extends Activity {    private static final int MESSAGE_1 = 1;    private static final int MESSAGE_2 = 2;    private static final int MESSAGE_3 = 3;    private final Handler mHandler = new MyHandler(this);    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mHandler.sendMessageDelayed(Message.obtain(), 60000);        // just finish this activity        finish();    }    public void todo() {    };    private static class MyHandler extends Handler {        private final WeakReference<HandlerActivity2> mActivity;        public MyHandler(HandlerActivity2 activity) {            mActivity = new WeakReference<HandlerActivity2>(activity);        }        @Override        public void handleMessage(Message msg) {            System.out.println(msg);            if (mActivity.get() == null) {                return;            }            mActivity.get().todo();        }    }
     记着写onDestory()方法。。。。
    


1 0
原创粉丝点击