不管是C++程序还是Java程序,都会有程序的入口,所有的Java应用程序都是从public static void main 开始,同样Android程序也有同样入口。
public class JavaStart{
public static void main(String... args) {
// The Java universe starts here.
}
}
那么安卓APP的入口在哪里呢?
现在就开始回答这个问题,当Android系统启动的时候,它创建一个称为ZygoteInit的进程,这个进程包含Java虚拟机和大部分公共的Class及Android SDK .当系统启动一个APP时,系统forks这个ZygoteInit进程,然后调用 ActivityThread.main()
函数,所以这个就是安卓APP的入口函数,应用的入口地方。
Loopers
随着我们进一步研究,我们会发现ActivityThread成员 Looper class.从名字就可以看出它是一个无限循环,占据一个循环,另外通过观察如下代码,我们发现它有一个消息队列,用来处理消息。需要注意的我们在开发应用的时候,尽量使用message.obtain来创建消息,这样在loop循环中,我们就可以同message的recycle函数将其回放,达到循环使用,所以尽量不要使用new创建message.
void loop() {
while(true) {
Message message = queue.next(); // blocks if empty.
dispatchMessage(message);
message.recycle();
}
}
每个Looper与一个线程绑定,而为了绑定当前的线程,你可以调用Looper.prepare .这个 loopers 储存在static ThreadLocal,获取与当前线程绑定的looper,可以调用Looper.myLooper()
.
我们可以这样使用Looper,HandlerThread是我自定义的一个类,你可以这样使用它。
HandlerThread thread = new HandlerThread("SquareHandlerThread");
thread.run(); // starts the thread.
类的定义如下:
class HandlerThread extends Thread {
Looper looper;
public void run() {
Looper.prepare(); // Create a Looper and store it in a ThreadLocal.
looper = Looper.myLooper(); // Retrieve the looper instance from the ThreadLocal, for later use.
Looper.loop(); // Loop forever.
}
}
Handlers
Handler 是looper天生的朋友,它有两个目的:
- 从一个线程到当前Looper的消息队列
- 处理looper 消息队列的消息,当然这个handler 必须和这个looper 绑定
// Each handler is associated to one looper.
Handler handler = new Handler(looper) {
public void handleMessage(Message message) {
// Handle the message on the thread associated to the given looper.
if (message.what == DO_SOMETHING) {
// do something
}
}
};
// Create a new message associated to that handler.
Message message = handler.obtainMessage(DO_SOMETHING);
// Add the message to the looper queue.
// Can be called from any thread.
handler.sendMessage(message);
你可以绑定多个hander到looper并且 looper 会传递 message到message.target
.
一个简单并且流行使用 handler的方式是: 发送一个 Runnable.
// Create a message containing a reference to the runnable and add it to the looper queue
handler.post(new Runnable() {
public void run() {
// Runs on the thread associated to the looper associated to that handler.
}
});
一个handler也可以通过如下方式创建!那么它的looper是谁呢?
// DON‘T DO THIS
Handler handler = new Handler();
答案就在这个
Looper.myLooper()
通过这个函数
获得与当前线程绑定的Looper. 当然大多时候,你想handler绑定主线程,你可以这样来做,如下:
Handler handler = new Handler(Looper.getMainLooper());
让我们最后回到这里,APP的入口,看看它做了什么?
public class ActivityThread {
public static void main(String... args) {
Looper.prepare();
// You can now retrieve the main looper at any time by calling Looper.getMainLooper().
Looper.setMainLooper(Looper.myLooper());
// Post the first messages to the looper.
// { ... }
Looper.loop();
}
}
这就是为什么它被称为主线程的原因。
注意: 可能你已经猜到,这个主线程首先会创建Application并且会调用 Application.onCreate()
.