说来惭愧,工作这么多年,竟然一直忽略了这个问题,今天来讲讲,首先你要知道内存泄漏,相对于安卓来说“泄漏”就是添加,系统分配给每个应用的内存大小一定,如何利用好内存尤为重要,如果我们的对象不能被垃圾回收机制及时回收就会出现内存泄漏,导致最后内存占用越来越大,出现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()方法。。。。
新闻热点
疑难解答