Handler 非静态内部引起的内存泄漏问题

感谢:Android中使用Handler引发的内存泄露

看到这里,可能还是有一些搞不清楚,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下。

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之后 消息仍然存在消息队列中,最好把他们移除
	}

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值