博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android -> 怎样避免Handler引起内存泄露
阅读量:5809 次
发布时间:2019-06-18

本文共 1945 字,大约阅读时间需要 6 分钟。

很多其它内容,可訪问个人博客

错误代码

假设在Activiy中通过(Runnable)的方式定义了一个变量runnable,

final Runnable runnable = new Runnable() {    public void run() {        // ... do some work    }};handler.postDelayed(runnable, TimeUnit.SECONDS.toMillis(10)

由于Runnable不是static类型,所以会有一个包括Activity实例的implicit reference --- Activity.this。

假设Activity在runnable变量run之前(10s内)被finish掉了可是Activity.this仍然存在。那么Activity的对象就不会被GC回收,从而导致memory leak

即使使用一个静态内部类,也不能保证万事大吉。

static class MyRunnable implements Runnable {    private View view;    public MyRunnable(View view) {        this.view = view;    }    public void run() {        // ... do something with the view    }}

如果在runnable运行之前。View被移除了。可是成员变量view还在继续引用它,仍然会导致memory leak

上面的两个样例其中,导致内存泄露的两种使用方法各自是隐式引用(implicit reference)显式引用(explicit reference)

解决方法

解决隐式引用的方法比較简单。仅仅要使用内部非静态类(non-static inner class)或者 top-level class(在一个独立的java文件里定义的变量)就能够将隐式变为显式,从而避免内存泄露。

假设继续使用非静态内部类,那么就要在onPause的时候手动结束那些挂起的任务(pending task)。

关于怎样结束不论什么,Handler可參考中的Canceling a pending RunnableCanceling pending Messages。HandlerThread可參考。

解决第二个问题要用到WeakReference。WeakReference的使用方法能够google一下。简而言之就是:仅仅要还有其它的stronger reference。WeakReference就能够继续引用。

static class MyRunnable implements Runnable {    private WeakReference>View< view;    public MyRunnable(View view) {        this.view = new WeakReference>View<(view);    }    public void run() {        View v = view.get();        if (v != null) {            // ... do something with the view        }    }}

这样一来问题就攻克了。美中不足的是每次使用view之前都要做空指针推断。另外一个比較高效的方法就是在onResume中为runnable的view赋值,在onPause中赋值为null。

private static class MyHandler extends Handler {    private TextView view;    public void attach(TextView view) {        this.view = view;    }    public void detach() {        view = null;    }    @Override    public void handleMessage(Message msg) {        // ....    }

总结

在继承Handler或者HandlerThread的时候。

  • 尽量定义一个static类或者top-level类。
  • 假设用到了ui元素,一定要在Activity的生命周期接触之前释放掉。

參考

Asynchronous Android - Steve Liles

转载地址:http://kqcbx.baihongyu.com/

你可能感兴趣的文章
个人开公司的流程,以后用得着(转)
查看>>
自动部署系统
查看>>
DSP网络子系统
查看>>
我的友情链接
查看>>
第一次尝试写IT博客
查看>>
struct字节分配问题
查看>>
Error string types not allowed at android:configChanges in manifest file
查看>>
mysql服务器主从服务器设置
查看>>
文件管理、命令别名和glob
查看>>
趣谈家用计算机维护
查看>>
Spring security
查看>>
ubuntu 14 /etc/sudoers权限修改引起sudo不能使用
查看>>
花样的年华
查看>>
我的友情链接
查看>>
centos *** clent 连接
查看>>
《QTP自动化测试进阶》(14)
查看>>
JMeter入门教程2:录制1
查看>>
RAIDD 互联网应用
查看>>
第九章 缓存技术
查看>>
有4家企业获得阿里云创投资金 一夜间成为土豪的感脚有木有~~
查看>>