android难点汇总

Handler

Handler原理

了解Handler的原理。梳理Android的消息机制
谈谈handler容易导致内存泄漏的原因。

private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            ...
        }
    };

当使用内部类(包括匿名类)来创建Handler的时候,Handler对象会隐式地持有Activity的引用。

而Handler通常会伴随着一个耗时的后台线程一起出现,这个后台线程在任务执行完毕后发送消息去更新UI。然而,如果用户在网络请求过程中关闭了Activity,正常情况下,Activity不再被使用,它就有可能在GC检查时被回收掉,但由于这时线程尚未执行完,而该线程持有Handler的引用(不然它怎么发消息给Handler?),这个Handler又持有Activity的引用,就导致该Activity无法被回收(即内存泄露),直到网络请求结束。

另外,如果执行了Handler的postDelayed()方法,那么在设定的delay到达之前,会有一条MessageQueue -> Message -> Handler -> Activity的链,导致你的Activity被持有引用而无法被回收。

解决方法之一,使用弱引用:

static class MyHandler extends Handler {
    WeakReference<Activity > mActivityReference;
    MyHandler(Activity activity) {
        mActivityReference= new WeakReference<Activity>(activity);
    }
    @Override
    public void handleMessage(Message msg) {
        final Activity activity = mActivityReference.get();
        if (activity != null) {
            mImageView.setImageBitmap(mBitmap);
        }
    }
}

Looper的退出

Looper的退出方案可以参考,消息队列中无消息的时候,Looper的处理方案是什么?
总结一下:
Looper提供了方法quit(), quitSafely() 区别就是quit会清除掉所有消息队列的消息,quitSafely清理时间点未执行的消息。
quit方法可用于释放线程。
主线程Looper不可以退出,调用会抛出异常。

Message的创建

MessageQueue的数据结构是一个单向链表。
Messgae创建使用Message.obtain()的方式,好处可复用一个已经被回收的 Message.也可以直接new Message()不推荐这种方式。
主要的 Message 回收时机是:

  • 在 MQ 中 remove Message 后;
  • 单次 loop 结束后;
  • 主动调用 Message 的 recycle 方法后;

Looper死循环问题

参考 Handler机制Looper死循环为什么不会导致应用卡死
主线程的死循环一直运行会不会特别消耗CPU资源呢?其实不然这里就涉及到Linux pipe/epoll机制,简单说就是在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。 所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源。

参考资料

关于Handler面试题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值