博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android代码优化之Handler内存泄漏
阅读量:5832 次
发布时间:2019-06-18

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

目录

img_32a68da51a52d530463cf8ef2069c97d.png
目录

前言

Android代码中涉及进程间通信的地方经常会使用Handler。

public class MainActivity extends AppCompatActivity {    //可能引入内存泄漏的方法    private Handler handler=new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}

而上面这种用法可能会导致内存泄漏,比如使用如下代码,由于消息会在5分钟后发送,所以当用户进入并退出Activity后,在消息发送并处理完成之前,这个Activity是不会被回收的,这样就会导致内存泄漏。

public class MainActivity extends AppCompatActivity {    //可能引入内存泄漏的方法    private Handler handler=new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //5分钟后发送消息        handler.postDelayed(new Runnable() {            @Override            public void run() {                Log.e("测试","123");            }        },1000*10*5);    }}

内存泄漏的原因

由于Handler、Looper和MessageQueue是一起工作的,在Android中一个应用启动后系统会默认创建一个用于处理主线程所有Message对象的Looper对象,它的生命周期贯穿于整个应用的生命周期,所以在主线程使用Handler的时候都会默认绑定这个Looper对象并关联MessageQueue,这时发送到MessageQueue的Message对象都会持有这个Handler对象的引用,这样Looper在处理消息的时候才能回调到Handler中年的handleMessage方法。因此如果Message对象还没有处理完成,那么Handler对象也就不会被垃圾回收。而在Java中非静态内部类会持有外部类的一个隐式引用,所以当Handler无法回收时由于Handler持有MainActivity的引用导致MainActivity也无法被回收,从而导致内存泄漏。

解决方法:将Handler改为静态内部类并使用弱引用

public class MainActivity extends AppCompatActivity {    private final InnerHandler mInnerHandler=new InnerHandler(this);    private final Runnable sRunnable=new Runnable() {        @Override        public void run() {            Toast.makeText(MainActivity.this, "解决方法", Toast.LENGTH_SHORT).show();        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mInnerHandler.postDelayed(sRunnable,1000*60*5);    }    private static class InnerHandler extends Handler{        private final WeakReference
activityWeakReference; public InnerHandler(MainActivity activity) { this.activityWeakReference = new WeakReference
(activity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); MainActivity activity=activityWeakReference.get(); if(activity!=null){ } } }}

个人技术博客:

我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。

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

你可能感兴趣的文章
Android的Aidl安装方法
查看>>
Linux中rc的含义
查看>>
曾鸣:区块链的春天还没有到来| 阿里内部干货
查看>>
如何通过Dataworks禁止MaxCompute 子账号跨Project访问
查看>>
js之无缝滚动
查看>>
Django 多表联合查询
查看>>
logging模块学习:basicConfig配置文件
查看>>
Golang 使用 Beego 与 Mgo 开发的示例程序
查看>>
+++++++子域授权与编译安装(一)
查看>>
asp.net怎样在URL中使用中文、空格、特殊字符
查看>>
路由器发布服务器
查看>>
实现跨交换机VLAN间的通信
查看>>
python例子
查看>>
环境变量(总结)
查看>>
ios之UILabel
查看>>
Java基础之String,StringBuilder,StringBuffer
查看>>
1月9日学习内容整理:爬虫基本原理
查看>>
安卓中数据库的搭建与使用
查看>>
AT3908 Two Integers
查看>>
C++ 0X 新特性实例(比较常用的) (转)
查看>>