详解Android创建Handler的必备知识点

目录
  • 普通Handler创建
  • 异步Handler的使用及创建

普通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指定为异步方式,就可以优先进行执行。

到此这篇关于详解Android创建Handler的必备知识点的文章就介绍到这了,更多相关Android创建Handler内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • android使用handlerthread创建线程示例

    在android开发中,一说起线程的使用,很多人马上想到new Thread(){...}.start()这种方式.这样使用当然可以,但是多次使用这种方式,会创建多个匿名线程.使得程序运行起来越来越慢.因此,可以考虑使用一个Handler来启动一个线程,当该线程不再使用就删除,保证线程不会重复创建.一般会使用Handler handler = new Handler(){...}创建Handler.这样创建的handler是在主线程即UI线程下的Handler,即这个Handler是与UI线程下

  • Android App在线程中创建handler的方法讲解

    相关概念 1.Handler:可以看做是一个工具类,用来向消息队列中插入消息的; 2.Thread:所有与Handler相关的功能都是与Thread密不可分的,Handler会与创建时所在的线程绑定; 3.Message:消息; 4.MessageQueue:消息队列,对消息进行管理,实现了一个Message链表; 5.Looper:消息循环,从MessageQueue中取出Message进行处理: 6.HandlerThread:继承Thread,实例化时自动创建Looper对象,实现一个消息

  • 详解Android创建Handler的必备知识点

    目录 普通Handler创建 异步Handler的使用及创建 普通Handler创建 一般下面这样创建Handler时AS会进行告警: 删除线提示Handler的无参构造方法已经被@Deprecated标记,正确的做法都是使用带Looper构造参数的构造方法进行Handler的创建: 这样做的好处是直接指定消息调度在哪个Looper,而Looper是通过ThreadLocal和线程绑定在一起,也就是说,指明了Looper就能知道当前消息Message最终会在哪个线程中执行. 而之所以Handle

  • 详解Android中Handler的内部实现原理

    本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文<详解Android中Handler的使用方法>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功

  • 详解Android中Handler的实现原理

    在 Android 中,只有主线程才能操作 UI,但是主线程不能进行耗时操作,否则会阻塞线程,产生 ANR 异常,所以常常把耗时操作放到其它子线程进行.如果在子线程中需要更新 UI,一般是通过 Handler 发送消息,主线程接受消息并且进行相应的逻辑处理.除了直接使用 Handler,还可以通过 View 的 post 方法以及 Activity 的 runOnUiThread 方法来更新 UI,它们内部也是利用了 Handler .在上一篇文章 Android AsyncTask源码分析 中

  • 详解Android中Handler的使用方法

    在Android开发中,我们经常会遇到这样一种情况:在UI界面上进行某项操作后要执行一段很耗时的代码,比如我们在界面上点击了一个"下载"按钮,那么我们需要执行网络请求,这是一个耗时操作,因为不知道什么时候才能完成.为了保证不影响UI线程,所以我们会创建一个新的线程去执行我们的耗时的代码.当我们的耗时操作完成时,我们需要更新UI界面以告知用户操作完成了.所以我们可能会写出如下的代码: package ispring.com.testhandler; import android.app.

  • 详解Android使用Handler造成内存泄露的分析及解决方法

    一.什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向,则该对象会在被GC发现的时候被回收:另外,如果一组对象中只包含互相的引用,而没有来自它们外部的引用(例如有两个对象A和B互相持有引用,但没有任何外部对象持有指向A或B的引用),这仍然属于不可到达,同样会被GC回收. Android中使用Handler造成内存泄露的原因 private Han

  • 详解Android Handler机制和Looper Handler Message关系

    概述 我们就从以下六个问题来探讨Handler 机制和Looper.Handler.Message之前的关系? 1.一个线程有几个Handler? 2.一个线程有几个Looper?如何保证? 3.Handler内存泄漏原因?为什么其他的内部类没有说过这个问题? 4.为何主线程可以new Handler?如果在想要在子线程中new Handler 要做些什么准备? 5.子线程中维护的Looper,消息队列无消息的时候的处理方案是什么?有什么用? 6.Looper死循环为什么不会导致应用卡死? 一.

  • 详解Android Handler的使用

    目录 Handler 概要 构造器 sendMessageAtTime dispatchMessage ThreadLocal Looper MessageQueue IdleHandler AsyncMessage和SyncBarrier 阻塞和唤醒机制 Handler内存泄漏分析 Handler 概要 Handler用于线程间的消息传递,它可以将一个线程中的任务切换到另一个线程执行.切换的目标线程与Handler内部持有的Looper所在线程一致.若初始化Handler时未手动设置Loope

  • 详解Android 基于TCP和UDP协议的Socket通信

    本来想讲一下基础的网络通信方面的知识点,发现太枯燥乏味了,不过笔试中也经常会问到这方面的问题,所以关于通信方面的知识点,小编会放到面试中去,因为实战中也就面试会用到这方面知识点 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据. 而Socket通信中基于TCP/IP协议的通信则是在双方建立起连接后就可以直接进行数

  • 详解Android ContentProvider的基本原理和使用

    一.前言 Android 的数据存储方式总共有五种,分别是:Shared Preferences.网络存储.文件存储.外储存储.SQLite.但一般这些存储都只是在单独的一个应用程序之中达到一个数据的共享,有时候我们需要操作其他应用程序的一些数据,就会用到 ContentProvider.而且 Android 为常见的一些数据提供了默认的 ContentProvider(包括音频.视频.图片和通讯录等). 要实现与其他的 ContentProvider 通信首先要查找到对应的 ContentPr

  • 详解Android 中AsyncTask 的使用

    详解Android 中AsyncTask 的使用 1.首先我们来看看AsyncTask 的介绍:   Handler 和 AsyncTask 都是android 中用来实现异步任务处理的方式:其中: Handler 实例向 UI 线程发送消息,完成界面更新, 优点:对整个过程控制的比较精细:         缺点:代码相对臃肿,多个任务同时执行时,不易对线程进行精确的控制: AsyncTask :比Handler 更轻量级一些,适用于简单的异步处理: 优点:简单 | 快捷 | 过程可控:    

随机推荐