【转】内部Handler类引起内存泄露
如果您在Activity中定义了一个内部Handler类,如下代码:
public class MainActivity extends Activity {
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//TODO handle message...
}
};
@TargetApi(11)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler.sendMessageDelayed(Message.obtain(), 60000);
//just finish this activity
finish();
}
}
然后运行Android Lint工具会有一个内存泄露警告:
This Handler class should be static or leaks might occur (com.example.ta.MainActivity.)
Issue: Ensures that Handler classes do not hold on to a reference to an outer class
Id: HandlerLeak
In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread’s MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.
原因是:
- 当Android应用启动的时候,会先创建一个应用主线程的Looper对象,Looper实现了一个简单的消息队列,一个一个的处理里面的Message对象。主线程Looper对象在整个应用生命周期中存在。
- 当在主线程中初始化Handler时,该Handler和Looper的消息队列关联。发送到消息队列的Message会引用发送该消息的Handler对象,这样系统可以调用 Handler#handleMessage(Message) 来分发处理该消息。
- 在Java中,非静态(匿名)内部类会引用外部类对象。而静态内部类不会引用外部类对象。
- 如果外部类是Activity,则会引起Activity泄露 。
当Activity finish后,延时消息会继续存在主线程消息队列中1分钟,然后处理消息。而该消息引用了Activity的Handler对象,然后这个Handler又引用了这个Activity。这些引用对象会保持到该消息被处理完,这样就导致该Activity对象无法被回收,从而导致了上面说的 Activity泄露。
要修改该问题,只需要按照Lint提示的那样,把Handler类定义为静态即可,然后通过WeakReference 来保持外部的Activity对象。
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler{
private final WeakReference<Activity> mActivity;
public MyHandler(Activity activity) {
mActivity = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
System.out.println(msg);
if(mActivity.get() == null) {
return;
}
}
}
所以,当你在Activity中使用内部类的时候,需要时刻考虑您是否可以控制该内部类的生命周期,如果不可以,则最好定义为静态内部类。
原文:http://blog.chengyunfeng.com/?p=468
【转】内部Handler类引起内存泄露的更多相关文章
- Android handler 可能会造成内存泄露
Android handler 可能会造成内存泄露 Android Studio 使用 Handler 时: private Handler handler = new Handler(){ @Ove ...
- Android 中 Handler 引起的内存泄露
在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下.http://w ...
- Handler 引起的内存泄露
先看一组简单的代码 1 2 3 4 5 6 7 8 9 public class SampleActivity extends Activity { private final Handler mHa ...
- Android 从java字节码告诉你 为什么Handler会造成内存泄露
很多人面试的时候,都知道Handler 极易造成内存泄露,但是有一些讲不出来为什么,好一点的 会告诉你looper msg 之类的,但是你再往下问 为什么msg持有handler handler为什么 ...
- Android中Handler引起的内存泄露
在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. 1 2 3 4 5 6 7 8 9 public class SampleActivit ...
- Handler引起的内存泄露
一般我都写handler的时候是这样的: public class MyActivity extends Activity{ private final Handler myHandler = n ...
- 4类 JavaScript 内存泄露及如何避免
原文:4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them笔记:涂鸦码龙 译者注:本文并没有逐字逐句的翻译,而是把我认为重要 ...
- AndroidStudio中Handler类的内存溢出风险
package com.test.king.xmlparser; import android.annotation.SuppressLint; import android.app.Activity ...
- Android中Handler导致的内存泄露
http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html Consider the follo ...
随机推荐
- [JAVA词形还原工具]Snowball
demo:http://snowball.tartarus.org/demo.php jar download:http://snowball.tartarus.org/download.php (J ...
- Js调用Java方法并互相传参
Js通过PhoneGap调用Java方法并互相传参的. 一.JAVA代码 写一个类,该类继承自Plugin并重写execute方法. import org.json.JSONArray; import ...
- Python 之 lambda 函数
Python 支持一种单行匿名函数,这种函数称为 lambda,它最初借鉴自 Lisp. >>> add = lambda x, y: x +y >>> add(3 ...
- 关于在for循环中绑定事件打印变量i是最后一次。
其实函数引用的外部变量都是最后一次的值. <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- [Python] Remote debugging by Pycharm
From: http://blog.csdn.net/u013088062/article/details/50170551 虚拟环境配置 配置远程解释器 设想这样一种情况,你在一个平台上操作你的工程 ...
- MPU9250调试
MPU9250 芯片概述 MPU9250芯片是一个9轴姿态传感芯片,其中包含了3轴加速度传感器.3轴角速度传感器以及三轴磁力计. 其本质上是MPU6050芯片+AK8963. 可以获取传感芯片的加速度 ...
- Nginx: could not build the server_names_hash 解决办法
# /etc/init.d/nginx reload * Reloading nginx configuration nginx [fail] # nginx -t nginx: [emerg] co ...
- 分享几个cocos2dx的小游戏
先上几个自己写的,因为最近要用cocos2dx,所以就边学边开发几个小游戏玩玩,有捕鱼,连连看,还有打地鼠!都不算完整的项目,不过拿来学习还是可以的,或者在基础上再二次开发,扩展自己! 1:捕鱼的 先 ...
- 复利程序(c语言)(张俊毅 周修文)
因为之前发烧一直没有了解这个 所以最近才补上 分数扣了就扣了 补上先 单元测试迟点更 #include<stdio.h> #include <math.h> #include ...
- ASP.NEt MVC5--创建下拉列表
Adding Search by Genre If you added the HttpPost version of the Index method, delete it now. Next, ...