Android消息传递机制

背景需求

在Android中,当遇到子线程需要刷新UI时,最常的做法就是handler,当然还有其他方便的方法如Android给我们提供的runOnUiThread(runnable)方法,但归根结底都是使用handler来刷新UI的。

Android消息传递原理

简单的讲:handler发送(post或send)一条消息;MessageQueue(队,实际上是一个用单链表实现的队列)接受并存储该消息;looper无限循环的从MessageQueue中取出一条消息,例如msg,然后调用msg.target.dispatchMessage(msg)方法对msg进行处理。其中msg.target为发送该msg的handler。

源码解读

Handler

Handler在Android消息传递过程中,主要负责发送消息和处理事件。

当handler发送一条消息时,无论是使用handler.postXX()还是使用handler.sendXXX()最终调用的都是:

 public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }

其中enqueueMessage()方法是执行单链表在队尾的插入操作,该方法主要完成的是想messagequeue中插入一条消息。

dispatchMessage(Message msg)方法:

 public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

在looper.loop()方法中,调用该方法对消息msg进行处理。

几点说明:

  1. msg.callback中的callback实际上是handler.post(runable r)中的r。handleCallback代码:
private static void handleCallback(Message message) {
        message.callback.run();
    }

从这可以看出,handleCallback实际操作是调用r.run()方法,即调用post过来的线程的run方法执行该线程的逻辑。

 2. mCallback :当我们创建一个handler对象时,handler有一个构造方法:
public Handler(Callback callback){
        this(callback, false);
    }

其中Callback是一个接口,即:

public interface Callback {
        public boolean handleMessage(Message msg);
    }

mCallback.handleMessage(msg)实际调用的就是构造handler时传入的callback对象的handlermessage方法。

3. 最后调用的 handleMessage(msg)方法实际上是我们自己构造一个handler时 @Override 的handleMessage(Message msg)方法。


需要特别指明的是:

handler.post(runnable r)实际执行在handler所在的线程中。

官方说明为:

*Causes the Runnable r to be added to the message queue.

* The runnable will be run on the thread to which this handler is

* attached. *

在view中也有类似的post(runnable r)方法,但该方法执行在UI线程中。

官方说明为:

Causes the Runnable to be added to the message queue.The runnable will be run on the user interface thread.


Looper

在一个线程中,只有一个Looper对象。Looper在实现上使用的是单例模式。

Looper.prepare()代码:

private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

new Looper(quitAllowed)代码:

private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();//当前looper所在线程
    }

在这里可以看出,looper的构造方法是私有的,表明当前Looper使用的是单例模式,只有在myLooper()方法中才返回,代码 :return sThreadLocal.get()

总结

Handler:发送和处理message

Looper:为一个线程创建以messagequeue,使得在该线程中可以使用Handler。

时间: 2024-10-29 09:25:26

Android消息传递机制的相关文章

android 消息传递机制EventBus的深入探究

以前,对于activity和fragment之间的通信可以使用接口的方式,定义起来比较麻烦费事,偶然间发现可以使用EventBus,发现很好用,查看了一下官方说明:EventBus是针一款对Android的发布/订阅事件总线.它可以让我们很轻松的实现在Android各个组件之间传递消息,并且代码的可读性更好,耦合度更低.但是在用的过程中总会出现一些问题,下面就将出现的问题详细记录一下,顺便具体学习EventBus(GreenRobot)这个第三方开源库,了解它内部的实现原理,以至于出了问题可以快

android触碰消息传递机制

前阵子要的工作是给桌面(Launcher启动器,其实也是一个activity)添加一个触摸特效(一个View),而这个特效是每次触碰都会有,不管你在桌面上做什么操作都会显示特效!之前一直摸索着不知道如何入手,后来慢慢的实验之后才知道有个android触碰消息传递机制.自己摸索的确很慢,要是早点知道这个机制那将会事半功倍. 用户的每次触碰(onClick,onLongClick,onScroll,etc.)都是由一个ACTION_DOWN+n个ACTION_MOVE+1个ACTION_UP组成的,

Android异步消息传递机制源码分析&&相关知识常被问的面试题

1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.postDelay(Runnable r, time)来在指定时间执行msg. 2).线程间通信:在执行较为耗时操作的时候,在子线程中执行耗时任务,然后handler(主线程的)把执行的结果通过sendmessage的方式发送给UI线程去执行用于更新UI. 3.handler源码分析 一.在Activ

Android笔记二十五.Android事件Handler消息传递机制

因为Android平台不同意Activity新启动的线程訪问该Activity里的界面控件.这样就会导致新启动的线程无法动态改变界面控件的属性值.但在实际Android应用开发中,尤其是涉及动画的游戏开发中,须要让新启动的线程周期性地改变界面控件的属性值,这就须要借助Handler的消息传递机制实现. 一.Handler类简单介绍 1.功能 Handler类主要有两个作用 (1)在新启动的线程中发送消息; (2)在主线程中获取消息.处理消息.即当须要界面发生变化的时候.在子线程中调用Handle

解析Android的 消息传递机制Handler

1. 什么是Handler: Handler 网络释义"操纵者,管理者的"意思,在Android里面用于管理多线程对UI的操作: 2. 为什么会出现Handler: 在Android的设计机制里面,只允许主线程(一个程序第一次启动时所移动的线程,因为此线程主要是完成对UI相关事件的处理,所以也称UI线程) 对UI进行修改等操作,这是一种规则的简化,之所以这样简化是因为Android的UI操作时线程不安全的,为了避免多个线程同时操作UI造成线程安全 问题,才出现了这个简化的规则. 由此以

Android基础入门教程——3.3 Handler消息传递机制浅析

Android基础入门教程--3.3 Handler消息传递机制浅析 标签(空格分隔): Android基础入门教程 本节引言 前两节中我们对Android中的两种事件处理机制进行了学习,关于响应的事件响应就这两种:本节给大家讲解的 是Activity中UI组件中的信息传递Handler,相信很多朋友都知道,Android为了线程安全,并不允许我们在UI线程外操作UI:很多时候我们做界面刷新都需要通过Handler来通知UI组件更新!除了用Handler完成界面更新外,还可以使用runOnUiT

Android Handler消息传递机制

1. Handler消息传递机制初步认识:什么是Handler? handler通俗一点讲就是用来在各个线程之间发送数据的处理对象.在任何线程中,只要获得了另一个线程的handler,则可以通过 handler.sendMessage(message)方法向那个线程发送数据.基于这个机制,我们在处理多线程的时候可以新建一个thread,这个thread拥有UI线程中的一个handler.当thread处理完一些耗时的操作后通过传递过来的handler向UI线程发送数据,由UI线程去更新界面. 主

Android学习之Handler消息传递机制

Android只允许UI线程修改Activity里的UI组件.当Android程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件.屏幕绘图事件,并把相关的事件分发到对应的组件进行处理.所以,主线程通常又被称为UI线程. Android只允许UI线程修改Activity里的UI组件,这样会导致新启动的线程无法动态改变界面组件的属性值.但在实际的Android程序开发中,尤其是涉及动画的游戏开发中,需要让新启动的线程周

android线程消息传递机制——Looper,Handler,Message

android线程消息传递机制——Looper,Handler,Message 在引入这些概念之前,我们先了解一下引入这些机制的背景. 出于性能优化的考虑,Android的UI操作并不是线程安全的(如果你不懂什么是线程安全,可以阅读一下<一起探究多进程与多线程>里的数据安全与可重入),这意味着如果有多个线程同时操作某个UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件.这个UI线程也通常被我们称为主线程. 在此引