簡介
建立子線程,使用 handler 和 message 更新 UI 界面
Android 定義并啟動線程的方法
繼承 Thread 類
class MyThread extends Thread {
@Override
public void run() {
//處理邏輯
}
}
//啟動
new MyThread().start();
實作 Runnable 接口
class MyThread implements Runnable {
@Override
public void run() {
//處理邏輯
}
}
//啟動
MyThread myThread = new MyThread();
new Thread(myThread).start();
使用匿名類實作 Runnable 接口
new Thread(new Runnable() {
@Override
public void run() {
//處理邏輯
}
}).start();
在子線程中更新 UI
使用 runOnUiThread
是一個異步消息處理機制的接口封裝。
runOnUiThread(new Runnable() {
@Override
public void run() {
text.setText("Nice to meet you 111");
}
});
利用異步消息處理
public static final int UPDATE_TEXT = 1;
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
if(message.what == UPDATE_TEXT) {
text.setText("Nice to meet you");
}
return false;
}
});
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message);
}
}).start();
異步處理機制解析
Android 異步消息處理由四個部分組成:Message、Handler、MessageQueue 和 Looper。
Message
線程之間傳遞的資訊,可攜帶少量的資訊,用于在不同線程之間交換資料;
message 可以攜帶 what 的 int 資料,除此之外 arg1 和 arg2 也可以攜帶 int 資料,obj 攜帶一個 Object 對象。
Handler
用于發送和處理消息。發送消息使用 handler 的 sendMessage 方法;處理消息在 handleMessage 方法中。
MessageQueue
主要存放所有通過 Handler 發送的消息,這部分消息一直存在于消息隊列中,等待被處理。
每個線程隻有一個 MessageQueue 對象。
Looper
是 MessageQueue 的管家;
調用 Looper 的 loop 方法後,就會進入到一個無限循環當中,每當發現 MessageQueue 存在一條消息,就會将它取出來傳遞到 Handler 的 handleMessage 方法中。
每個線程中也隻有一個 Looper 對象。
AsyncTask
Android 封裝的異步消息處理從子線程切換到主線程。
class UpdateTextTask extends AsyncTask<Void, Integer, Boolean> {
//在背景任務開始執行之前調用,做界面上的初始化操作
@Override
protected void onPreExecute() {
text.setText("start");
}
//在子線程中運作,通過 return 傳回結果,調用 publishProgress 方法更新 UI
@Override
protected Boolean doInBackground(Void... voids) {
int count = 0;
while(count != 20) {
publishProgress(++count);
Log.d(TAG, "doInBackground: " + count);
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
return true;
}
//publishProgress 調用最終會到這個函數裡,在這裡對 UI 進行操作。
@Override
protected void onProgressUpdate(Integer... values) {
Log.d(TAG, "onProgressUpdate() called with: values = [" + values[0] + "]");
text.setText(""+values[0]);
}
//當背景任務執行完畢并 return 傳回是會被調用,可以進行 UI 操作。
@Override
protected void onPostExecute(Boolean aBoolean) {
text.setText("end");
}
}
項目源碼下載下傳
Github