2012-12-03 54 views
2

我使用AsyncTask發送POST請求到webservice,但我不斷收到NetworkOnMainThreadException異常。我正在使用這個問題的答案解決方案: How to fix android.os.NetworkOnMainThreadException? 但我不能讓它工作。 我的課:NetworkOnMainThreadException當發送POST請求到webservice

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應該做的一切裏面有什麼,因爲這將是在另一個線程。

+2

出於好奇,爲什麼你不能在doInBackground中處理實體並返回JSONObject呢? – Blackbelt

回答

2

-它總是更好的做法是有UI work on UI-ThreadNon-UI work on Non-UI Thread,但是從蜂窩版本的Android成爲一個定律。

-在你的情況get()阻塞調用,你是從UI線程,在那裏,因爲它應該非UI線程調用

-EntityUtils.toString(resEntity)應在非UI線程,所以應該在doInBackground()方法。

2

正如你所說,你要在這行你的錯誤:

retSrc = EntityUtils.toString(resEntity); 

這是因爲EntityUtils.toString()也應在doInBackground()方法位於。

+1

另外,擺脫'get()',這將阻止主應用程序線程。 – CommonsWare

+0

是的,謝謝你完成我的答案CommonsWare。 –

1

get()是一個阻塞調用,您不能執行的UI線程阻塞調用

AsyncTask文檔如有必要,計算完成

等待,然後檢索 其結果。

1

從ICS及以上版本的Android將不允許在UI thread.It任何網絡操作應在單獨的線程來完成,這樣就不會掛UI.Try在單獨的線程網絡通信代碼。