Android Handler导致的内存泄漏分析解决

问题代码:

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_my_imageview_load);

		mHandler.sendEmptyMessageDelayed(1, 11000);

	}

	Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			todo();
		};
	};

	private void todo() {
		Toast.makeText(this, "aa", Toast.LENGTH_SHORT).show();
	}

大概意思是将Handler改成静态要不就会出现内存泄漏。

原因

1、在Java中,非静态(匿名)内部类会默认隐性引用外部类对象。而静态内部类不会引用外部类对象;这里外部类是Activity,造成了Activity的泄漏

2、Activity finish之后,Activity已经可以被回收,但是handler处理消息的时候又使用到了Activity,使得Activity不能被回收造成泄漏

解决办法:

静态内部类、弱引用、正面周期控制

public class LruCacheDemoActivity extends Activity {

	MyHandler mHandler = new MyHandler(this);

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_my_imageview_load);

		// 时间尽量长一些,保证finish后Activity被回收。
		mHandler.sendEmptyMessageDelayed(1, 11000);

	}

	static class MyHandler extends Handler {
		WeakReference<LruCacheDemoActivity> weakReference;

		public MyHandler(LruCacheDemoActivity activity) {
			weakReference = new WeakReference<LruCacheDemoActivity>(activity);
		}

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			LruCacheDemoActivity activity = weakReference.get();
			if (null == activity) {
				return;
			}

			activity.todo();
		}
	}

	private void todo() {
		Toast.makeText(this, "aa", Toast.LENGTH_SHORT).show();
	}

	public void btn(View v) {
		finish();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// 当Activity finish后 handler对象还是在Message中排队。 还是会处理消息,这些是没用的操作
		// 正常Activitiy finish后,已经没有必要对消息处理
		// 解决办法很简单,在Activity onStop或者onDestroy的时候,取消掉该Handler对象的Message和Runnable
		mHandler.removeCallbacksAndMessages(null);
	}
}

猜你喜欢

转载自blog.csdn.net/u013359807/article/details/80431837