2

我正在使用 AsyncTask 向 web 服务发送 POST 请求,但我不断收到NetworkOnMainThreadException异常。我正在使用来自这个问题的答案的解决方案: 如何修复 android.os.NetworkOnMainThreadException? 但我不能让它工作。我的课程:

public class MainActivity extends Activity {

    public JSONObject result;
    public String retSrc;
    public HttpEntity resEntity;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        try {
            resEntity = new UpdateData().execute().get();     
            retSrc = EntityUtils.toString(resEntity);         // Here I get an exception
            result = new JSONObject(retSrc);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    private class UpdateData extends AsyncTask<String, Void, HttpEntity>{

        private HttpEntity entit;
            @Override
            protected HttpEntity doInBackground(String... params) {
                try {
                    HttpClient client = new DefaultHttpClient();  
                    String postURL = "http://www.test.com";
                    HttpPost post = new HttpPost(postURL);
                        List<NameValuePair> crc = new ArrayList<NameValuePair>();
                        crc.add(new BasicNameValuePair("crc", "test"));
                        UrlEncodedFormEntity ent = new UrlEncodedFormEntity(crc,HTTP.UTF_8);
                        post.setEntity(ent);
                        HttpResponse responsePOST = client.execute(post);  
                        entit = responsePOST.getEntity();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return entit;
            }
    }
}

这是错误日志:

12-03 14:46:36.929: E/AndroidRuntime(3044): FATAL EXCEPTION: main
12-03 14:46:36.929: E/AndroidRuntime(3044): java.lang.RuntimeException: Unable to start activity ComponentInfo{app/app.MainActivity}: android.os.NetworkOnMainThreadException
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.os.Looper.loop(Looper.java:137)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.main(ActivityThread.java:4424)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.lang.reflect.Method.invokeNative(Native Method)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.lang.reflect.Method.invoke(Method.java:511)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at dalvik.system.NativeStart.main(Native Method)
12-03 14:46:36.929: E/AndroidRuntime(3044): Caused by: android.os.NetworkOnMainThreadException
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at libcore.io.IoBridge.recvfrom(IoBridge.java:503)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:161)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:175)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.exhaustInputStream(ChunkedInputStream.java:289)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.impl.io.ChunkedInputStream.close(ChunkedInputStream.java:262)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.conn.BasicManagedEntity.streamClosed(BasicManagedEntity.java:179)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:266)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:213)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at java.io.InputStreamReader.close(InputStreamReader.java:145)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:139)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at pl.lodz.uni.uniinformator.MainActivity.onCreate(MainActivity.java:43)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.Activity.performCreate(Activity.java:4465)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12-03 14:46:36.929: E/AndroidRuntime(3044):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
12-03 14:46:36.929: E/AndroidRuntime(3044):     ... 11 more

如果我理解正确,方法doInBackground应该做所有里面的事情,就像它在另一个线程中一样。

4

4 回答 4

2

正如您所说,您在这一行中遇到了错误:

retSrc = EntityUtils.toString(resEntity);

这是因为EntityUtils.toString()也应该位于doInBackground()方法中。

于 2012-12-03T13:21:16.043 回答
2

-UI work on UI-Thread拥有and总是更好的做法Non-UI work on Non-UI Thread,但从Android 的HoneyComb版本开始,它变成了法律。

-在你的情况下get()是一个阻塞调用,你是从 UI 线程调用的,它应该在非 UI 线程上。

- EntityUtils.toString(resEntity)应该在Non-UI thread中,所以应该在doInBackground()方法中。

于 2012-12-03T13:28:40.817 回答
1

get()是一个阻塞调用,你不能在UI线程上执行阻塞调用

来自AsyncTask文档

如有必要,等待计算完成,然后检索其结果。

于 2012-12-03T13:22:21.677 回答
1

从 ICS 及以上版本 Android 将不允许在 UI 线程中进行任何网络操作。它应该在单独的线程中完成,这样它就不会挂起 UI。在单独的线程中尝试您的网络通信代码。

于 2012-12-03T13:22:58.887 回答