2013-09-30 137 views
0

我想從當前完成的AsyncTaskonPostExecute調用新的AsyncTask從onPostExecute方法調用另一個AsyncTask

  protected void onPostExecute(Integer feed) { 
     dialog1.dismiss();   
     super.onPostExecute(feed); 
     new SendsequenceofRequest().execute(); 
    } 

但我收到以下異常:

 android.os.NetworkOnMainThreadException 

我logcat的輸出是:

09-30 16:08:19.517: W/System.err(3706): android.os.NetworkOnMainThreadException 
09-30 16:08:19.517: W/System.err(3706):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077) 
09-30 16:08:19.517: W/System.err(3706):  at dalvik.system.BlockGuard$WrappedNetworkSystem.read(BlockGuard.java:279) 
09-30 16:08:19.517: W/System.err(3706):  at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:448) 
09-30 16:08:19.517: W/System.err(3706):  at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:75) 
09-30 16:08:19.517: W/System.err(3706):  at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103) 
09-30 16:08:19.517: W/System.err(3706):  at org.apache.http.impl.io.SocketInputBuffer.isStale(SocketInputBuffer.java:132) 
09-30 16:08:19.517: W/System.err(3706):  at org.apache.http.impl.AbstractHttpClientConnection.isStale(AbstractHttpClientConnection.java:205) 
09-30 16:08:19.517: W/System.err(3706):  at org.apache.http.impl.conn.AbstractClientConnAdapter.isStale(AbstractClientConnAdapter.java:185) 
09-30 16:08:19.577: W/System.err(3706):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:336) 
09-30 16:08:19.577: W/System.err(3706):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
09-30 16:08:19.577: W/System.err(3706):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
09-30 16:08:19.597: W/System.err(3706):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
09-30 16:08:19.597: W/System.err(3706):  at com.dm.ekot.reqres.SimpleHttpClient.sendresponseSequReqRes(SimpleHttpClient.java:715) 
09-30 16:08:19.607: W/System.err(3706):  at com.dm.ekot.MainScreen$SendsequenceofRequest$1$1.run(MainScreen.java:1020) 
09-30 16:08:19.620: W/System.err(3706):  at android.os.Handler.handleCallback(Handler.java:587) 
09-30 16:08:19.620: W/System.err(3706):  at android.os.Handler.dispatchMessage(Handler.java:92) 
09-30 16:08:19.620: W/System.err(3706):  at android.os.Looper.loop(Looper.java:132) 
09-30 16:08:19.620: W/System.err(3706):  at android.app.ActivityThread.main(ActivityThread.java:4025) 
09-30 16:08:19.627: W/System.err(3706):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-30 16:08:19.627: W/System.err(3706):  at java.lang.reflect.Method.invoke(Method.java:491) 
09-30 16:08:19.627: W/System.err(3706):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 
09-30 16:08:19.627: W/System.err(3706):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 
09-30 16:08:19.642: W/System.err(3706):  at dalvik.system.NativeStart.main(Native Method) 

