在主線程中更新ui,一般有兩個方法,使用handle和runonuithread的方法
1. 使用handle的方法更新ui
2. 使用runonuithread更新ui
activity.this. runonuithread(new runnable()
});
3. 原碼分析
在android開發的過程中,主線程主要來完成ui繪製和響應使用者的操作,預設情況下,我們大部分的**都是在主線程
中執行的,因此我們時刻要考慮主線程的情況。我們都知道要開啟乙個子執行緒來完成乙個耗時操作,以避免阻塞主線程影響
使用者體驗,甚至anr。但是子執行緒執行完要更新ui的時候,我們又必須回到主線程來更新,實現這一功能常用的方法是執行
activity的runonuithread()方法:
runonuithread(new runnable()
});這樣就可以很神奇的使run()中的方法在主線程中執行。那麼runonuithread()是怎麼使run()中的**在主線程中執行的呢?
開始分析
先從activity的部分原始碼開始:
final handler mhandler = new handler();
private thread muithread;
// ...
public final void runonuithread(runnable action) else
// ...
}**很簡單,首先判斷當前的執行緒是否是主線程,如果是住執行緒就直接執行runnable介面的run()方法;但如果不是主線程
呢?這時呼叫handler的post(runnable)方法。那麼這個過程又發生了什麼了呢?讓我們從looper說起。
looper
我們建立乙個執行緒並重寫它的run()方法,如下:
public class mythread extends thread
}當這個run()方法中的語句執行完的時候,這個執行緒就結束了,無用了。如果我們為了減小記憶體而不建立新的執行緒來復用
這個執行緒的時候,我們需要它保持存活並等待新的指令。常見的做法是建立乙個迴圈:
public class mythread extends thread }}
只要while迴圈沒執行完,執行緒就保持存活。這就是looper可以實現的,looper字面意思就是「迴圈」,保持執行緒存活。
關於looper值得一提的事:
* 執行緒預設不會得到looper;
* 可以再執行緒中建立乙個looper;
* 每個執行緒只能建立乙個looper。
下面我們用looper替換white迴圈:
public class mythread extends thread
}呼叫looper.prepare()檢查當前執行緒中是否有looper,如果沒有則建立。呼叫looper.loop()後looper開始迴圈。
這樣,looper迴圈並保持執行緒存活,但這樣什麼也不做的執行緒存活是沒有意義的。
當建立looper時,它建立了乙個訊息佇列(messagequeue),用來存放訊息(message)。
什麼是訊息
message實際上就是一些指令的集合。它能保持string,int,runnables等資料型別。
如果我們想要在特定的執行緒執行runnables,我們只需將runnables放到訊息中,並將訊息放到這個執行緒的looper建立
的訊息佇列中!那麼如何放到訊息佇列中呢?又用到了handler。
handler
handler就是處理者的意思,他負責將訊息放到looper的訊息佇列中,當到了執行的時候,他又負責在looper所繫結的
執行緒中執行這個訊息。
handler被建立的時候是指向特定的looper的。有兩種不同的建立方式:
1. 在構造方法中指定looper:
handler handler = new handler(looper looper);
2. 使用空構造方法,此時指向當前執行緒的looper:
handler handler = new handler();
handler能非常便利的建立訊息並將其新增到looper的訊息佇列末尾,如post()。
所以,我們只需將runnable傳到post()中:
handler.post(new runnable()
});是不是看上去很眼熟了。
結論重新回過頭來看runonuithread()的原始碼:
final handler mhandler = new handler();
private thread muithread;
// ...
public final void runonuithread(runnable action) else
// ...
}首先在主線程裡通過無參的構造方法建立乙個handler,這個handler是指向主線程的。
當執行runonuithread()時,當前執行緒不是主線程,呼叫mhandler.post(action),將runnable新增到主線程的訊息佇列中
這樣,runnable的語句就是在主線程執行的了。
---------------------
原文:
runOnUiThread簡單應用
首先runonuithread是activity內部的方法,在運用的時候最好指明當前環境變 context new thread new runnable start new thread new runnable start 上面兩個其實原理一樣,runonuithread這個會呼叫父類中的 pu...
visual studio在主工程中匯入靜態庫工程
又他媽的乙個上午浪費到這樣乙個無意義的事情中了。需求 我需要將別人的vs工程匯入到自建的工程檔案中,就是已經獲取了別人的vs工程的原始碼,要把它當做乙個靜態庫使用。這個問題,可能太簡單,以至於網上在這裡語焉不詳。本人是使用vs的小白,今天才開始用,且是情非得已。平時,用這麼大的ide,有必要嗎。這個...
在主函式內使用巨集定義
之前習慣於在主函式外面使用巨集定義,但實際上主函式內也可使用,例 include include include include include include intmain define min x,y x y x y char const end ptr g 8 char tmp ptr g ...