Essentials系列主要是讲原理和实现,应用可以参考API说明和APIDemo
一直觉得搞Android的开发,还是看原生的SDK说明 + source code比较好。关键是要思考。
搞Handler也一样,先上原版的说明。
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. 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.
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
Scheduling messages is accomplished with the
post, postAtTime(Runnable, long), postDelayed, sendEmptyMessage, sendMessage, sendMessageAtTime, and sendMessageDelayed methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage method (requiring that you implement a subclass of Handler).
When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.
When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will than be scheduled in the Handler's message queue and processed when appropriate.
Thread ---- Looper
Looper ---- MessageQueue
一个Thead里面有一个looper [thread 跟looper的关系 注1]
一个Looper里面有一个MessageQueue
[注1 可以看Looper的api介绍,有讲怎么在自定义的thread里面建立Looper]
1. Insert message to MessageQueue(入链表)
看一句常用的code
mHandler.sendEmptyMessage(1);
这个send的动作是阻塞式(synchronized)的,如果有其它thread也在向同一个handler send message,那当前thread就会被block
Message msg = Message.obtain();
sendMessageAtTime
sent = queue.enqueueMessage(msg, uptimeMillis);
MesaageQueue
Message mMessages;
这里是一个
链表,按when排序,从小到大的链表。
enqueueMessage就是按when插入链表的动作
2. 出链表
先查出链表的method,
猜测
next, poke, pullNextLocked
final Message next() {
// Try to retrieve the next message, returning if found.
synchronized (this) {
now = SystemClock.uptimeMillis();
Message msg = pullNextLocked(now);
if (msg != null) return msg;
if (tryIdle && mIdleHandlers.size() > 0) {
idlers = mIdleHandlers.toArray();
}
}
}
final Message pullNextLocked(long now) {
Message msg = mMessages;
if (msg != null) {
if (now >= msg.when) {
mMessages = msg.next;
if (Config.LOGV) Log.v(
"MessageQueue", "Returning message: " + msg);
return msg;
}
}
return null;
}
好,就是这个了next(), pullNextLocked()
再找invoke这个method的地方
先猜,一定是个一直在跑的死循环
结果找到
Looper.java
public static final void loop() {
while (true) {
Message msg = queue.next(); // might block
msg.target.dispatchMessage(msg);
}
}
那谁又在invoke这个呢?
请教Changer大神
找到了调用Looper.loop()的地方
在ActivityManagerService
static class AThread extends Thread {
public void run() {
Looper.prepare();
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
ActivityManagerService m = new ActivityManagerService();
synchronized (this) {
mService = m;
notifyAll();
}
synchronized (this) {
while (!mReady) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
Looper.loop();
}
}
原来touchEvent也是由这个Looper来存储的。 //Point 1 这句是错的。Touch等事件传递不走这边。!!!
这个Looper.loop() might block
UI的display和消息的队列是一起建立起来的。
并且是跑在一个Thread的里面的,是序列化的动作。
问题1:在loop()取不到消息就会阻塞,那我写的onCreate(), onStart()函数怎么跑?!!!他们都在一个thread里面哎。
刚刚想了一下,是不是跑到Looper.loop()的时候,onCreate(), onStart(), onResume()都已经跑完了。
又请教了下Changer大神。真的已经跑完了。大神作用就是大啊。
Looper.loop()在所有的东西都显示出来以后,就调用起来了。然后等待消息驱动,这就是所谓的事件驱动啊。
问题2: 可是,这个时候我touch一下,又是谁往MessageQueue里面插入touch消息的呢?
我想消息肯定是从其它Thread里面插入的。// Point 2 ,error !!!
这个再议。关于事件传递,关于view的显示我们先搁着。
这次强调一下,TouchEvent的传递跟Looper的MessageQueue是两码事。灰化的文字是错的。
3. 整个Flow
现在回过头来看下整个Flow
当Looper.loop调起的时候,
如果消息,它就会分发出去(这里面还包括消息时间未到的情况)。
如果没有,它就会等待。
看code, MessageQueue.java next()
synchronized (this) {
// No messages, nobody to tell about it... time to wait!
try {
if (mMessages != null) {
if (mMessages.when-now > 0) {
Binder.flushPendingCommands();
this.wait(mMessages.when-now);
}
} else {
Binder.flushPendingCommands();
this.wait();
}
}
catch (InterruptedException e) {
}
}
直到其它的Thread,通过Handler发了一条消息,插入MessageQueue,然后会Notify出来。
这样,整个Flow就跑通了。
看code, MessageQueue.java
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
this.notify();
} else {
Message prev = null;
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
msg.next = prev.next;
prev.next = msg;
this.notify();
}
分享到:
相关推荐
"android_essentials-4026.zip" 提供的资源无疑是学习Android开发的一份宝贵资料,旨在帮助初学者和有经验的开发者深入理解Android平台的核心概念和技术。 1. **Android系统架构**:Android系统由Linux内核、运行库...
《Android Essentials》是一本专注于Android应用开发的参考书籍,它为开发者提供了全面的Android平台知识,帮助他们构建高质量的移动应用程序。这本书详细介绍了Android开发环境的搭建、编程基础、UI设计、数据存储...
源代码可能包含AsyncTask、Handler、Looper等多线程和异步处理的实例。 十四、网络编程 Android应用经常需要访问网络资源,例如HTTP请求、WebSocket通信等。源代码中可能包含网络请求的实现,如使用...
10. **多线程和异步处理**:讨论如何在Android应用中有效地处理多任务,如使用Handler、AsyncTask、Thread和IntentService。 11. **资源管理**:包括本地化、图标的适配和尺寸优化,以及如何有效利用资源文件。 12...
11. **多线程与异步处理**:Android应用通常需要在后台执行任务以避免阻塞UI线程,因此,书中会介绍AsyncTask、Handler、Looper和Thread池等并发技术。 12. **通知(Notification)**:通知是向用户显示重要信息的...
此外,Android的异步处理机制,如Intent、AsyncTask和Handler/Looper,是避免阻塞主线程的关键。理解这些工具的工作原理和应用场景,能帮助开发者编写出流畅、响应迅速的应用。 对于数据存储,Android提供了SQLite...
9. **多线程与异步处理**:Android开发中,理解和使用Handler、Looper、AsyncTask等机制处理后台任务是提高应用性能的关键。 10. **性能优化**:包括内存管理、渲染性能优化、电量优化等方面的知识,帮助你打造高效...