使用AsyncTask仍触发android.os.NetworkOnMainThreadException问题求助
解决android.os.NetworkOnMainThreadException异常(使用AsyncTask仍出现问题)
核心错误
你直接调用了AsyncTask的doInBackground()方法,这个方法会在**当前调用它的线程(也就是主线程)**里执行,完全没有触发AsyncTask的异步线程机制,导致网络请求还是跑在了主线程上,从而抛出异常。
正确的做法是调用AsyncTask的execute()方法,它会由Android系统自动调度,在后台线程执行doInBackground(),同时负责线程切换的逻辑。
修正后的代码示例
1. 修正触发AsyncTask的方法
@RequiresApi(api = Build.VERSION_CODES.CUPCAKE) public void TEST() { new TESTROOT().execute(); // 改用execute(),而非直接调用doInBackground() }
2. 完善AsyncTask类的逻辑(修复空指针、优化UI操作)
@SuppressLint("StaticFieldLeak") @RequiresApi(api = Build.VERSION_CODES.CUPCAKE) public class TESTROOT extends AsyncTask<Void, Void, Boolean> { private Exception mRequestException; // 存储请求过程中的异常,用于UI线程展示 @Override protected Boolean doInBackground(Void... voids) { HttpURLConnection connection = null; try { URL url = new URL("http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8"); connection.setRequestProperty("SOAPAction", "http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso/ListOfContinentsByName"); connection.setDoOutput(true); // 写入SOAP请求XML内容(你原代码缺失这部分逻辑) String soapRequest = "<your完整的SOAP请求XML内容>"; OutputStream os = connection.getOutputStream(); os.write(soapRequest.getBytes(StandardCharsets.UTF_8)); os.flush(); os.close(); // 后续可添加读取响应流的逻辑 // ... return true; } catch (Exception e) { mRequestException = e; return false; } finally { // 确保连接关闭,避免资源泄漏 if (connection != null) { connection.disconnect(); } } } @Override protected void onPostExecute(Boolean isSuccess) { super.onPostExecute(isSuccess); // AsyncTask的onPostExecute方法自动在主线程执行,无需手动调用runOnUiThread if (mRequestException != null) { Toast.makeText(getApplicationContext(), "请求出错:" + mRequestException.getMessage(), Toast.LENGTH_LONG).show(); } else if (isSuccess) { Toast.makeText(getApplicationContext(), "请求完成", Toast.LENGTH_SHORT).show(); } } }
额外注意事项
- 不要手动调用AsyncTask的生命周期方法(如
doInBackground()、onPostExecute()),这些方法由系统自动调度 - 网络操作必须添加权限,在
AndroidManifest.xml中声明:<uses-permission android:name="android.permission.INTERNET" /> - AsyncTask已在Android 11及以上版本被标记为Deprecated,长期来看建议改用
Coroutines、ExecutorService等现代异步方案
内容的提问来源于stack exchange,提问作者andrea
相关产品推荐
相关产品推荐

