美文网首页Android技术知识Android开发
Handler创建的几个必备知识点,了解一下

Handler创建的几个必备知识点,了解一下

作者: KKK_f600 | 来源:发表于2022-10-18 13:49 被阅读0次

    普通Handler创建

    一般下面这样创建Handler时AS会进行告警:

    删除线提示Handler的无参构造方法已经被@Deprecated标记,正确的做法都是使用带Looper构造参数的构造方法进行Handler的创建:

    这样做的好处是直接指定消息调度在哪个Looper,而Looper是通过ThreadLocal和线程绑定在一起,也就是说,指明了Looper就能知道当前消息Message最终会在哪个线程中执行。

    而之所以Handler无参构造方法被废弃的一个原因就是:

    它会尝试从当前线程中的ThreadLocal获取Looper,主线程会自动帮助我们创建好Looper自然是没什么问题,但是如果子线程中执行Handler的创建,而没有手动调用Looper.prepare(),就会导致崩溃。

    异步Handler的使用及创建

    异步Handler有什么作用呢,相比较于普通Handler,可以获取优先调度执行权,当前,前提是要添加同步屏障消息。

    这里解释下同步屏障消息:

    同步屏障消息和普通的Message基本上没啥区别,主要的一个区分点是同步屏障消息Messagetarget属性为null,当从消息队列中取出消息并执行时,会先判断下当前的Messagetarget是否为null,如果为null则会从消息队列中优先获取异步消息 进行调度执行

    相应的源码如下:

    添加消息屏障的方法为MessageQueue.postSyncBarrier(),不过这个方法目前是不支持业务方直接进行调用。

    上面消息屏障说完了,我们接下来看下异步消息如何创建:异步消息的创建依赖异步Hanlder的创建。所以我们看下异步Handler如何进行创建:

    @NonNull
    public static Handler createAsync(@NonNull Looper looper) {
        if (looper == null) throw new NullPointerException("looper must not be null");
        return new Handler(looper, null, true);
    }
    
    @NonNull
    public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
        if (looper == null) throw new NullPointerException("looper must not be null");
        if (callback == null) throw new NullPointerException("callback must not be null");
        return new Handler(looper, callback, true);
    }
    

    Handler提供了createAsync()两个重载方法进行创建,最终会将HandlermAsynchronous属性置为true,然后通过Hanlder发送消息时,最终会走到Handler.enqueueMessage()方法:

    private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
            long uptimeMillis) {
        ...
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }
    

    可以看到,如果mAsynchronous属性为true,就将Message添加FLAG_ASYNCHRONOUS置为异步消息。不过这个API是只有在SDK>=28以上才能调用,那么消息28的版本如何创建的,这里给出一个非常全面的兼容各个SDK版本的创建异步Handler的方法:

    上面的使用讲完了,说下应用了。这个异步消息+消息屏障在系统源码中有一个非常典型的应用场景,那就是界面的绘制

    由于界面的绘制渲染优先级是比较高的,所以添加消息屏障后,将绘制相关的Message指定为异步方式,就可以优先进行执行。

    总结

    本篇文章主要是详细介绍了普通Hanlder异步Hanlder的创建方式及使用场景,希望能给大家带来帮助。

    相关文章

      网友评论

        本文标题:Handler创建的几个必备知识点,了解一下

        本文链接:https://www.haomeiwen.com/subject/uanjzrtx.html