執行緒 Thread
當應用程式啟動時,系統會為執行該應用程式建立一個稱為「主要」的執行緒。 執行緒除了負責處理程式大部份的運算,還需負責協調各介面的事件,如繪製事件等。 應用程式與UI元件互動時,也需要使用這個執行緒。 因此,主要執行緒有時也稱為 UI 執行緒。
系統「不會」為每個元件執行個體建立個別的執行緒。以相同處理程序執行的所有元件都是利用 UI 執行緒來具現化,而且都是由該執行緒分配系統呼叫的每個元件。 因此,回應系統回呼的方法 (例如報告使用者動作的onKeyDown()
)或生命週期回呼方法) 一律會以該處理程序的 UI 執行緒執行。
當應用程式密集執行作業以回應使用者互動時,這種單一執行緒會降低效能。 假設一切都在 UI 執行緒中進行,如果執行像是網路存取或資料庫查詢的長時間操作,將會封鎖整個 UI。當執行緒遭到封鎖時,會無法分配任何事件 (包括繪製事件)。 從使用者的觀點來看,應用程式似乎閒置不動。 更糟的是,如果 UI 執行緒遭到封鎖長達數秒 (目前約為 5 秒),就會向使用者顯示的「應用程式沒有回應」(ANR) 對話方塊。
Thread 範例
class MyThread extends Thread {
@Override
public void run() {
super.run();
try {
//DO SOMETHING
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
}
}
}
private void runThread() {
MyThread myThread = new MyThread();
myThread .start();
}
不過使用 Thread 執行長時間的工作時,若需要與UI互動時,需要使用 Handler 來處理之間的互動。Handler負責傳送訊息,交給MessageQueue進行排隊,再透過Looper將每一個Message Object丟給Handler處理。
Message msg = mHandler.obtainMessage();
msg.what = WHAT_UPDATE_PROCESS;
// 附加參數
Bundle data = new Bundle();
data.putInt(UPDATE_PROCESS, tProgress);
msg.setData(data);
mHandler.sendMessage(msg);
static class MyHandler extends Handler {
private final WeakReference<ThreadSampleActivity> mThis;
public MyHandler(ThreadSampleActivity activity) {
mThis = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
ThreadSampleActivity activity = mThis.get();
if (activity != null) {
try {
switch (msg.what) {
case WHAT_UPDATE_PROCESS:
int progress = msg.getData().getInt(UPDATE_PROCESS);
mThis.get().mProgressDialog.setProgress(progress);
break;
default:
break;
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
}