handler.post()方法的执行时机

时间:2022-05-29 17:32:49

有如下场景,在onCreate()方法里执行handler.post(new Runnable())

public class ProgressBarActivity extends Activity {
private final static String TAG = "ProgressBarActivity";

private Runnable test = new Runnable(){
@Override
public void run() {
try {
Thread.sleep(10000);
Log.i(TAG,"Thread---->"+Thread.currentThread().getId());
Log.i(TAG,"Thread---->"+Thread.currentThread().getName());
} catch (InterruptedException e) {}
}
};
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler.post(test);
this.setContentView(R.layout.progress_bar_layout);
Log.i(TAG,"Activity--->"+Thread.currentThread().getId());
Log.i(TAG,"Activity--->"+Thread.currentThread().getName());
}

以上代码里的test会立马执行或者说在activity的log日志前执行吗?
看下打印结果:

06-04 14:13:09.964: INFO/ProgressBarActivity(366): Activity--->1

06-04 14:13:09.964: INFO/ProgressBarActivity(366): Activity--->main

06-04 14:13:20.070: INFO/ProgressBarActivity(366): Thread---->1

06-04 14:13:20.070: INFO/ProgressBarActivity(366): Thread---->main

都知道post(new Runnable())也是在主线程里执行的,那为什么从打印结果上看是先走完oncreate方法再执行runnable里的方法呢?这个要从handler原理说起:

  • 当Android应用程序启动时,framework会为该应用程序的主线程创建一个Looper对象。这个Looper对象包含一个简单的消息队列Message Queue,并且能够循环的处理队列中的消息。这些消息包括大多数应用程序framework事件,例如Activity生命周期方法调用、button点击等,这些消息都会被添加到消息队列中并被逐个处理。

所以Activity生命周期方法调用其实也是通过handler来处理的,oncreate调用和post(new Runnable())对于handler来说都是一个message的处理,都存在主线程的message queue里,但队列是FIFO原则,所以Runnable()必须等oncreate这条message处理完才能处理自己的这条message。

You have it wrong: the docs here say this:

Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.
That means the Runnable will be run on the Activity's main thread, but will be queued up and run AFTER the thread is done with its current work. The current work is completing onCreate, so after onCreate finishes the thread is now free and will process the Runnable. This is why you see the Activity text before the Runnable text: the current thread can not just stop what its doing and pick up the Runnable.

关于以上demo相关的*地址