剩下最後五天了加油!!
今天來介紹Thread,ok開始!
所有的UI操作,例如繪製畫面、回應按鈕點擊等,都在一個被稱為主執行緒(Main Thread)或UI執行緒(UI Thread)的單一執行緒上執行。如果在這個主執行緒上執行耗時的操作,如下載檔案、存取資料庫、複雜運算,就會導致 UI 被阻塞,畫面凍結,最終可能跳出應用程式無回應之類的錯誤
為了解決問題,我們使用Thread將這些耗時任務移到背景執行緒 (Background Thread) 中執行,讓主執行緒保持流暢,專心處理 UI 互動。
背景執行緒完成任務,要安全的將結果更新回UI介面上,可以透過Handler
或runOnUiThread()
等機制溝通
Activity 中,可以透過 new Thread().start()
來啟動一個新的執行緒
背景執行緒完成任務後,要將更新UI的程式碼傳遞回主執行緒來執行
runOnUiThread()
: 可以將一個Runnable
物件post到UI執行緒的事件佇列裡Handler
: 在主執行緒中建立一個 Handler
,它會自動與主執行緒的訊息迴圈綁定。任何執行緒都可以透過這個Handler
將訊息或 Runnable
物件傳遞回主執行緒執行這邊用點擊按鈕後,啟動一個背景執行緒模擬3秒的耗時工作,然後用 Handler
將結果更新回TextView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@+id/start_main_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開始耗時任務" />
<TextView
android:id="@+id/status_main_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="等待任務開始..."/>
</LinearLayout>
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView statusTextView;
private Button startButton;
//建立主執行緒Handler
private Handler mainHandler = new Handler(Looper.getMainLooper());
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
statusTextView = findViewById(R.id.status_main_tv);
startButton = findViewById(R.id.start_main_btn);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startBackgroundTask();
}
});
}
private void startBackgroundTask() {
//禁用按鈕,讓執行時不能重複點擊
startButton.setEnabled(false);
statusTextView.setText("任務執行中...");
//建立並啟動背景執行緒
new Thread(new Runnable() {
@Override
public void run() {
try {
//模擬耗時
Thread.sleep(3000);
//使用Handler將UI更新post回主執行緒
mainHandler.post(new Runnable() {
@Override
public void run() {
//更新UI並重新啟用按鈕
statusTextView.setText("任務完成!");
startButton.setEnabled(true);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
//發生異常時恢復按鈕狀態
mainHandler.post(new Runnable() {
@Override
public void run() {
statusTextView.setText("任務執行失敗");
startButton.setEnabled(true);
}
});
}
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除所有pending的callbacks
mainHandler.removeCallbacksAndMessages(null);
}
}
Thread就介紹到這裡,明天來介紹Toolbar,明天見(. v . )