android looper 机制,android中的Looper实现机制

Looper类是android系统中重要的类,用于处理android线程方面的应用。它的主要作用是初始化MessageQueue类,并且分配消息的处理。Looper类的源码非常简短,可以好好的分析一下源码:

private static final String TAG = "Looper";

// sThreadLocal.get() will return null unless you've called prepare().

static final ThreadLocal sThreadLocal = new ThreadLocal();

private static Looper sMainLooper;  // guarded by Looper.class

final MessageQueue mQueue;

final Thread mThread;

volatile boolean mRun;

private Printer mLogging;

在这些成员变量中,最重要的属性分别是sThreadLocal和mQueue,sThreadLocal是ThreadLocal类型的变量,对于这个ThreadLocal类型,正确的理解应该是ThreadLocalVariable,是一个线程本地化的变量,对于这个对象在每个线程中都像是拥有单独的变量一样,这样多个线程之间就不会产生竞争关系。mQueue是一个MessageQueue对象,暂时可以理解是一个阻塞队列,后面再去详细介绍。那么对于非UI线程的线程,使用Looper的第一步都是Looper.prepare()方法,那么这个方法都做了什么呢?

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

}

private Looper(boolean quitAllowed) {

mQueue = new MessageQueue(quitAllowed);

mRun = true;

mThread = Thread.currentThread();

}

在这个方法中,我们可以清楚看到Looper设置了sThreadLocal的值和初始化了MessageQueue。接下来调用的是Looper.loop()方法。

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

Printer logging = me.mLogging;

if (logging != null) {

logging.println(">>>>> Dispatching to " + msg.target + " " +

msg.callback + ": " + msg.what);

}

msg.target.dispatchMessage(msg);

if (logging != null) {

logging.println("<<<<

}

// Make sure that during the course of dispatching the

// identity of the thread wasn't corrupted.

final long newIdent = Binder.clearCallingIdentity();

if (ident != newIdent) {

Log.wtf(TAG, "Thread identity changed from 0x"

+ Long.toHexString(ident) + " to 0x"

+ Long.toHexString(newIdent) + " while dispatching to "

+ msg.target.getClass().getName() + " "

+ msg.callback + " what=" + msg.what);

}

msg.recycle();

}

}

在这个方法中,Looper首先是取出来一个本地化线程下的Looper对象,然后取出该对象中的MessageQueue。然后在for(;;;)语句中循环去取出MessageQueue中的Message对象,然后调用message.target对象的dispatchMessage()方法分发消息,此时的target对象就是一个Handler对象。所以对于Looper类的理解就是:初始化一个MessageQueue和一个本地化变量的Looper,这样handler类就可以通过sendMessage等方法将消息添加到MessageQueue中,并且通过looper方法将消息不断的取出分发到对应的handler去处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值