Android使用HttpClient发Post请求遇NetworkOnMainThreadException异常求助
解决Android中HttpClient Post请求触发的NetworkOnMainThreadException异常
这个问题我太熟了!你遇到的android.os.NetworkOnMainThreadException本质上是Android系统的一种保护机制——从Android 3.0(API 11)开始,系统禁止在**主线程(UI线程)**里执行网络请求,因为网络操作通常耗时,会卡住UI导致应用无响应(ANR),所以系统直接抛出这个异常来阻止你这么做。
解决方案:用AsyncTask把网络请求放到后台线程
最直接的修复方式是使用Android官方提供的AsyncTask,它能帮你轻松把耗时的网络操作移到后台线程,同时在主线程处理返回结果。下面是针对你代码的修改版本:
// 在你的Activity/Fragment中定义这个异步任务子类 private class AuthPostTask extends AsyncTask<Void, Void, String> { // 此方法运行在后台线程,专门处理耗时操作 @Override protected String doInBackground(Void... voids) { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("http://recrutement.stb.com.tn:1010/PlateformeApi_Externe/api/Authorize/"); try { // 组装请求参数 List<NameValuePair> nameValuePairs = new ArrayList<>(5); nameValuePairs.add(new BasicNameValuePair("username", "sami")); nameValuePairs.add(new BasicNameValuePair("password", "stb")); nameValuePairs.add(new BasicNameValuePair("AuthMethod", "FormsAuthentication")); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); // 执行请求并获取响应 HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); if (entity != null) { return EntityUtils.toString(entity); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } // 此方法运行在主线程,处理请求结果(可更新UI) @Override protected void onPostExecute(String responseResult) { super.onPostExecute(responseResult); if (responseResult != null) { // 这里写成功后的逻辑,比如解析响应、更新UI Log.d("AuthSuccess", "响应内容:" + responseResult); } else { // 处理请求失败的情况,比如弹提示 Toast.makeText(getApplicationContext(), "认证请求失败,请检查网络", Toast.LENGTH_SHORT).show(); } } } // 调用异步任务的方式(比如在按钮点击事件里) new AuthPostTask().execute();
重要提醒
- 别忘了在
AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
DefaultHttpClient和HttpClient在Android API 22之后已经被标记为过时了,如果你是新项目或者打算重构,推荐使用更现代的网络库比如OkHttp,代码更简洁且性能更优。这里给你一个OkHttp版本的示例参考:
private class OkHttpAuthTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { OkHttpClient client = new OkHttpClient(); // 组装表单参数 FormBody formBody = new FormBody.Builder() .add("username", "sami") .add("password", "stb") .add("AuthMethod", "FormsAuthentication") .build(); Request request = new Request.Builder() .url("http://recrutement.stb.com.tn:1010/PlateformeApi_Externe/api/Authorize/") .post(formBody) .build(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { return response.body().string(); } } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String responseResult) { // 处理结果逻辑和之前一致 } }
内容的提问来源于stack exchange,提问作者Ouertani Saiid
相关产品推荐
相关产品推荐

