Android Handler机制·一(入门篇)

概览

Android线程间通信是消息驱动的,Looper负责轮询,Message为消息,MessageQueue为Message的集合,Handler负责串联线程。本文基于android api 29源码,主要讲解java层的Handler机制。
先来个一般性的例子:

  fun testOriHandler() {
   
        var handler1: Handler? = null
        var handler2: Handler? = null

        Log.d("Ktest", "${
     Thread.currentThread().name}:main")
        thread {
   
            Looper.prepare()
            // 暂不考虑内存泄漏
            handler1 = object : Handler() {
   
                override fun handleMessage(msg: Message) {
   
                    super.handleMessage(msg)
                    Log.d("Ktest", "${
     Thread.currentThread()}:handler1.handleMessage")
                }
            }
            Looper.loop()
        }

        thread {
   
            Looper.prepare()
            handler2 = object : Handler() {
   
                override fun handleMessage(msg: Message) {
   
                    super.handleMessage(msg)
                    Log.d("Ktest", "${
     Thread.currentThread()}:handler2.handleMessage")
                }
            }
            Looper.loop()
        }

        thread {
   
            Thread.sleep(1000)
            handler2?.sendMessage(Message.obtain(handler2, Runnable {
   
                Log.d("Ktest", "${
     Thread.currentThread()}:msg2.callback")
            }))

            Thread.sleep(1000)
            handler1?.sendMessage(Message.obtain())
        }
    }

运行结果:
在这里插入图片描述
其大概的运行流程如下:
在这里插入图片描述
工作线程通过绑定了Looper线程的handler,发送Message到消息队列,而Looper线程无限循环的从消息队列中取Message,并在Looper所在线程,执行handler的dispatchMessage方法,实现了异步线程通信。
正式代码分析前先看看简略类图:
在这里插入图片描述

关键代码分析

其实也就四句话:

  1. 初始化Looper:Looper.prepare()
  2. 初始化Handler:handler1 = object : Handler()
  3. 开始循环:Looper.loop()
  4. 消息发送:handler1?.sendMessage(Message.obtain())

初始化Looper

// Looper.java
// 充当ThreadLocalMap的key和获取线程Looper的工具类
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
public static void prepare() {
    prepare(true); }
private static void prepare(boolean quitAllowed) {
   
    if (sThreadLocal.get() != null) {
   
    	// 这里保证了prepare两次会抛错,保证一个线程对应一个looper
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    // 设置线程的Looper
    sThreadLocal.set(new Looper(quitAllowed));
}

初始化当前线程.threadLocals,最终会调用ThreadLocal.createMap,给当前线程初始化threadLocals变量:

// ThreadLocal.java
public T get() {
   
    Thread t = Thread.currentThread();
    // 获取当前线程的threadLocals
    ThreadLocalMap map = getMap(t);
    if (map != null) {
   
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
   
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    // 设置当前线程.threadLocals初始值
    return setInitialValue();
}

ThreadLocalMap getMap(Thread t) {
   
    return t.threadLocals;
}

private T setInitialValue() {
   
    T value = initialValue();
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        // threadLocals初始化
        createMap(t, value);
    return value;
}

void createMap(Thread t, T firstValue) {
   
   // 设置线程threadLocals
   t.threadLocals = new ThreadLocalMap(this, firstValue);
}

设置当threadLocals的初始值:

// ThreadLocal.java#ThreadLocalMap
private Entry[] table;
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
   
    table = new Entry[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值