在AsyncTask内部出现android.os.NetworkOnMainThreadException异常

5

我正在构建一个应用程序,但在AsyncTask中出现了NetworkOnMainThreadException异常。

调用:

new POST(this).execute("");

异步任务:

public class POST extends AsyncTask<String, Integer, HttpResponse>{
private MainActivity form;
public POST(MainActivity form){
    this.form = form;
}


@Override
protected HttpResponse doInBackground(String... params) {
try {
        HttpPost httppost = new HttpPost("http://diarwe.com:8080/account/login");
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
    nameValuePairs.add(new BasicNameValuePair("email",((EditText)form.findViewById(R.id.in_email)).getText().toString()));
    //add more...
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    return new DefaultHttpClient().execute(httppost);
} catch (Exception e) {
    Log.e("BackgroundError", e.toString());
}
return null;
}

@Override
protected void onPostExecute(HttpResponse result) {
super.onPostExecute(result);
try {
    Gson gSon = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create();
    gSon.fromJson(IOUtils.toString(result.getEntity().getContent()), LogonInfo.class).fill(form);
} catch (Exception e) {
    Log.e("BackgroundError", e.toString());
}
}
}

日志记录器:

BackgroundError | android.os.NetworkOnMainThreadException

我很困惑为什么在AsyncTask的doInBackground中会抛出这个异常,你有什么想法吗?
3个回答

7

JSON 代码移动到 doInBackground() 中:

@Override
protected HttpResponse doInBackground(String... params) {
    ...
    Your current HttpPost code...
    ...
    Gson gSon = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create();
    gSon.fromJson(IOUtils.toString(result.getEntity().getContent()), LogonInfo.class).fill(form);
    ...
}

1
AsyncTask 中的所有内容都在主 UI 线程上,除了 doInBackground()。一般的想法是支持以下常见用例:在 onPreExecute() 中设置您的 ProgressBar,在 onProgressUpdate() 中更新您的 ProgressBar,最后在 onPostExecute() 中关闭您的 ProgressBar。所有这些函数都是 UI 线程安全的,而 doInBackground() 可以安全地花费尽可能多的时间。 - David Manpearl

2

result.getEntity().getContent() 打开了一个从网络读取的流,所以网络通信在主线程中。将 JSON 解析移到 doInBackground() 中,只在 onPostExecute() 中执行 UI 任务。


非常感谢!仅供参考,onPostExecute 运行在主线程上吗? - Joseph Dailey
这是正确的。onPreExecute()也是。您需要了解的所有内容都可以在此处找到:http://developer.android.com/reference/android/os/AsyncTask.html - SimonSays

0

我认为问题出在你将 MainActivity 继承到你的 AsyncTask 中,尝试删除这部分代码:

private MainActivity form;
public POST(MainActivity form){
    this.form = form;
}

既然你不需要它,如果你想向AsyncTask传递任何参数,可以立即通过doInBackground()方法传递。

另外,要调用你的AsyncTask,请使用以下代码:new POST().execute();

此外,在onPostExecute()方法中,您不需要调用super.onPostExecute(result);

希望这能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接