應用啟動時 XMLParser 崩潰,錯誤堆疊指向 DefaultClientConnectionOperator.openConnection。這是典型的「在主執行緒執行網路操作」導致的 NetworkOnMainThreadException(Android 3.0+ 嚴格模式預設攔截)。
提供的 XMLParser.getXmlFromUrl() 方法在主執行緒同步呼叫 HttpClient.execute(),違反 Android 單執行緒模型規範。主執行緒負責 UI 繪製,不可阻塞等待網路 I/O。
不建議使用 StrictMode.ThreadPolicy.permitAll() 繞過檢查,這只是掩蓋問題,會導致 ANR。應採用以下任一現代寫法:
// ViewModel 或 Repository 中
suspend fun fetchXml(url: String): String = withContext(Dispatchers.IO) {
OkHttpClient().newCall(Request.Builder().url(url).build()).execute().use { it.body?.string() ?: "" }
}
private class FetchXmlTask : AsyncTask() {
override fun doInBackground(vararg urls: String): String {
return try {
val client = DefaultHttpClient()
val response = client.execute(HttpPost(urls[0]))
EntityUtils.toString(response.entity)
} catch (e: Exception) { "" }
}
override fun onPostExecute(xml: String) { /* 解析 XML 並更新 UI */ }
}
Thread {
val xml = getXmlFromUrl(url)
handler.post { parseAndUpdate(xml) }
}.start()
DefaultHttpClient,改用 OkHttp 或 HttpURLConnection。XmlPullParser 或 SimpleXml,效能優於 DOM。核心原則:耗時操作(網路、IO、複雜運算)必須離開主執行緒,才能構建流暢穩定的 Android 應用。