在我SendsequenceofRequestAsyncTask我做doInBackground()方法啓動另一個線程。

  class SendsequenceofRequest extends AsyncTask<String, Void, Integer> { 

// private ProgressDialog dialog1; 

    protected void onPreExecute() { 
    // dialog1 = ProgressDialog.show(MainScreen.this, "", "Loading..."); 
    } 

    protected void onPostExecute(Integer feed) { 
    // dialog1.dismiss();   
     super.onPostExecute(feed); 
    }   

    @Override 
    protected Integer doInBackground(String... arg0) {  

        String str_stater_menu = "Starters"; 
        String response_starter = ""; 
       try { 

        new Thread(new Runnable() { 
         @Override 
         public void run() { 
          // TODO Auto-generated method stub 
          while (isThreadPaused1) { 
           try { 
            Thread.sleep(3000); 
            mHandler.post(new Runnable() {  

             @Override 
             public void run() { 
              // TODO Auto-generated method stub 
              try { 
               final String response_req_sequence = SimpleHttpClient.sendresponseSequReqRes(response_send_order); 
               System.out.println(" i ma in thread"); 
               if(response_req_sequence != null) 
    { 
                onPause(); 
     runOnUiThread(new Runnable() {  
       @Override 
       public void run() {  
        // TODO Auto-generated method stub 
        Toast.makeText(getApplicationContext(), "Your Order will be delivered in"+response_req_sequence, 10000).show(); 
       } 
      }); 
    } 
} catch (Exception e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
             } 
            }); 
           } catch (Exception e) { 
            // TODO: handle exception 
           } 
          } 
         } 
        }).start(); 
        //response_starter = SimpleHttpClient.sendFirstStarter(str_stater_menu); 
       } catch (Exception e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       }  
        System.out.println("i am getting response for starter"+response_starter); 
       // str_reponse_request_tableid_ip = SimpleHttpClient.sendIpTabletId(url , str_ip); 

       /** 
       *  
       */ 
       // res = response_starter.toString(); 
        System.out.println("response TEST: "+res); 
      // Object obj = response_starter.toString(); 
       System.out.println("after object creation "); 

       // getJsonStringForStarter(response_starter); 

       System.out.println("response :"+res);  

      /** Inside the new thread we cannot update the main thread 
      So updating the main thread outside the new thread */ 
      try { 

      }catch (Exception e) { 
     e.printStackTrace(); 
       // e.printStackTrace(); 
      } 
     return null; 
      }  


    } 

當我通過幾個鏈接,我找不到任何幫助作爲我的問題。所以請不要讓身體幫我把我帶出這個問題。在此先感謝所有人。

+1

爲什麼在AsyncTask中創建線程?他們的重點是,所以你不必管理你的線程。 – Geobits

+0

感謝您的回覆。我不得不連續發送請求到服務器,直到我沒有得到任何迴應。此請求將在第一次請求完成後執行。那爲什麼我在onPostExecute方法中使用它。如果您有其他解決方案或建議,請幫助我.. – DJhon

+2

您可以在'doInBackground'中執行此操作。只需在Thread.sleep(1000)中添加一個'while(true)'循環,一旦成功完成一個'break' – Tseng

回答

2

我會建議使用publishProgress發佈的最新進展,並覆蓋其主線程上執行onProgressUpdate。因此,您根本不必在AsyncTask中使用處理程序和線程。

請注意,第一行已從extends AsyncTask<String, Void, Integer>更改爲extends AsyncTask<String, String, Integer>。中間參數確定更新參數的對象類型。如果您需要將複雜數據發送到更新方法,請將其更改爲包含所有必需信息的類。

class SendsequenceofRequest extends AsyncTask<String, String, Integer> { 
    @Override 
    protected Integer doInBackground(String... arg0) {  
     try { 
      // This will run indefinitely, unless stopped by break. So make sure you have an exit condition, see below 
      String response_req_sequence = null; 
      do { 
       response_req_sequence = SimpleHttpClient.sendresponseSequReqRes(response_send_order); 
       if(response_req_sequence != null) { 
        // Instead of calling runOnUiThread, call progress update 
        publishProgress(response_req_sequence); 
       } 

       // Wait before retry 
       Thread.sleep(3000); 

      // Keep in mind, that if the connection is successful, the string may be empty, 
      // so TextUtils.isEmpty(response_req_sequence); may be better exit condition as it checks if string is null or has size of 0 
      } while(response_req_sequence!=null); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    void onProgressUpdate(String... string) { 
     // This will always be executed in main thread 
     onPause(); 
     Toast.makeText(getApplicationContext(), "Your Order will be delivered in"+response_req_sequence, 10000).show(); 
    } 

    protected void onPostExecute(Integer feed) { 
     // Notify user the task has bene completed 
     Toast.makeText(getApplicationContext(), "Task completed.", 10000).show(); 
    }   
} 
+0

謝謝....讓我檢查你的建議。 – DJhon

+0

我收到了您的建議,但我將如何再次發送請求,直到我沒有得到回覆。 – DJhon

+1

這是在'doInBackground'中完成的。 「while(true)」會一遍又一遍地被調用,直到你在裏面調用break。我不知道你的實際退出條件,這就是爲什麼我使用'if(somecondition == true)'作爲佔位符。如果'null'是你的退出條件,那麼你可以'if(response_req_sequence == null)break;'退出while循環 – Tseng

0

如果mHandler是從主/ UI線程創建的,那麼發佈到它的任何Runnable也將在主線程上運行。由於您正在嘗試在Runnable之內執行網絡I/O,因此該應用投擲了NetworkOnMainThreadException。通過

mHandler.post(Runnable runnable); 

+0

感謝您的快速響應..所以我應該如何解決我的問題。 – DJhon

+0

我建議從'doInBackground()'方法中刪除'Handler'和'Thread'代碼,因爲根據定義,您已經在後臺線程上運行了。請參閱Tseng的答案以獲得更全面的解決方案。 – acj

0

的Runnable開始主線程中執行,並且你要使用內部的可運行的網絡。

爲了避免這個問題簡單地創建新的線程,象這樣開始:

Thread t = new Thread(new Runnable { 
... 
}); 
t.start(); 
+0

我已經試過這個,但是,這對我來說也是同樣的例外。 – DJhon

+2

如果您要使用'AsyncTask',則無需使用線程。 「AsyncTask」是爲了方便工作而做的,並且不直接與處理程序和線程一起工作。看到我的回答在 – Tseng

+0

以下您是否嘗試在'doInBackground'內部使用網絡?爲什麼創建內部線程?你可以在'doInBackground'中使用由'while'封裝的'Thread.sleep(...)'。 – XeNoN

相關問題