在 onCreate 中直接執行 HttpURLConnection 獲取 JSON,Android 4.0+ 拋出 NetworkOnMainThreadException (調試斷在 getResponseCode())。
Android 3.0+ (Honeycomb) **嚴禁主線程執行網絡 I/O**,防止 ANR。
private class FetchJsonTask extends AsyncTask {
@Override
protected List<Map<String,String>> doInBackground(String... urls) {
// 此處執行網絡請求、解析 JSON,返回結果
return getJSONObject(urls[0]);
}
@Override
protected void onPostExecute(List<Map<String,String>> result) {
// UI 線程更新界面
adapter.setData(result);
}
}
// 調用
new FetchJsonTask().execute("https://m.lalas.cn/help/all_1.html?format=json&size=5");
// build.gradle: implementation "org.jetbrains.kotlinx:kotlin-coroutines-android:1.6.+"
lifecycleScope.launch(Dispatchers.IO) {
val result = getJSONObject(url) // 懸掛函數或 runBlocking
withContext(Dispatchers.Main) {
adapter.submitList(result)
}
}
// Retrofit 定義接口
interface ApiService {
@GET("help/all_1.html")
fun getHelp(@Query("format") String format, @Query("size") Int size): Observable
}
// 使用
apiService.getHelp("json", 5)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ result -> /* 更新 UI */ }, { err -> /* 錯誤處理 */ })
doInBackground / Dispatchers.IO / subscribeOn(Schedulers.io()))。onPostExecute / withContext(Main) / observeOn(Main))。<uses-permission android:name="android.permission.INTERNET"/> 已添加。**主線程不能做網絡請求**,使用 AsyncTask/協程/RxJava 將耗時操作移至後台線程,結果回主線程更新 UI。