2013-03-01 31 views
0

我一直在尋找如何在一段時間內實現Android的AsyncTask類。基本上,我希望它能夠實現經典的場景:在我進行網絡通話時簡單地創建一個無限期的裝載輪。但是,在實踐中,我遇到了一些問題,使其按我想要的方式工作。Android的AsyncTask:多個參數,返回值,等待

我的代碼看起來像這樣目前:(我期望的AsyncTask實施前)

String result = timeConsumingNetworkCall(String someData, ArrayList stuff1); 
doStuff(result); 

String result = timeConsumingNetworkCall(String otherData, ArrayList stuff2); 
doOtherStuff(result); 

String result = timeConsumingNetworkCall(String dataAgain, ArrayList stuff3); 
doYetEvenMore(result); 

我希望能夠重用我的AsyncTask通話將數據傳遞給它,它使網絡通話,然後返回我可以隨意處理的數據,就像我上面所做的那樣。

現在 - 這個工程是完美的,當然應用程序似乎沒有加載「掛起」。在來的AsyncTask。也許我還沒有完全「得到它」 - 但是如何將數據返回到AsyncTask的外部,以便doStuffToUI()等可以使用它?

最後,我想,如果我可以使用的AsyncTask與此類似:

String result = new PostToFile("function_name", keysAndValues).execute().getResult(); 
doStuff(result); // this shouldn't execute until the AsyncTask is done 

我要對這個權利?這是應該/可以完成的嗎?下面是我的AsyncTask類,縮寫爲簡潔。

private class PostToFile extends AsyncTask<PostToFile, Void, Void>{ 
    private String functionName; 
    private ArrayList<NameValuePair> postKeyValuePairs; 
    private String result = ""; 

    public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){ 
     functionName= function; 
     postKeyValuePairs = keyValuePairs; 
    } 

    @Override 
    protected void onPreExecute() { 
     progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false); 
    } 

    @Override 
    protected Void doInBackground(PostToFile... params) {      
     ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 
     nameValuePairs.add(new BasicNameValuePair(FUNCTION_KEYWORD, functionName)); 
     for (int i = 0; i < postKeyValuePairs.size(); i++)   { 
      nameValuePairs.add(postKeyValuePairs.get(i)); 
     } 

     try{ 
      // ***do the POST magic.*** 
      result = response.toString(); 
     } 
     catch (Exception e){ 
      // clean up my mess 
     } 

     return null; 
    } 

    private String getResult(){ 
     return result; // can I use this somehow??? 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     progressDialog.dismiss(); 
    } 
} 

任何幫助表示讚賞,多謝提前。如果需要,我很樂意澄清。

+0

你可以寫doStuff(result);在onPostExtecute()方法 – 2013-03-01 09:11:55

+0

嗯,我真的寧願不這樣做。因爲那樣我就必須在每次想要PostToFile時都有多個AsyncTask對象,這只是基於我如何接收數據。這聽起來很混亂,代碼太多。我只是想把數據放進去,然後解析它。 – 2013-03-01 09:20:46

+0

@ unexpected62我有同樣的問題,如果你已經解決了這個問題,請幫助我如何實現這個 – CoronaPintu 2013-05-27 05:47:46

回答

1

doStuff(result);這不應該執行,直到的AsyncTask完成

,那麼你將需要使用AsyncTask.get()如果有必要,這使得等待計算完成,然後獲取其結果。

因爲調用AsyncTask.get()凍結主UI線程,直到doInBackground執行沒有完成,那麼您將需要使用線程來避免凍結UI,runOnUiThread用於在AsyncTask執行完成後更新UI元素。

例子: -

public void ThreaddoStuff(){ 

Thread th=new Thread(){ 
    @Override 
    public void run(){ 
     // start AsyncTask exection here 
     String result = new PostToFile("function_name", 
         keysAndValues).execute().get().getResult(); 

    // now call doStuff by passing result 
    doStuff(result); 
    } 
    }; 
th.start(); 
} 
+0

我害怕這個......有一個更好的辦法......你告訴我,當我做'新AsynTaskObject(params).execute()'會開始,然後在完成之前立即執行下一行?我想要做的就是製作該死的裝載輪,而不是繼續運行我的程序!我不能繼續,除非我有用於填充下一個屏幕的UI的數據!必須有一些基本的東西我失蹤/不理解。 – 2013-03-01 09:57:46

+0

'你告訴我,當我做新的AsynTaskObject(params).execute()時,它會啓動,然後在完成上一行之前立即執行下一行?' - 是的,如果你有這種AsynTask行爲在不調用get()方法的情況下調用它,在這種情況下,您需要在onPostExecute方法內調用doStuff(result);因爲在doInBackground執行完成時調用此方法。 '我所要做的就是動畫這個該死的加載輪':: ---爲此,您將需要使用runOnUiThread更新線程 – 2013-03-01 10:08:35

1

請使用默認onPostExecute實現可重複使用的異步任務,然後覆蓋默認實現爲每個電話:

public static class PostToFile extends AsyncTask<Void, Void, String> { 
     private String functionName; 
     private ArrayList<NameValuePair> postKeyValuePairs; 
     private String result = ""; 

     public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){ 
      functionName= function; 
      postKeyValuePairs = keyValuePairs; 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      // show progress bar 
     } 

     @Override 
     protected String doInBackground(Void... arg0) { 
      // make request and get the result 
      return null; // return result 
     } 

     @Override 
     protected void onCancelled(String result) { 
      super.onCancelled(result); 
      // hide progress bar 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      super.onPostExecute(result); 
      // hide progress bar 
     } 
    } 

執行你的異步任務:

new PostToFile(function, keyValuePairs) { 

     @Override 
     protected void onPostExecute(String result) { 
      super.onPostExecute(result); // this will hide a progress bar 

      doStuff(result); 
     } 
}.execute(); 

new PostToFile(otherFunction, otherKeyValuePairs) { 

     @Override 
     protected void onPostExecute(String result) { 
      super.onPostExecute(result); // this will hide a progress bar 

      doOtherStuff(result); 
     } 
}.execute(); 
+0

的加載輪,我明白了,而且我確實已經開始實施了。然而,問題仍然是,當我執行新的'AsynTaskObject(params).execute()'時,會啓動,然後在'execute()'必須完成之前立即執行下一行。把所有東西放在'onPostExecute()'裏是不可行的,因爲它基本上是我程序的其餘部分,哈哈。在我處理完這些數據之前,我無法繼續前進,我只想在發生這種情況時展示一個裝載輪。也許AsyncTask實際上並不是我需要的?也許只是一個新的線程ProgressDialog? – 2013-03-01 17:57:32

+0

然後在一個doInBackground方法中完成所有工作(多個請求和結果解析)。或者將進度條移動到活動並在執行異步任務之前啓動它,並將其隱藏在最後一次異步任務的onPostExecute中(或者更好地說,當所有任務完成時) – vokilam 2013-03-01 20:08:40