首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 開發:解決耗時操作導致程式碼提前執行的問題

     編輯:程式設計綜合問答

問題背景

在 Android 開發中,經常會遇到網路請求、資料庫查詢或複雜運算等耗時操作。若直接在主執行緒呼叫這些方法,程式碼會繼續往下執行,而不等待結果返回,導致邏輯錯誤或應用程式無回應(ANR)。

典型錯誤示範

public void cc() {
    String aa = getHtml(); // 這是一個耗時操作(如網路請求)
    // 程式碼未等待 aa 返回值,直接執行後續邏輯
    // ...
}

解決方案:非同步處理

核心原則是不要阻塞主執行緒。推薦使用以下現代化方案:

1. 使用 Kotlin 協程(推薦)

// 在 ViewModel 或 Repository 中
suspend fun fetchHtml(): String = withContext(Dispatchers.IO) {
    getHtml() // 耗時操作放在 IO 執行緒
}

// 在 Activity/Fragment 中呼叫
lifecycleScope.launch {
    val html = fetchHtml()
    // 這裡會等待 fetchHtml 完成,再執行後續 UI 更新
    updateUI(html)
}

2. 使用 Java 執行緒池 + Handler

public void cc() {
    new Thread(() -> {
        String aa = getHtml(); // 子執行緒執行耗時操作
        runOnUiThread(() -> {
            if (aa != null) {
                // 回到主執行緒更新 UI 或執行後續邏輯
                handleResult(aa);
            }
        });
    }).start();
}

3. 使用 RxJava

Observable.fromCallable(this::getHtml)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(this::handleResult, this::handleError);

為什麼不建議用 `if (aa != null)` 同步等待?

原回答建議用 `if (aa != null)` 來「等待」,但這在主執行緒中無效——`getHtml()` 若是同步阻塞呼叫,主執行緒會卡死;若是非同步回調,`aa` 依然會是 null。正確做法是採用非同步回調、協程或 Reactive Streams 等機制。

最佳實踐總結

  • 嚴禁在主執行緒進行耗時操作(網路、IO、複雜運算)。
  • 優先使用 Kotlin 協程,程式碼簡潔、結構化、易維護。
  • Java 專案可用 ExecutorService + Handler 或 RxJava。
  • 務必處理生命週期,避免記憶體洩漏(如使用 `lifecycleScope` 或 `viewModelScope`)。

掌握非同步程式設計,是打造流暢、穩定 Android 應用的關鍵技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved