2015-01-10 63 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工作结果的好地方。

相关问题