您的位置:首页 > 移动开发 > Android开发

Android关于looper的几个方法的个人理解

2017-10-23 23:41 585 查看
    最近在看android的looper这个类与android的消息队列的处理有一定的紧密关系,今天写一些关于这个类的几个常用的方法,主要是起到自己巩固学习的作用,方便以后自己的查看。1、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));
}
先是判断了一下sThreadLocal是否为空,不为空时报出异常否侧讲一个Looper实例放入其中。这也可以从中看出不可以多次的去调用这个方法,第一次调用后sThreadLocal中就已经是有值的了,如果再次调用就会报错。
2、getMainLooper() 源码如下
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
该方法主要是返回当前进程中的主线程的消息队列。
3、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("<<<<< Finished to " + msg.target + " " + msg.callback);
}

// 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.recycleUnchecked();
}
}
该方法先是判断myLooper的方法返回的是否为空,为空就报错证明你没有向sThreadLocal中放入实例及没有调用到prepare()方法或者调用它的方法。而后获取其消息队列,进行无限循环。
4、Looper() 源码如下
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread [/b]= Thread.currentThread();
}
Looper类的构造方法,创建了一个消息队列。
5、myLooper 源码如下
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
返回存储在sThreadLocal中的looper实例,可以看出在调用该方法前,必须调用prepare()方法或者调用它的方法,不然sThreadLocal中是空的会报错。
6、quit() 源码如下
public void quit() {mQueue.quit(false);}
停止looper。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: