当前位置:首页 > > 充电吧
[导读]Android没有全局的消息队列,Android的消息队列是和某个线程相关联在一起的。每个线程最多只有一个消息队列,消息的处理也是在这个线程中完成。也就是说,如果想在当前线程中使用消息模型,则必须构建

Android没有全局的消息队列,Android的消息队列是和某个线程相关联在一起的。每个线程最多只有一个消息队列,消息的处理也是在这个线程中完成。也就是说,如果想在当前线程中使用消息模型,则必须构建一个消息队列,消息机制的主要类是:Looper、Handler、MessageQueue、Message. 1、
public class Handler extends Object
java.lang.Object    ↳ android.os.Handler Class Overview

A Handler allows you to send and process Message and Runnable objects associated with a thread'sMessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
 

 mHandler = new Handler(){
	public void handleMessage(Message msg){
//int android.os.Message.what
//User-defined message code so that the recipient can identify what this message is about.
switch(msg.what){
		 case UPDATE_TEXT:
		mTextView.setText("text changed");
		 break;
		default:
		 break;
		}
	                                }
		};



public final boolean sendMessage(Message msg)Added inAPI level 1

Pushes a message onto the end of the message queue after all pending messages before the current time. It will be received inhandleMessage(Message), in the thread attached to this handler.

Returns Returns true if the message was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting.

Message mMessage = Message.obtain(mHandler, UPDATE_TEXT);

//Pushes a message onto the end of the message queue after all pending messages before the current time. 
mHandler.sendMessage(mMessage);

Handler负责将Message发送至当前线程的MessageQueue中,处理消息。发送消息一般是使用Handler的sendMessage方法,发出的消息最终会传递到Handler的handleMessage()方法中。
public final class 2、 Looper extends Object
java.lang.Object    ↳ android.os.Looper Class Overview

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, callprepare() in the thread that is to run the loop, and thenloop() to have it process messages until the loop is stopped.

Most interaction with a message loop is through the Handler class. 

Looper时时刻刻监视着MessageQueue,是每个线程中的MessageQueue管家,每个线程中只有一个Looper,调用其loop()方法就会进入到一个无限循环中,每当发现MessageQueue中存在一条消息,就会把它取出,送到Handler中的handleMessage()中。 public final class 3、
MessageQueue extends Object
java.lang.Object    ↳ android.os.MessageQueue 消息队列,每个线程中只会有一个MessageQueue。主要存放所有通过Handler发送的消息。

4、 public final class Message extends Object
implements Parcelable java.lang.Object    ↳ android.os.Message Class Overview

Defines a message containing a description and arbitrary data object that can be sent to aHandler. This object contains two extra int fields and an extra object field that allow you to not do allocations in many cases. 


//Message android.os.Message.obtain(Handler h, int what)
Message mMessage = Message.obtain(mHandler, UPDATE_TEXT);

Message是在线程之间传递消息,它可以在内部携带少量信息,如what字段、arg1、arg2来携带一些整型数据、obj携带Object对象,用于在不同线程间交换数据。

异步消息处理的整个流程:
首先需要在主线程中创建一个Handler对象,并重写handleMessage()方法; 然后,当子线程中需要UI操作时,就创建一个Message对象,并通过Handler将消息发送出去; 之后这条消息会被添加到MessageQueue队列中,等待被处理,期间Looper会一直尝试从MessageQueue中取出待处理消息,最后分发到Handler的handleMessage()方法中。由于Handler是在主线程中创建的,因此handleMessage()中的代码也会在主线程中处理。
MeloDev的Message游历:
Message
在边境X(子线程)服役的士兵Message慵懒的躺在一个人数为50(线程中最大数量)的军营(Message池)中。不料这时突然接到上司的obtain()命令,让它去首都(主线程)告诉中央领导一些神秘代码。小mMessage慌乱地整理下衣角和帽子,带上信封,准备出发。上司让士兵mMessage收拾完毕等待一个神秘人电话,并嘱咐他:到了首都之后,0是这次的暗号。

Message mMessage = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("key","这里一切安全");
mMessage.what = 0;
mMessage.obj = bundle;

