天天看點

【第一行代碼】AndroidThreadTest

簡介

建立子線程,使用 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

繼續閱讀