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