通常会用obtain()方法创建Message,如果消息池中有Message则取出,没有则创建,这样防止对象重复创建,节省资源。 obtain()方法源码:

 /**
     * Return a new Message instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }


“铃铃铃……”,小mMessage接到一个店换,"我叫Handler,来此Activity大本营,是你这次任务的接收者,一会我会带你去首都的消息中心去报道。"

Handler:
来此Activity大本营的Handler部门是整个消息机制的核心部门,部门里有很多个Handler,这次协助小mMessage的叫mHandler.

 mHandler = new Handler(){
	public void handleMessage(Message msg){
//int android.os.Message.what
//User-defined message code so that the recipient can identify what this message is about.
				
				
			}
		};

Handler属于Activity,创建任何一个Handler都属于重写了Activity的Handler。

在Handler的构造中,默认完成了对当前线程Looper的绑定。

public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }


通过Looper.myLooper()方法获得当前线程保存的Looper实例,通过Looper.mQueue()获得MessageQueue实例, static Looper myLooper()Return the Looper object associated with the current thread. static MessageQueue myQueue()Return the MessageQueue object associated with the current thread. 在此时,mHandler实例与looper、messageQueue实例关联上了。
mHandler神情骄傲的对小mMessage说:我已经跟首都的消息中心打好了招呼,准备接收你了,现在有两种车“send”和“post”你想坐哪辆都可以,不过要根据你上司的命令选择对应的型号哦~
post、send: final boolean post(Runnable r)Causes the Runnable r to be added to the message queue. final boolean postAtFrontOfQueue(Runnable r)Posts a message to an object that implements Runnable. final boolean postAtTime(Runnable r,Object token, long uptimeMillis)Causes the Runnable r to be added to the message queue, to be run at a specific time given by. final boolean postAtTime(Runnable r, long uptimeMillis)Causes the Runnable r to be added to the message queue, to be run at a specific time given by. final boolean postDelayed(Runnable r, long delayMillis)Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses final boolean sendEmptyMessage(int what)Sends a Message containing only the what value. final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)Sends a Message containing only the what value, to be delivered at a specific time. final boolean sendEmptyMessageDelayed(int what, long delayMillis)Sends a Message containing only the what value, to be delivered after the specified amount of time elapses. final boolean sendMessage(Message msg)Pushes a message onto the end of the message queue after all pending messages before the current time. final boolean sendMessageAtFrontOfQueue(Message msg)Enqueue a message at the front of the message queue, to be processed on the next iteration of the message loop. boolean sendMessageAtTime(Message msg, long uptimeMillis)Enqueue a message into the message queue after all pending messages before the absolute time (in milliseconds). final boolean sendMessageDelayed(Message msg, long delayMillis)Enqueue a message into the message queue after all pending messages before (current time + delayMillis). String toString()
分析源码,post方法也是在使用send类在发送消息,除了sendMessageAtFrontOfQueue()外,其余send方法都经过层层包装走到sendMessageAtTime()中。 这时小mMessage和mHandler上了sendMessage的车,行驶在一条叫enqueueMessage的高速公路上进入MessageQueue。将Message按时间排序,放入MessageQueue中。其中mMessage.target = this,是保证每个发送Message的Handler也能处理这个Message。mHandler向小mMessage说,其实你的消息到时候也是我处理的,不过现在还不是时候,因为我很忙。
Looper
路上时间,mHandler为小mMessage热心介绍着MessageQueue和Looper。“在每个驻扎地(线程)中只有一个MessageQueue和一个Looper,他们两个是相爱相杀,同生共死的好朋友,Looper是个跑不死的邮差,一直负责取出MessageQueue中的Message”。 "不过通常只有首都(主线程)的Looper和MessageQueue是创建好的,其他地方需要我们人为创建"。 Looper提供prepare()方法来创建Looper。重复创建会抛出异常,也就是说每个线程只能有一个looper。

Looper.prepare();

static void prepareMainLooper()Initialize the current thread as a looper, marking it as an application's main looper.
Looper的构造方法中,创建了和他一一对应的MessageQueue

private Looper(boolean quitAllowed){
   mQueue = new MessageQueue(quitAllowed);
   mThread = Thread.currentThread();
}


在Android中ActivityThread的main方法是程序入口,主线程的Looper和MessageQueue就是在此刻创建。

mHandler和小mMessage来到了MessageQueue中,进入队列之前,门卫仔细给小mMessage贴上以下标签:“mHandler负责带入”、“处理时间为0ms”并告诉小mMessage一定要按时间顺序排队。进入队伍中,Looper正不辞辛劳的将一个个跟小mMessage一样的士兵带走。 public static void loop() Run the message queue in this thread. Be sure to callquit() to end the loop.   loop()方法有一个for死循环,不断调用queue.next()方法,在消息队列中取出Message。并在Message中取出target,这个target就是发送消息的mHandler调用它的dispatchMessage()方法。
首都的MessageQueue中心虽然message很多,但大家都按时间排着队,轮到mMessage了,Looper看了小mMessage的标签,对他说:“喔,又是mHandler带来的啊,那把你交给他处理了。”忐忑不安的小mMessage看到了一个熟悉的身影,mHandler,可能是接触太多Message,为了让mHandler想起自己,mMessage说出了上司教他的暗号0。

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

dispatchMessage()方法:若mCallback不为空,则调用mCallback的handleMessage();否则,直接调用Handler的handleMessage()方法,并将消息对象作为参数传递过去。在handleMessage()方法中,小mMessage出色的完成了任务。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