博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
每日一道面试题(第1期)---自定义handler如何有效保证内存泄漏问题
阅读量:7196 次
发布时间:2019-06-29

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

零零碎碎的东西总是记不长久,仅仅学习别人的文章也只是他人咀嚼后留下的残渣。无意中发现了这个,想了想如果只是简单地去思考,那么不仅会收效甚微,甚至难一点的题目自己可能都懒得去想,坚持不下来。所以不如把每一次的思考、理解以及别人的见解记录下来。不仅加深自己的理解,更要激励自己坚持下去。

handler作用

SDK文档是这么说的。

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

我们一般就是用来更新UI线程的。具体点就是在子线程进行耗时操作,比如获取网络图片,然后需要在主线程更新图片,就需要handler+Message+Loop+MessageQueue来帮忙啦。

但是如果你直接创建一个handler对象,然后重写内部handlerMessage方法,那么AS一定会提醒你会有内存泄漏的可能。

为什么会造成内存泄漏

Android内存泄漏:需要被GC回收的对象因为被其他存活的对象所持有引用,而导致GC不能回收此对象。那么这块内存就会在程序运行期间长期被占据,造成系统内存的浪费,使系统运行缓慢甚至崩溃。

那么handler什么时候会造成内存泄漏呢?

发送延迟消息

众所周知,匿名内部类持有外部类的引用,那么handler对象就会持有activity对象的引用。handler发送message到MessageQueue,message持有handler的引用,而MessageQueue会持有message的引用,而MessageQueue是属于TLS(ThreadLocalStorage)线程,是与Activity不同的生命周期。

所以当Activity的生命周期结束后,而MessageQueue中还存在未处理的消息,那么上面一连串的引用关系就不允许Activity的对象被回收,就造成了内存泄漏。

解决办法

知道了内存泄漏是由引用链造成的,那么解决方法也就是破坏上面的引用链。

首先是引用的类型,有强引用、软引用、弱引用、虚引用,上面的引用链都是强引用。

所以第一种方法,自定义静态内部类,如果想使用外部类的方法,那就通过弱引用的方法引入Activity对象。

public class BaseActivity extends Activity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    public void myHandleMessage(Message msg){}    static class MyHandler extends Handler{        WeakReference
mActivityReference; public MyHandler(BaseActivity activity){ mActivityReference = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { BaseActivity activity = mActivityReference.get(); if(activity != null){ activity.myHandleMessage(msg); } } }}复制代码

你可以自定义在BaseActivity中,在其他Activity中创建Myahndler对象,通过重写myHandleMessage方法进行消息处理。

这种方法就是处理了Activity与Handler之间的引用,这种引用可以再GC时被回收。

第二种,就是处理后面的引用。既然是Activity要被回收时还有未被处理的消息,那么在Activity要被回收时清除消息就可以了。

@Override    protected void onDestroy() {        super.onDestroy();        if(mHandler != null){            mHandler.removeCallbacksAndMessages(null);        }    }复制代码

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

你可能感兴趣的文章
Java中static作用及使用方法具体解释
查看>>
SVN版本回退
查看>>
HTML5的Video标签的属性,方法和事件汇总
查看>>
Kids Store - OpenCart 自适应主题模板 ABC-0022
查看>>
Swift开发教程--怎样自己定义TabBarItem的图片显示
查看>>
Cacti学习
查看>>
ASP.NET Core 返回 Json DateTime 格式
查看>>
Java编程的逻辑 (89) - 正则表达式 (中)
查看>>
shadowOffset 具体解释
查看>>
惊心动魄的SAP S4客户额度调整运动
查看>>
myeclipse2013 jsp编辑初始化
查看>>
Ubuntu: GlusterFS+HBase安装教程
查看>>
黄聪:C#如何Json转字符串;字符串转Json;Newtonsoft.Json(Json.Net)学习笔记(转)...
查看>>
MyEclipse改动内存大小
查看>>
自己主动化开发測试的一些理论根据及经验总结(2015)
查看>>
SDCC2013大会笔记整理
查看>>
线性表之链表源码
查看>>
Java设置Client Socket链接Server超时时间
查看>>
Gradle Build速度加快终极方法(android studio)
查看>>
CentOS6.8安装360 pika
查看>>