同樣的 DefaultHttpClient 程式碼在 Android 2.2/2.3 正常,4.0 (ICS) 以上崩潰。原因是 Android 3.0+ 強制執行 StrictMode,攔截主執行緒網路 I/O,拋出 NetworkOnMainThreadException。
// 在 onCreate 直接執行網路請求
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://google.com");
HttpResponse response = httpclient.execute(httppost); // 主執行緒阻塞,ICS+ 崩潰
private class FetchTask extends AsyncTask {
@Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(MainActivity.this, "載入中", "請稍候...");
}
@Override
protected String doInBackground(String... urls) {
try {
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(new HttpPost(urls[0]));
return EntityUtils.toString(response.getEntity());
} catch (Exception e) { return "Error: " + e.getMessage(); }
}
@Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
textView.setText(result);
}
}
// 呼叫
new FetchTask().execute("https://google.com");
new Thread(() -> {
try {
String result = // ...網路請求...
runOnUiThread(() -> textView.setText(result));
} catch (Exception e) {
runOnUiThread(() -> textView.setText("Error: " + e.getMessage()));
}
}).start();
// build.gradle
implementation "com.squareup.okhttp3:okhttp:4.11.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
// ViewModel 或 Activity
lifecycleScope.launch(Dispatchers.IO) {
try {
val response = OkHttpClient().newCall(Request.Builder().url(url).build()).execute()
val result = response.body?.string() ?: ""
withContext(Dispatchers.Main) { textView.text = result }
} catch (e: Exception) {
withContext(Dispatchers.Main) { textView.text = "Error: ${e.message}" }
}
}
HttpURLConnection 或 OkHttp。res/xml/network_security_config.xml 允許或全站 HTTPS。任何網路、資料庫、檔案 I/O、複雜運算,絕不可在主執行緒同步執行。 這是 Android 流暢體驗的基石,也是從 2.x 遷移到 4.x+ 必須重構的核心架構調整。