2015-01-10 62 views
2

這是我的應用程序的流程:顯示ProgressDialog直到的AsyncTask完成,然後更新UI

1)用戶需要的圖片或視頻

2)將培養基保存在內部存儲器

3)的路徑被分配給該UI被更新,以指示用戶可以繼續

的UI更新只有如果C的自定義對象

4) ustom對象具有圖像路徑或視頻路徑。我剛開始使用AsyncTask在後臺線程中保存到內部存儲器,這樣在保存大文件時應用程序不會掛起,但我遇到了一些問題。

我想要做的:顯示ProgressDialog直到doInBackground()完成,那麼路徑分配給我的對象,然後繼續主線程上更新UI。

現在,主線程將繼續運行,而AsyncTask仍在工作,並且UI將不會正確更新,因爲路徑尚未分配給對象。

我已閱讀約AsyncTask#get(),但我不確定如何使用ProgressDialog來實現它。我嘗試了,主線程在繼續之前似乎沒有等待結果。

我非常感謝任何幫助。謝謝!

AsyncTask

private class SaveMediaTask extends AsyncTask<Integer, Void, String> 
{ 
    private ProgressDialog progressDialog; 
    private int mediaType; 

    public SaveMediaTask() 
    { 
     progressDialog = new ProgressDialog(getActivity(), ProgressDialog.THEME_HOLO_LIGHT); 
     progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
     this.progressDialog.setTitle("Processing"); 
    } 

    @Override 
    protected void onPreExecute() 
    { 
     super.onPreExecute(); 
     this.progressDialog.show(); 
    } 

    protected String doInBackground(Integer... mediaType) 
    { 
     //save to internal storage and return the path 
     return path; 
    } 

    protected void onPostExecute(String path) 
    { 
     //by the time this runs, the UI has already tried to update itself on the main thread, 
     //and found that myObject does not yet have a path. Once this runs, it is too late. 
     myObject.setPath(path); 

     if (progressDialog.isShowing()) 
     { 
      progressDialog.dismiss(); 
     } 
    } 
} 

我怎麼稱呼它,用戶離開照相機後立即:

new SaveMediaTask().execute(MEDIA_TYPE_IMAGE);

//WAIT HERE AND DISPLAY PROGRESSDIALOG UNTIL TASK IS DONE

//update UI

+0

你的任務,我不能真正得到你想要的東西,但這個答案吧[這裏]( http://stackoverflow.com/questions/27499292/cant-show-alertdialog-in-doinbackground/27500068#27500068)會告訴你如何構建你的asynctask,同時注意你的代碼需求,我不認爲你需要檢查直接從主線程的路徑,我在想asynctask有辦法可以到達用戶界面,所以用它來檢查你的對象路徑,如果它真正的調用postexecute並做你的東西,希望它有幫助 – Elltz

回答

2

主線程似乎沒有等待 繼續之前的結果。

主線程不會等待。這不是AsyncTask的工作方式。 AsyncTask與您的主線程一起在後臺運行。

然後繼續在主線程上更新UI。

你並不需要繼續在主線程中更新UI一旦AsyncTask任務完成後,你可以簡單地執行該doInBackground任務onPostExecute()駁回progressDialog,即progressDialog.dismiss();因爲onPostExecute運行在後UI線程。

此外,好辦法是開始progressDialogonPreExecute()方法和關閉它在onPostExecute沒有檢查是否progessDialog仍呈現與否,因爲如果doInBackground()方法結束做它的工作onPostExecute()將只運行。

我想要做的:顯示ProgressDialog直到doInBackground() 完成,那麼路徑分配給我的對象,然後繼續 主線程上更新UI。

  • 開始ProgressDialog在onPreExecute
  • 指定的路徑,你的對象doInBackground
  • onPostExecute辭退ProgressDialog,
  • 繼續onPostExecute你的主線程的工作,因爲它在UI線程中運行。

您還可以通過調用publishProgress()更新您的UI線程,而doInBackground仍在運行。每次調用此方法都將觸發UI線程上的執行onProgressUpdate()

提示:它是一個好主意,駁回progressDialogonCancelled()方法的情況下,駁回它onPostExecute()旁邊,如果你曾經取消內部doInBackground

3

呦ur onPostExecute應該通知你的活動,它可以繼續。所以基本上:

// Start the task from your activity 
new SaveMediaTask().execute(MEDIA_TYPE_IMAGE); 

// Method that will be called when task is completed 
public void taskComplete() { 
    // update UI 
} 

...

protected void onPostExecute(String path) { 
    myObject.setPath(path); 

    if (progressDialog.isShowing()) { 
     progressDialog.dismiss(); 
    } 

    ((YourActivity)getActivity()).taskComplete(); 
} 
+0

這意味着我需要實例化我的A如果異步任務是在一些不同的自定義類,因爲我不會有getActivity()那裏做類似'((YourActivity)getActivity())。taskComplete();' 或者有更好的方法嗎? – eRaisedToX

+0

@eRaisedToX'AsyncTask'需要知道'Activity'會顯示'ProgressDialog',所以你需要某種引用。你如何做就是讓你決定。 – Simas

+0

耶!謝謝 ! – eRaisedToX

2

您可以將您的代碼打上//update UIonPostExecute方法結束。 onPostExecute總是在UI線程上調用,並且是更新UI以反映AsyncTask工作結果的好地方。

相關問題