Android Studio切換主線程的兩種方式詳解
在 Android 中,UI 操作必須在主線程中進行,不能直接在子線程中更新 UI。今天介紹兩種在子線程切換回主線程的方法。
runOnUiThread() 和 Handler.post() 都可以用于切換到 主線程(UI 線程) 執(zhí)行任務(wù),主要用于 更新 UI。但它們在使用方式、作用范圍、底層實現(xiàn)上有所不同。
1. runOnUiThread()
runOnUiThread() 是 Activity 的一個方法,它可以讓任務(wù)在 主線程(UI 線程) 執(zhí)行。適用于 在 Activity 內(nèi)部 從子線程切換到主線程 以更新 UI。
用法:
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("更新 UI");
}
});
Lambda 寫法:
runOnUiThread(() -> textView.setText("更新 UI"));
底層原理:
runOnUiThread() 的實現(xiàn)本質(zhì)上 使用了 Handler.post(),它會獲取 Activity 綁定的 Looper,然后將任務(wù)投遞到 主線程消息隊列。
適用場景
- 只在
Activity里使用,不能在Service、BroadcastReceiver等組件中用。 - 簡單的 UI 更新,比如在
onCreate()、網(wǎng)絡(luò)請求回調(diào)、異步任務(wù)完成后 更新 TextView、Button 等 UI 組件。
完整的代碼:實現(xiàn)的效果很簡單,2秒后在主界面更新UI,顯示 "UI 更新成功!"
public class MainActivity extends AppCompatActivity {
private TextView textView;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main9);
textView = findViewById(R.id.textView);
// 在子線程中執(zhí)行耗時操作
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000); // 模擬網(wǎng)絡(luò)請求或其他耗時任務(wù)
} catch (InterruptedException e) {
e.printStackTrace();
}
// 切換到主線程更新 UI
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("UI 更新成功!");
}
});
}
}).start();
}
}2. Handler.post()
Handler.post() 通過 Handler 將任務(wù)投遞到指定的線程,一般用于 從子線程切換到主線程 處理 UI 更新,也可以用于子線程間通信。
Handler handler = new Handler(Looper.getMainLooper());
handler.post(() -> textView.setText("更新 UI"));
底層原理
Handler通過MessageQueue投遞任務(wù),Looper取出并執(zhí)行。- 不會判斷當前線程,即使
post()發(fā)生在主線程,它也會把任務(wù)加入消息隊列,可能稍微延遲執(zhí)行。
適用場景
- 適用于 所有 Android 組件(
Activity、Service、Fragment、BroadcastReceiver)。 - 可以執(zhí)行延遲任務(wù)(
postDelayed())。 - 可在子線程和子線程間通信,不僅限于 UI 更新。
完整代碼,實現(xiàn)的效果和上面runOnUiThread()是一樣的。2秒延遲后,主界面顯示"數(shù)據(jù)加載完成"
import android.os.Handler;
import android.os.Looper;
public class MainActivity extends AppCompatActivity {
private TextView textView;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main9);
textView = findViewById(R.id.textView);
Handler handler = new Handler(Looper.getMainLooper());
new Thread(() -> {
try {
Thread.sleep(2000); // 模擬網(wǎng)絡(luò)請求
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(() -> textView.setText("數(shù)據(jù)加載完成"));
}).start();
}
}
到此這篇關(guān)于Android Studio切換主線程的兩種方式詳解的文章就介紹到這了,更多相關(guān)Android Studio切換主線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android Map新用法:MapFragment應(yīng)用介紹
MapView ,MapActivity 這種的局限在于,必須要繼承MapActivity,否則無法使用MapView,但是,MapFragment 這種的局限在于,必須要安裝Google Play Service ,也就是說必須是原生rom。而且sdk要在12以上2013-01-01
Android IPC機制ACtivity綁定Service通信代碼實例
這篇文章主要介紹了Android IPC機制ACtivity綁定Service通信代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下2020-09-09
NestScrollView嵌套RecyclerView實現(xiàn)淘寶首頁滑動效果
這篇文章主要介紹了NestScrollView嵌套RecyclerView實現(xiàn)淘寶首頁滑動效果,主要實現(xiàn)淘寶首頁嵌套滑動,中間tab吸頂效果,以及介紹NestScrollView嵌套RecyclerView處理滑動沖突的方法,需要的朋友可以參考下2021-12-12
Android Gradle多渠道打包的實現(xiàn)方法
這篇文章主要介紹了Android Gradle多渠道打包的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2020-11-11
淺談Android Classloader動態(tài)加載分析
這篇文章主要介紹了淺談Android Classloader動態(tài)加載分析,詳細的介紹了ClassLoader概念、分類,具有一定的參考價值,有興趣的可以了解一下2018-03-03
Android實現(xiàn)倒計時結(jié)束后跳轉(zhuǎn)頁面功能
最近在工作中遇到一個需求,需要在倒計時一段時間后進行跳轉(zhuǎn)頁面,通過查找相關(guān)資料發(fā)現(xiàn)其中涉及的知識還不少,所以分享出來,下面這篇文章主要給大家介紹了關(guān)于Android實現(xiàn)倒計時結(jié)束后跳轉(zhuǎn)頁面功能的相關(guān)資料,需要的朋友可以參考下。2017-11-11

