Handler机制与原理

Handler在Android中用于线程间通信,可能导致内存泄漏。使用非静态内部类创建Handler会因持有外部引用造成内存泄漏。解决方案是使用静态内部类和弱引用。Message通过Message.obtain()获取,利用缓存池提高效率。每个线程有一个Looper和MessageQueue,可有多个Handler。不能在子线程直接创建Handler,需确保有Looper并启动循环。Looper的死循环不会导致应用卡死,利用Linux的epoll机制在无消息时休眠,节省资源。

为什么会出现内存泄漏问题呢?

  • 分析

    • Handler使用是用来进行线程间通信的,所以新开启的线程是会持有Handler引用的,如果在Activity等中创建Handler,并且是非静态内部类的形式,就有可能造成内存泄漏

    • 非静态内部类是会隐式持有外部类的引用,所以当其他线程持有了该Handler,线程没有被销毁,则意味着Activity会一直被Handler持有引用而无法导致回收

    • MessageQueue中如果存在未处理完的Message,Message的target也是对Activity等的持有引用,也会造成内存泄漏

  • 解决的办法

    • 使用静态内部类 + 弱引用的方式

      • 静态内部类不会持有外部类的的引用,当需要引用外部类相关操作时,可以通过弱引用还获取到外部类相关操作,弱引用是不会造成对象该回收回收不掉的问题,不清楚的可以查阅JAVA的几种引用方式的详细说明
    • 在外部类对象被销毁时,将MessageQueue中的消息清空

在使用Handler时,通常是通过Handler.obtainMessage()来获取Message对象的,而其内部调用的是Message.obtain()方法,那么问题来了,为什么不直接new一个Message,而是通过Message的静态方法obtain()来得到的呢?

  • 使用obtain获取Message对象是因为Message内部维护了一个数据缓存池,回收的Message不会被立马销毁,而是放入了缓存池,在获取Message时会先从缓存池中去获取,缓存池为null
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值