Handle笔记(Sundy课程)

简介: 张凌华课程(Handler-不可缺少的异步)笔记: Handle主要用于进行线程间通信 Handle衔接了Message(Message存放在MessageQueue中)和Looper这两大部分 Handle主要方法 (1)sendMes...

张凌华课程(Handler-不可缺少的异步)笔记:
Handle主要用于进行线程间通信
Handle衔接了Message(Message存放在MessageQueue中)和Looper这两大部分

Handle主要方法
(1)sendMessage (Message msg)
(2)post (Runnable r)
注意:post(Runnable r)最终调用的还是sendMessage (Message msg)所以只有一个消息队列

实验一:
一个Handle实例只能接受到自己发出的message.
若在一个MainActivity里定义了两个Handle1和Handle2,那么在子线程中Handle1发出消息
在MainActivity中只有Handle1收到消息Handle2收不到.这就是说虽然只有一个消息队列但是不同Handle发送和接收消息是彼此独立的.
老师说:这主要是Message中的what进行标记的,这样唯一标记了Message.但是这样有些牵强.
真正实现:同一个消息队列但是不同Handle发送和接收消息是彼此独立,是这样的:
(1)在handler对象调用方法handler.sendMessage(message)时,查看源码
可知实际调用的是方法sendMessageAtTime(Message message, long uptimeMillis)
此方法里面的message有一个成员target且msg.target = this;这里的this就是此handler对象本身
它的作用:当主线程的消息处理器Looper在处理Message的时候会查看Message的target,就知道把此消息交给哪一个Handle处理
源码如下:
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;
        if (queue != null) {
            msg.target = this;
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
                Log.w("Looper", e.getMessage(), e);
        }
        return sent;
}
这样就实现了:哪个Handle发送的消息交给哪个Handle处理
(2)主要Message中的what是作为Message的唯一标示.因为同一个Handle可以收到好几个Message,而且每个Message
代表了不同的含义.所以Handle可以通过switch(message.what)对不同的消息,做出不同的响应
这样就实现了:Handle对不同的消息做出不同的处理

综合这两步实现:同一个消息队列但是不同Handle发送和接收消息是彼此独立

Looper的实现
因为Looper是一个死循环.while(true)不断监听消息队列,但是Looper不是额外的线程,因为Looper是由系统来控制的

Handle不建立新的线程


实验二:
我们在子线程中新建Handle并且发送消息,实验结果是:报错!!
因为在普通的子线程中是没有Looper的.如果非要这么做的话可以用public class HandlerThread代替普通的子线程.
因为HandlerThread在普通子线程的基础上增加了Looper和一些Handle的特性

实验三:
此实验实际使用价值不大,只为验证技术
在子线程中调用Looper的静态方法getMainLooper得到主线程的Looper,且以此为参数新建Handle
即Handle testHandle=new Handle(Looper.getMainLooper);
这样建立的Handle也可以实现消息的处理

实验四:
此实验实际使用价值不大,只为验证技术
可以在子线程中新建一个自己的Looper,也可实现消息的处理


总结:
1 Handle实例与消息处理是关联的,发送和接收要匹配
  即哪一个Handle发送消息就要用哪一个Handle来处理消息,其余的Handle是无法接收和处理消息Message的,即便这两个Handle在同一个主线程中,如实验一
2 最常用的模式:在子线程中使用的是主线程的消息队列
3 普通子线程是没有消息队列的

相关文章
|
编译器
课程03-嵌入式设计方法(2)
课程03-嵌入式设计方法(2)
课程03-嵌入式设计方法(2)
|
人工智能 运维 文字识别
课程3: 做一个小程序吧 | 学习笔记
快速学习课程3: 做一个小程序吧
126 0
课程3: 做一个小程序吧 | 学习笔记
|
前端开发 索引 设计模式
|
Android开发 开发者 Windows