Android消息机--handler的自我总结

大家都知道Handler是Android为了能在子线程更新UI所创作出来的一个类.

那么为什么Handler能在handler里面能更新UI。是因为Handler 把更新UI的操作切换到了主线程来操作.

有些博客说Handler是线程之间的一种通讯方式,这只局限于子线程跟主线程之间,

那么子线程是怎么把消息传送到主线程来操作,这其中一个关键的地方就是Looper.

从例子我们可以知道 假如现在有一段主要的代码

oncrete(){

new Thread(new Runnable(){

run{

//进行UI操作  ---这样是会报错的 那么我们加上handler

// 之前是没有的,现在加上Looper

Looper.prepare();

new Handler(){

handlerMessage(){

//进行UI操作 ---

// 如果是这样依然会报错 因为子线程中现在还没有Looper,会报没有Looper那个错误信息(从源码可以看到加了Looper检测)  那么我们加上Looper

}

}

Looper.loop();

}

}).start;

}

从上面的代码中 加了Looper之后还是会报错,报应该在主线程中执行UI操作.

那么是为什么,原因在于 这个Looper不是主线程的Looper

一个解决方法是 把Looper.prepare();改成Looper.getMainLooper();

或者 new Handler(Looper.getMainLooper);

这样就可以更新UI不会报错了,

那么Looper是怎样把更新UI的操作切换到主线程

我们从源码可以看到 当我们new Handler(Looper.getMainLooper())的时候 里面有

Handler(Looper looperCallback callbackasync) {
    = looper= looper.mQueue= callback= async}

所以说这个时候 handler已经拿到了主线程的Looper;

然后我们在Looper的loop();方法里面看到

{
    msg.target.dispatchMessage(msg)} {
    (traceTag != ) {
        Trace.(traceTag)}
}

会调用msg.target 这个msg.target是在这里拿到

Looper me = ()(me == ) {
    RuntimeException()}
MessageQueue queue = me.mQueue
() {
    Message msg = queue.next()(msg == ) {
        }

在loop()方法里面Looper会开始无限循环 去处理信息啦。

顺序是以下这样

1:实例化Activity 的时候创建ActivityThread(主线程) 然后在Main()里面创建Looper 然后Looper里面通过mThreadLocal 的set方法保存主线程

然后再调用Looper.loop();这时候会开启无限循环

2:Looper.getMainLooper 会调用get方法 这个时候就拿到了主线程的Looper 以及里面保存的messageQueue

然后 handler调用post 其实也就是在主线程的messageQueue上插入一个信息

那么loop 方法里面就检测到了,这时候已经是切换到主进程了.

看源码比较能清晰整个流程

时间: 2024-12-14 11:49:57

Android消息机--handler的自我总结的相关文章

android 消息系统Handler、MessageQueue、Looper源码学习

android消息系统 整体框架如图所示 在安卓的消息系统中,每个线程有一个Looper,Looper中有一个MessageQueue,Handler向这个队列中投递Message,Looper循环拿出Message再交由Handler处理.整体是一个生产者消费者模式,这四部分也就构成了android的消息系统. 先来看一个最简单的例子 //这段代码在某个Activity的onCreate中 Handler handler = new Handler(Looper.getMainLooper()

Android消息机制Handler的实现原理解析

Android的主线程为什么可以一直存在? 线程是一个动态执行的过程,从产生到死亡包括五个状态:新建.就绪.运行.死亡和堵塞.只要线程没有执行完毕或者没有被其它线程杀死,线程就不会进入死亡状态.Android中的主线程一直存在是因为主线程中一直在监听消息,从而使线程无法被执行完毕. 线程的五种状态: 新建new Thread 当创建Thread类的一个实例对象时,此线程进入新建状态未被启动. 就绪runnable 线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等

Android消息机制Handler、Looper、MessageQueue源码分析

1. Handler Looper MessageQueue的关系 2.源码分析 下图表示了Handler.Looper.MessageQueue.Message这四个类之间的关系. Handler必须与一个Looper关联,相关Looper决定了该Handler会向哪个MessageQueue发送Message 每一个Looper中都包含一个MessageQueue Handler中的mQueue引用的就是与之关联的Looper的MessageQueue 不管Handler在哪个线程发送Mes

android 消息系统Handler、MessageQueue、Looper源代码学习

android消息系统 总体框架如图所看到的 在安卓的消息系统中,每一个线程有一个Looper,Looper中有一个MessageQueue,Handler向这个队列中投递Message,Looper循环拿出Message再交由Handler处理.总体是一个生产者消费者模式,这四部分也就构成了android的消息系统. 先来看一个最简单的样例 //这段代码在某个Activity的onCreate中 Handler handler = new Handler(Looper.getMainLoope

Android消息机制Handler解析(源码+Demo)

Handler是开发人员在面试过程中最常见的问题之一了,这篇文章将较为全面地对Handler进行解读,包括源码层,以及使用方法. 如果看完文章有疑问,欢迎在评论中一起探讨 基本内容包括: 看完文章之后,可以用这个图片进行复习. 一.什么是Handler Handler是Android提供用来更新UI的一套机制,也是一套消息处理机制,可以用它来发送消息,也可以用它来接收消息. 二.为什么使用Handler Android在设计之时,就封装了一套消息的创建.传递.处理机制,若不遵循这样的处理机制,就

Android消息机制——Handler

1 /**android的消息处理有三个核心类:Looper,Handler和Message.其实还有一个MessageQueue(消息队列), 2 * 但是MessageQueue被封装到Looper里面了. 3 * 4 * Looper 5 * 6 * Looper 循环着.被设计用来使一个普通线程变成Looper线程. 7 * Looper.prepare()将当前线程初始化为Looper线程 8 * ....实例化Handler,处理消息 9 * Looper.loop()开始循环处理消

[Android源代码分析]Android消息机制,Handler,Message,Looper,MessageQueue

最近准备把Android源码大致过一遍,不敢私藏,写出来分享给大家,顺便记录一下自己的学习感悟.里面一定有一些错误的地方,希望广大看客理解理解. 网上也有不少分析文章,这里我尽量分析的更加细致详尽.不留死角. 一.核心循环体:Looper.loop(); 我们知道,在线程run()中Looper.prepare();Looper.looper().之后这个线程就是一个HandlerThread了.我们可以通过Handler在另外一个线程中(自己也可以)向这个线程发送消息,在这个线程中处理消息.

Android消息机制之Handler

Android为什么要提供Handler Android建议我们不要在UI线程中执行耗时操作,因为这很容易导致ANR异常(在Android源码中我们可以看到,UI如果对用户的操作超过5秒无响应,就会报ANR异常).因此,一些耗时操作都会在子线程中完成.当我们在子线程中获取了数据,要将其显示到UI中,如果没有Handler,这将很难完成.因此,Android之所以提供Handler,就是为了解决子线程访问UI的问题.为什么Android不允许在子线程中访问UI呢?显然这样做不安全,多线程访问UI是

Android中利用Handler实现消息的分发机制(三)

在第二篇文章<Android中利用Handler实现消息的分发机制(一)>中,我们讲到主线程的Looper是Android系统在启动App的时候,已经帮我们创建好了,而如果在子线程中需要去使用Handler的时候,我们就需要显式地去调用Looper的 prepare方法和loop方法,从而为子线程创建其唯一的Looper. 具体代码如下: class LooperThread extends Thread { public Handler mHandler; public void run()