博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
handler looper和messageQueue
阅读量:5306 次
发布时间:2019-06-14

本文共 5018 字,大约阅读时间需要 16 分钟。

一、用法。

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;}

转载于:https://www.cnblogs.com/gcczhongduan/p/4568949.html

你可能感兴趣的文章
SpringBoot 项目 部署 jar方式
查看>>
SYSUCPC2017 1007 Tutu’s Array II
查看>>
NGUI使用Bitmap制作特殊数字
查看>>
第二阶段冲刺01
查看>>
三层架构
查看>>
204
查看>>
Requests基础的一些应用和Xpath
查看>>
~ 按位取反
查看>>
go语言通过反射创建结构体、赋值、并调用对应方法
查看>>
(转载)详解Tomcat 配置文件server.xml
查看>>
Class.forName()与包的问题
查看>>
Oracle中创建数据链
查看>>
Appium环境搭建(Mac版)
查看>>
通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!...
查看>>
以太坊(二)安装Solidity编译器
查看>>
Niginx简单的配置
查看>>
从关联数组中取得键名
查看>>
112. Path Sum
查看>>
谈首次软工作业感受_苏若
查看>>
培训班出来的你还好吗
查看>>