Android handler 可能会造成内存泄露
Android handler 可能会造成内存泄露
Android Studio
使用 Handler 时;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// handle something
}
};
Android Studio 弹出了警告;
This Handler class should be static or leaks might occur (null) less... (Ctrl+F1)
Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object.
如果这个Handler用的是主线程外的Looper或者消息队列就没事。若是在主线程中,Handler的消息还在队列中尚未被处理,GC有可能无法回收这个Handler;也就无法回收使用这个Handler的外部类(如Activity、Service),有可能引起OOM。
换句话说,当Activity结束时,延迟的消息还可能在消息队列中。消息引用这Activity的Handler,Handler持有着它的外部类(也就是这个Activity)。这个引用会持续到消息被处理,在此之前不会被GC。
Java中,非静态内部类和匿名类会引用了它们的外部类。
根据修改建议,按照提示进行修改,将handler声明为static。
static class rustHandler extends Handler {
private final WeakReference<MySwipeActivity> mActivity;
rustHandler(MySwipeActivity mySwipeActivity) {
mActivity = new WeakReference<MySwipeActivity>(mySwipeActivity);
}
@Override
public void handleMessage(Message msg) {
MySwipeActivity activity = mActivity.get();
if (activity != null) {
// la la la la la ...
}
}
}
静态类 rustHandler 中定义一个 WeakReference(弱引用);利用这个若引用来完成操作。这样警告就消失了。
参考Android源码,也有这种做法,没有使用弱引用的
static class MyHandler extends Handler {
MySwipeActivity handlerSwipeActivity;
MyHandler(MySwipeActivity mySwipeActivity) {
handlerSwipeActivity = mySwipeActivity;
}
@Override
public void handleMessage(Message msg) {
if (handlerSwipeActivity != null) {
// do something
}
}
}
同样消除了AS的警告;MyHandler 声明为 static,达到了目的
Java中的引用
java.lang.ref 类库包含了一组类,这些类为垃圾回收提供了更大的灵活性。
SoftReference WeakReference PhantomReference 由强到弱,对应不同级别的“可获得性”;越弱表示对垃圾回收器的限制越少,对象越容易被回收。
参考
http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html
http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler
Android handler 可能会造成内存泄露的更多相关文章
- Android 中 Handler 引起的内存泄露
在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下.http://w ...
- 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 ...
- Android 从java字节码告诉你 为什么Handler会造成内存泄露
很多人面试的时候,都知道Handler 极易造成内存泄露,但是有一些讲不出来为什么,好一点的 会告诉你looper msg 之类的,但是你再往下问 为什么msg持有handler handler为什么 ...
- Android中Handler导致的内存泄露
http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html Consider the follo ...
- [Android Memory] App调试内存泄露之Context篇(下)
转载地址:http://www.cnblogs.com/qianxudetianxia/p/3655475.html 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用A ...
- 【转】内部Handler类引起内存泄露
如果您在Activity中定义了一个内部Handler类,如下代码: public class MainActivity extends Activity { private Handl ...
- [Android Memory] App调试内存泄露之Context篇(上)
转载自:http://www.cnblogs.com/qianxudetianxia/p/3645106.html Context作为最基本的上下文,承载着Activity,Service等最基本组件 ...
- Handler 引起的内存泄露
先看一组简单的代码 1 2 3 4 5 6 7 8 9 public class SampleActivity extends Activity { private final Handler mHa ...
随机推荐
- 网络编程应用:基于TCP协议【实现文件上传】--练习
要求: 基于TCP协议实现一个向服务器端上传文件的功能 客户端代码: package Homework2; import java.io.File; import java.io.FileInputS ...
- 第45篇 js操作打开本地程序
原文地址:http://blog.laofu.online/2017/06/10/how-js-controlApp/ 背景 假设有这样一个产品,一个web和一个winform客户端,在客户在web的 ...
- Spring学习(6)---Bean定义及作用域的例子
(一)Bean的定义 先定义一个BeanAnnotation package com.mypackage; import org.springframework.stereotype.Componen ...
- EF之通过不同条件查找去重复
Enumerable.Distinct<TSource> Method(IEnumerable<TSource>, IEqualityComparer<TSource&g ...
- WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)
到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击but ...
- [0] CollectionBase与索引符DictionaryBase与迭代器
对于简单数组来说,需要用固定的大小来初始化,才能使用: Animal[] myAnimal=new Animal[10]; myAnimal[0]=new Cow("Ken"); ...
- java基础:简单实现线程池
前段时间自己研究了下线程池的实现原理,通过一些源码对比,发现其实核心的东西不难,于是抽丝剥茧,决定自己实现一个简单线程池,当自已实现了出一个线程池后.发现原来那么高大上的东西也可以这么简单. 先上原理 ...
- iframe 父页面与子页面之间的方法的相互调用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 有关SQL模糊查询
执行 数据库查询时,有完整查询和模糊查询之分. 一般模糊语句如下: SELECT 字段 FROM 表 WHERE 某字段 Like 条件 其中关于条件,SQL提供了四种匹配模式: 1,%:表示任意0个 ...
- epoll的ET和LT模式比较 - 源码分析
eventpoll是一种文件,它实现了一种机制利用一条rdllist队列来避免阻塞地进行poll.eventpoll归根到底还是在使用poll.而ET比LT高效,并不在于是否使用了poll,更不能说是 ...