Runnable 並不一定是新開一個線程,比如下面的調用方法就是運行在UI主線程中的:
Handler mHandler=new Handler(); mHandler.post(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub } });
官方對這個方法的解釋如下,注意其中的:“The runnable will be run on the user interface thread. ”
boolean android.view.View .post(Runnable action)
Causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread.
Parameters:
action The Runnable that will be executed.
Returns:
Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting.
我們可以通過調用handler的post方法,把Runnable對象(一般是Runnable的子類)傳過去;handler會在looper中調用這個Runnable的Run方法執行。
Runnable是一個接口,不是一個線程,一般線程會實現Runnable。所以如果我們使用匿名內部類是運行在UI主線程的,如果我們使用實現這個Runnable接口的線程類,則是運行在對應線程的。
具體來說,這個函數的工作原理如下:
View.post(Runnable)方法。在post(Runnable action)方法裏,View獲得當前線程(即UI線程)的Handler,然後將action對象post到Handler裏。在Handler裏,它將傳遞過來的action對象包裝成一個Message(Message的callback爲action),然後將其投入UI線程的消息循環中。在Handler再次處理該Message時,有一條分支(未解釋的那條)就是爲它所設,直接調用runnable的run方法。而此時,已經路由到UI線程裏,因此,我們可以毫無顧慮的來更新UI。
如下圖,前面看到的代碼,我們這裏Message的callback爲一個Runnable的匿名內部類
這種情況下,由於不是在新的線程中使用,所以千萬別做複雜的計算邏輯。