likes
comments
collection
share

Android知识点整理-Handler

作者站长头像
站长
· 阅读数 54

Handler

相关博客blog.csdn.net/jdsjlzx/art…

在一个Handler中给另一个Handler发送消息

使用handlerThread创建一个含有Looper的子线程,即可实现向该子线程发送消息。

简述Handler,创建Message的方式,这种设计是什么设计模式?

有的话复用,没有的话创建,享元模式

子线程怎么创建Handler?

1.用HandlerThread 2.用getLooper()给一个looper

HandlerThread hanlerThread = new HandlerThread("子线程");
hanlerThread.start();
final Handler handler = new Handler(hanlerThread.getLooper()) {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        Log.d("----->", "线程:" + Thread.currentThread().getName());
    }
};

请解释下在单线程模型中Message、Handler、MessageQueue、Looper之间的关系

拿主线程来说,主线程启动时会调用Looper.prepare()方法,会初始化一个Looper,放入Threadlocal中,接着调用Looper.loop()不断遍历MessageQueue,Handler的创建依赖与当前线程中的Looper,如果当前线程没有Looper则必须调用Looper.prepare()。Handler , sendMessage到MessageQueue,Looper不断从MessageQueue中取出消息,回调handleMessage方法。

Handler机制如何保证消息不错乱?

消息队列

Handler和AsyncTask的区别

Handler 消息机制 AsyncTask :Handler、Thread等封装为一个异步执行框架

方法分析

关于Handler,在任何地方new Handler都是什么线程下?

看传递的looper,不传则是主线程

handler如何实现(消息)延时的?

www.jianshu.com/p/68083d432…

  1. DelayMillis加上当前开机的时间(这里可以理解就是这个time就是,现在的时间+需要延迟的时间=实际执行的时间),接下来进到sendMessageAtTime方法里面
  2. 把message发送到messageQueue里面,每个消息都会带有一个uptimeMillis参数,这就是延时的时间
  3. 将这个msg根据实际执行时间进行排序插入到queue里面

Handler.post(Runnable r)方法的底层实现(是如何执行的?)

这个Runable会加入的消息队列当中,同时会在handler所在的线程上运行。

也就是说,post(Runnable runnable) 并没有开启新的线程,这时我们就要注意了,当我们在UI主线程当中这样处理大事件时不能用此方法开启线程。

Handler的Callback和message都存在,但callback返回true,handleMessage还会执行么?(字节跳动、小米)

不会

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        // 1. 设置了Message.Callback(Runnable)
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            // 2. 设置了 Handler.Callback(Callback )
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        // 3. 未设置 Handler.Callback 或 返回 false
        handleMessage(msg);
    }
}
public interface Callback {
    public boolean handleMessage(Message msg);
}

Looper

Looper在主线程中死循环(循环查消息),为啥不会ANR(阻塞主线程)?

消息队列中无消息怎么处理 block nativePollOnce值为-1表示无限等待,让出cpu时间片给其线程,本线程等待 0表示无须等待直接返回 nativePollOnce -> epoll(linux) ->linux层的messagequeue

msg -> 5s -> ANRmsg

ANR: 5秒内没有响应输入事件,比如按键、屏幕触摸 10秒内没有处理广播 本质:消息队列中其他消息耗时,按键或广播消息没有及时处理

根本原因不是线程在睡眠,而是消息队列被其他耗时消息阻塞,导致按键或广播消息没有及时处理

如何保证一个线程只有一个Looper?

首先,Handler 主要利用了 ThreadLocal 在每个线程单独存储副本的特性,保证了一个ThreadLocal<Looper>在不同线程存取的Looper对象相互独立;其次,ThreadLocal 是 Looper 的一个static final变量,这样就保证了整个进程中 sThreadLocal对象不可变;第三,Looper.prepare()判断在一个线程里重复调用,则会抛出异常。

Message

Message有个缓存池,缓存池大小是多少知道吗

取决于Message数量,默认最大大小是10

内存泄漏

Handler内存泄露的原因以及解决方案

  1. 原因:Handler造成内存泄露的原因。非静态内部类,或者匿名内部类。使得Handler默认持有外部类的引用。在Activity销毁时,由于Handler可能有未执行完/正在执行的Message。导致Handler持有Activity的引用。进而导致GC无法回收Activity。
  2. 解决:Activity销毁时,清空Handler中,未执行或正在执行的Callback以及Message。

对比

Handler、Thread和HandlerThread的差别

  1. Handler:在android中负责发送和处理消息,通过它可以实现其他支线线程与主线程之间的消息通讯。
  2. Thread:Java进程中执行运算的最小单位,亦即执行处理机调度的基本单位。某一进程中一路单独运行的程序。
  3. HandlerThread:一个继承自Thread的类HandlerThread,Android中没有对Java中的Thread进行任何封装,而是提供了一个继承自Thread的类HandlerThread类,这个类对Java的Thread做了很多便利的封装。

IdleHandler是什么?怎么使用,能解决什么问题?

IdleHandler 说白了,就是 Handler 机制提供的一种,可以在 Looper 事件循环的过程中,当出现空闲的时候,允许我们执行任务的一种机制。

ThreadLocal

ThreadLocal原理,实现及如何保证Local属性?

ThreadLocal诞生的目的是隔离不同线程所使用的变量

虽然在不同线程中访问的是同一个ThreadLocal对象,但是它们通过ThreadLocal来获取到的值却是不一样的,这就是ThreadLocal的奇妙之处。ThreadLocal之所以有这么奇妙的效果,是因为不同线程访问同一个ThreadLocal的get方法,ThreadLocal内部会从各自的线程中取出一个数组,然后再从数组中根据当前ThreadLocal的索引去查找出对应的value值,很显然,不同线程中的数组是不同的,这就是为什么通过ThreadLocal可以在不同的线程中维护一套数据的副本并且彼此互不干扰。(从ThreadLocal的set和get方法可以看出,它们所操作的对象都是当前线程的localValues对象的table数组,因此在不同线程中访问同一个ThreadLocal的set和get方法,它们对ThreadLocal所做的读写操作仅限于各自线程的内部,这就是为什么ThreadLocal可以在多个线程中互不干扰地存储和修改数据。)

ThreadLocal在Looper是如何应用的?

 // sThreadLocal.get() will return null unless you've called prepare().
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

屏障

同步屏障机制

同步屏障(SyncBarrier)是 Handler 用来筛选高低优先级消息的机制,即:当开启同步屏障时,高优先级的异步消息优先处理。

转载自:https://juejin.cn/post/7058605124838490142
评论
请登录