内部类与内存泄漏(Handler,Runnable)
来源:互联网 发布:mac快捷键 编辑:程序博客网 时间:2024/05/17 07:08
利用多线程+Handler来完成UI的交互是常见的操作,而匿名Runnable对象的使用也是在多线程使用时常用的,那么使用时会在什么情况下导致内存泄漏的发生呢?
- 首先看以下的代码:
<span style="white-space:pre"></span>public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mLeakHandler.postDelayed(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stub}}, 60*60*1000);}private final Handler mLeakHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);}};}
- Android lint工具中会有以下的警告信息:
ThisHandler class should be static or leaks might occur
- 内存泄漏如何会发生呢?首先看以下的知识:
- android应用第一次启动时,framework会在主线中创建一个Looper对象(Looper对象实现了一个简单的消息队列,生命周期跟应用相同,其管理的消息包括Activity lifecycle方法的调用,Button点击事件,当然也包括我们主动调用的,handler.sendMessage)
- 当Handler对象在主线程实例化以后,其就会与Looper消息队列关联到一起,队列上的Message对象持有Handler引用,使得Looper处理某个消息时,会调用Hander#handlerMessage方法。
- java中,非静态内部类和匿名内部类持有隐式的外部类引用,而静态内部类没有隐式引用。
- 当Activity finish之后,延迟处理消息在主线程消息队列中保持1个小时,知道消息最终处理,消息中有Handler引用,而Handler有外部类MainActivity引用,这样Activity的Context就不能被回收,匿名Runnable对象同理
- 如何修改原来的程序?
只需要将Handler类和Runnable改为静态内部类。
如何调用外部类的方法?
可以通过内部静态类持有外部类的弱引用来实现;
- 具体修改代码如下:
<pre name="code" class="java">protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mHandler.postDelayed(mRunnable, 60*60*1000);}private static class MyHandler extends Handler {private final WeakReference<MainActivity> mActivity;public MyHandler(MainActivity activity) {mActivity = new WeakReference<MainActivity>(activity);}@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);}}private final MyHandler mHandler = new MyHandler(this);private static Runnable mRunnable = new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stub}};
- 其他:
- PendingIntent的send方法,如果某个类调用PendingIntent.send(),并且传入非静态内部类Handler类,也会导致内存泄漏;
- 如果想要重用,可以创建一个通用类:
public abstract class WeakReferenceHandler<T> extends Handler {private WeakReference<T> mReference;public WeakReferenceHandler(T reference) {mReference = new WeakReference<T>(reference);}@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);if(mReference.get() == null)return ;handleMessage(mReference.get(), msg);}protected abstract void handleMessage(T reference, Message msg);}private final MyHandler2 mHandler2 = new MyHandler2(this);private static class MyHandler2 extends WeakReferenceHandler<MainActivity> {public MyHandler2(MainActivity reference) {super(reference);// TODO Auto-generated constructor stub}@Overrideprotected void handleMessage(MainActivity reference, Message msg) {// TODO Auto-generated method stub}}
0 0
- 内部类与内存泄漏(Handler,Runnable)
- 自定义Handler使用静态内部类避免内存泄漏
- 自定义无内存泄漏的Handler内部类
- 内部类Handler引发的内存泄漏问题
- Handler或Runnable作为非静态内部类,引发的内存泄露问题
- 怎么使Handler净身出户(非静态内部类和匿名内部类造成内存泄漏)
- 内存泄漏之内部类handler()
- 内存泄漏之内部类new Handler();
- 内存优化-内存泄漏处理内部类
- 内部类导致内存泄漏的情况
- 匿名内部类造成的内存泄漏
- Java内存泄漏之静态内部类
- Context内存泄露:Handler&内部类
- Java内部类的实现原理与可能的内存泄漏
- Java内部类的实现原理与可能的内存泄漏
- 静态内部类与android handler
- 匿名内部类持外部引用造成内存泄漏问题
- 非静态内部类造成的内存泄漏
- 【剑指offer】八皇后问题
- C# WINFORM 某些控件实现联想输入功能
- 个人使用Linux操作系统常要做的事
- C++学习笔记9,堆栈与堆的区别
- 1142A Walk Through the Forest
- 内部类与内存泄漏(Handler,Runnable)
- css box-sizing
- Eclipse 插件整理
- Period - POJ 1961 KMP
- UML图(九) 部署图
- QT QTableView用法
- 剑指offer面试题3
- Power Strings - POJ 2406 KMP
- MSP430F247串口发送字符串并接受PC机发来的单字符并送回电脑显示