2013-12-09 44 views
0

當前我正在爲我的項目做一些事情,其中​​創建了一個單獨的類,它只處理Asynctask並獲取我通過的Web服務的值,類應該以String的形式返回JSON響應。現在我已經使用taskName.execute().get();來實現它了,其中它將等待任務完成,但問題在於它還在顯示屏幕布局之前等待任務完成。讓我的progressDialog無用,並導致切換屏幕上的延遲。這裏是我的代碼現在:具有子類AsyncTask的Android類在返回值之前等待postExecute

對於類具有的AsyncTask:

public class UtilGetResponse { 

    Context context; 
    Map hash_values = new HashMap(); 
    int DialogType; 
    String response; 
    /* 
     PLAN FOR DialogTypes: 
    * 0 - Standard Please wait dialog 
    * 1 - Progress dialog 
    * 2 - Camera upload dialog 
    * */ 


    InputStream is = null; 
    StringBuilder string_builder = null; 


    public UtilGetResponse(Map values, Context baseContext, int type){ 
     /*initialize class and pass the hash values for parameters*/ 
     context = baseContext; 
     hash_values.putAll(values); 
     DialogType = type; 
    } 

    public String startTask(){ 
     //TODO CASE WHEN BASED ON THE DIALOG TYPE SPECIFIED 
     Utilities util = new Utilities(); 

     if(util.isOnline(context)){ 
      try { 
       new UploaderTaskStandard().execute().get(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       e.printStackTrace(); 
      } 
     } 
     return response; //THE RESPONSE ONLY SHOW ONCE THE WHOLE TASK IS COMPLETED 
    } 


    public class UploaderTaskStandard extends AsyncTask<Map, Void, Void> { 
     ProgressDialog simpleDialog; 

     @Override 
     protected void onPreExecute() { 
      /*Do something before the async task starts*/ 
      simpleDialog = new ProgressDialog(context); 
      simpleDialog.setMessage("Please wait"); 
      simpleDialog.show(); 
     } 

     @Override 
     protected Void doInBackground(Map... maps) { 
      uploadData(); 
      return null; 
     } 

     protected void onPostExecute(Void v) { 
      /*Do something after the task is complete*/ 
      simpleDialog.dismiss(); 
     } 
    } 

    private void uploadData() { 
     response = "null"; 
     String url = hash_values.get("url").toString().replace(" ", "%20"); //get the URL replacing the space with %20 

     //If the user is trying to upload a file use this part 
     try { 
      HttpClient client = new DefaultHttpClient(); 
      HttpPost post = new HttpPost(url); 
      MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); 

       /*This will convert the hashMap sent into individual part per key per value*/ 
      Set set = hash_values.entrySet(); 
      Iterator iterator = set.iterator(); 

       /*do a loop passing all the data on a string*/ 
      while(iterator.hasNext()) { 
       Map.Entry mapEntry = (Map.Entry)iterator.next(); 
       String keyword = String.valueOf(mapEntry.getKey()); 
       String value = String.valueOf(mapEntry.getValue()); 

        /*this will check if the passed data is a URL, file or a simple value*/ 
       if(!keyword.equals("url")){ 
        if(value.matches("(.*)/(.*)")){ 
         File file = new File(value); 
         Log.v("Does this exists?",String.valueOf(file.exists())); 
         if(file.exists()){ 
          FileBody upload_file; 
          upload_file = new FileBody(file); 
           /*not url but file*/ 
          mpEntity.addPart(keyword, upload_file); 
         }else{ 
           /*not url and not file*/ 
          mpEntity.addPart(keyword, new StringBody(value)); 
         } 
        }else{ 
          /*not URL and not file*/ 
         mpEntity.addPart(keyword, new StringBody(value)); 
        } 
       } 
      } 

      post.setEntity(mpEntity); 
      HttpResponse response = client.execute(post); 
      HttpEntity resEntity = response.getEntity(); 

      is = resEntity.getContent(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      response = "null"; 
     } 

     /*convert JSON to string*/ 
     try{ 
      BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8); 
      string_builder = new StringBuilder(); 
      String line = "0"; 

      while ((line = reader.readLine()) != null) { 
       string_builder.append(line + "\n"); 
      } 
      is.close(); 
      response = string_builder.toString(); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

    } 

} 

,並呼籲這一點:

Map hash_values = new HashMap(); 

     try{ 
      HashMap params = new HashMap<String,String>(); 
      params.put("param1", "YOUR_PARAM"); 
      params.put("url", "YOUR_WEBSERVICE_URL"); 

      //pass parameters 
      hash_values.putAll(params); 
      //start async task 

      UtilGetResponse util = new UtilGetResponse(hash_values, getActivity(), 0); 
      String result = util.startTask(); 

      Log.v("The result string",result); 

     }catch (Exception e){ 
      e.printStackTrace(); 
      e.getCause(); 
      Toast.makeText(getActivity(), "Oops problem", Toast.LENGTH_SHORT).show(); 
     } 

有沒有對我正確地做到這一點沒有真正等待的方式整個任務完成後才能轉到下一個屏幕?我正在考慮使用處理程序,但我還是不太熟悉如何使用它。雖然你使用AsynTask,但仍使系統等到的結果是對你的要求

回答

3

你的問題是與這個

new UploaderTaskStandard().execute().get(); 

使用,你需要的是一個傳遞機制,這會通知你回來一次結果已準備就緒。你可以採取兩種方法中的任何一種。

change to this, and implement one of below mechanism. 
new UploaderTaskStandard().execute(); 
  1. 實施處理程序,併發布結果回來一次導致可用。
  2. 實現觀察者設計模式,在該模式下,您使用onResultReady等方法創建接口,並將實現上述接口的類的對象傳遞給方法startTask,並通過接口機制將結果從AsyncTask onPostExecute發回。

通過接口去會很容易並以這種方式你的代碼將獨立於網絡的邏輯,示例代碼的下方

// Observer listener interface design 
interface ResultListener{ 
    // You can overload this method with data type you want to return 
    public void onResultReceived(); 

    // Use them in a proper way for sending error message back to your program 
    public void onTaskCancelled(); 
    public void onError(); 

} 
// This will be your new method signature 
public String startTask(ResultListener listener){ 
    // Call it liske this, passing listener reference 
    new UploaderTaskStandard().execute(listener); 
} 

// This is your AsyncTask model 
public class UploaderTaskStandard extends AsyncTask<ResultListener, Void, Void> { 

    ResultListener listener; 

     @Override 
     protected Void doInBackground(ResultListener... maps) { 
      this.listener = maps[0]; 
      uploadData(); 
      return null; 
     } 

     protected void onPostExecute(Void v) { 
      /*Do something after the task is complete*/ 
      simpleDialog.dismiss(); 
      // Notify back to calling program 
      listener.onResultReceived(); 
     } 

} 
+0

沒錯,投了:) –

+0

我有這個想法,但我不我真的不知道該如何實施它。我對第二種選擇更感興趣。有關如何實施它的鏈接將非常感激。 :) – KaHeL

+0

hasve剛剛發佈了一個樣品爲你工作,看看,讓我知道,如果你有任何疑問。 – Techfist

相關問題