看到这里,可能还是有一些搞不清楚,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下。
1.当一个Android应用启动的时候,会自动创建一个供应用主线程使用的Looper实例。Looper的主要工作就是一个一个处理消息队列中 的消息对象。在Android中,所有Android框架的事件(比如Activity的生命周期方法调用和按钮点击等)都是放入到消息中,然后加入到 Looper要处理的消息队列中,由Looper负责一条一条地进行处理。主线程中的Looper生命周期和当前应用一样长。
2.当一个Handler在主线程进行了初始化之后,我们发送一个target为这个Handler的消息到Looper处理的消息队列时,实际上 已经发送的消息已经包含了一个Handler实例的引用,只有这样Looper在处理到这条消息时才可以调用 Handler#handleMessage(Message)完成消息的正确处理。
3.在Java中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用。静态的内部类不会持有外部类的引用。
当Activity finish后 handler对象还是在Message中排队。 还是会处理消息,这些处理有必要? 正常Activitiy finish后,已经没有必要对消息处理,那需要怎么做呢? 解决方案也很简单,在Activity onStop或者onDestroy的时候,取消掉该Handler对象的Message和Runnable。 通过查看Handler的API,它有几个方法:removeCallbacks(Runnable r)和removeMessages(int what)等。
/** * 一切都是为了不要让mHandler拖泥带水 */ @Override public void onDestroy() { mHandler.removeMessages(MESSAGE_1); mHandler.removeMessages(MESSAGE_2); mHandler.removeMessages(MESSAGE_3); // ... ... mHandler.removeCallbacks(mRunnable); // ... ... } <pre name="code" class="java">//也可以这样 @Override public void onDestroy() { // If null, all callbacks and messages will be removed. mHandler.removeCallbacksAndMessages(null); }
package com.tjove.ipcdemo;
import java.lang.ref.WeakReference;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class Demo4 extends Activity{
MyHandler handler=new MyHandler(this);
private static class MyHandler extends Handler{
WeakReference<Activity> weakReference=null;
public MyHandler(Activity activity) {
weakReference=new WeakReference<Activity>(activity);
}
public void handleMessage(android.os.Message msg) {
Demo4 activity=(Demo4) weakReference.get();
if (weakReference.get()!=null) {
Log.e("tag", "@@@@@@@@@@@@@@@@@@@@@@@@"+activity.getTaskId());
}else {
Log.e("tag", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.sendMessageDelayed(Message.obtain(), 2000);
finish();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
handler.removeCallbacksAndMessages(null);//finish之后 消息仍然存在消息队列中,最好把他们移除
}
}