一、用法。

Looper为了应付新闻周期,在创建过程中初始化MessageQueue。

Handler在一个消息到当前线程的其他线程

MessageQueue用于存储所述消息

Looper其中线程创建的对象。Handler的handleMessage方法就在哪个线程运行

在创建activity时,android系统本身会为activity创建Looper。

final Handler mainHandler = new Handler(getMainLooper())
{
@Override
public void handleMessage(Message msg)
{
String content = "当前线程:" + "msg:" + msg.what;
Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
}
};
mainHandler.sendEmptyMessage(0x1);

在其他线程中使用handler消息传递时,必须自己创建looper。以下的样例中HandlerThread封装了Looper和MessageQueue,还实现了获取Looper的同步机制,比較好用。

HandlerThread mThread = new HandlerThread("MyThread");
mThread.start();
Handler mHandle = new Handler(mThread.getLooper())
{
@Override
public void handleMessage(Message msg)
{
String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + msg.what;
System.out.println(content);
}
};
mHandle.sendEmptyMessage(0x2);

二、Looper解析

构造函数:

private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread();
} public static void prepare() {
prepare(true);
} 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));
}

在prepare中创建了Looper实例。并在Looper的构造函数中创建了MessageQueue

public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity(); for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
} // This must be in a local variable, in case a UI event sets the logger
msg.target.dispatchMessage(msg); // Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity(); msg.recycle();
}
}

在loop()中。Looper不断的通过queue.next()从MessageQueue取消息,然后调用语句msg.target.dispatchMessage(msg) 来运行。这里target为msg消息的发送者Handler,在分析Handler时再来分析。dispatchMessage在普通情况下会调用Handler类的handleMessage来处理消息。也就是上面样例中我们重载的这个handleMessage。

三、Handler解析

Handler的构造函数有非常多,这里选带Looper參数的构造函数

public Handler(Looper looper) {
this(looper, null, false);
} public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}

再看sendMessage。

public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
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);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}

sendEmptyMessage将message加到了Looper的MessageQueue中,之后Looper在loop()中调用queue.next()

在enqueueMessage里面。我们看到了msg.target = this

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

假设没有设置Callback的话,就会执行handleMessage了。

四、HandlerThread解析

HandlerThread继承于Thread,对Looper的操作进行了封装,做了同步处理。

public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
} public Looper getLooper() {
if (!isAlive()) {
return null;
} // If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}

handler looper和messageQueue的更多相关文章

  1. Android消息机制探索(Handler,Looper,Message,MessageQueue)

    概览 Android消息机制是Android操作系统中比较重要的一块.具体使用方法在这里不再阐述,可以参考Android的官方开发文档. 消息机制的主要用途有两方面: 1.线程之间的通信.比如在子线程 ...

  2. Handler Looper源码解析(Android消息传递机制)

    Android的Handler类应该是常用到的,多用于线程间的通信,以及子线程发送消息通知UI线程刷新View等等.这里我主要总结下我对整个消息传递机制,包括Handler,Looper,Messag ...

  3. Android消息处理机制(Handler、Looper、MessageQueue与Message)

    Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...

  4. (转)Android消息处理机制(Handler、Looper、MessageQueue与Message)

    转自 http://www.cnblogs.com/angeldevil/p/3340644.html Android消息处理机制(Handler.Looper.MessageQueue与Messag ...

  5. 讲讲Handler+Looper+MessageQueue 关系

    Handler+Looper+MessageQueue这三者的关系其实就是Android的消息机制.这块内容相比开发人员都不陌生,在面试中,或者日常开发中都会碰到,今天就来讲这三者的关系. 概述: H ...

  6. Android的消息机制: Message/MessageQueue/Handler/Looper

    概览   * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...

  7. android学习11——Handler,Looper,MessageQueue工作原理

    Message是Handler接收和处理的消息对象. 每个线程只能拥有一个Looper.它的loop方法读取MessageQueue中的消息,读到消息之后就把消息交给发送该消息的Handler进行处理 ...

  8. Handler,Looper,MessageQueue流程梳理

    目的:handle的出现主要是为了解决线程间通讯. 举个例子,android是不允许在主线程中访问网络,因为这样会阻塞主线程,影响性能,所以访问网络都是放在子线程中执行,对于网络返回的结果则需要显示在 ...

  9. Android 开发 深入理解Handler、Looper、Messagequeue 转载

    转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/73484527 本文已授权微信公众号 fanfan程序媛 独家发布 扫一扫文章底 ...

随机推荐

  1. angular的学习参考材料

    原文地址:https://www.jianshu.com/p/b9db7bb3d4ec 目的 其实写这篇文章的主要目的是为了提供给那些刚刚入门angular或者有意学习angular的读者准备的. 我 ...

  2. Home界面的启动

    继上篇文章Launcher进程的启动,我们继续分析Home界面的启动. public final class ActivityThread { ...... public static final v ...

  3. 曼德勃罗(Mandelbrot)集合与其编程实现

    一.从科赫雪花谈起 设想一个边长为1的等边三角形(例如以下图所看到的).取每边中间的三分之中的一个,接上去一个形状全然类似的但边长为其三分之中的一个的三角形,结果是一个六角形.如今取六角形的每个边做相 ...

  4. Android的NDK开发(1)————Android JNI简介与调用流程

    1.JNI简介 JNI全称为Java Native Interface(Java本地调用).从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C ...

  5. 工具类与工具函数 —— NextPrime

    求大于某数的下一个素数: static int NextPrime (int N) { if (N % 2 == 0) ++N; int i; for (; ; N += 2){ for (i = 3 ...

  6. 【SSH2(理论+实践)】--图说Struts2的执行

        前几篇文章讨论了有关Struts2的核心机制及一些基础,但同一时候也遗留下了非常多问题.这些问题主要是针对Struts2的一些使用技巧的,该篇文章将会针对Struts2的使用技巧进行讨论, ...

  7. java--css+js做的树形菜单(完整版)

    jsp页面: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8 ...

  8. NSURLSession网络接口

    URLSession URLSession NSURLSession是iOS7中新的网络接口,与NSURLConnection是并列的. 当程序在前台时,NSURLSession与NSURLConne ...

  9. BZOJ 2021 Usaco2010 Jan Cheese Towers 动态规划

    题目大意:全然背包.假设最顶端的物品重量≥k,那么以下的全部物品的重量变为原来的45 考虑一些物品装进背包,显然我要把全部重量大于≥k的物品中重量最小的那个放在最顶端.才干保证总重量最小 那么我们给物 ...

  10. MKNetWorkKit的使用(1)

    在整个程序中只有一个全局队列 MKNetWorkKit中主要有两个类,MKNetworkEngine和 MKNetworkOperation,MKNetworkOperation就是一个操作,是NSO ...