如果 Async Task 被取消,则重新显示进度对话框

Reshow a progress dialog from Async Task if it gets dismissed

我有一个进度对话框,显示我的异步任务中还有多少文件要上传,用户可以根据需要关闭此对话框。但是我想要一个按钮,它能够在当前阶段再次显示进度对话框,但我不知道该怎么做,因为我不能只在异步任务中创建一个函数并从不同 activity。有什么想法吗?

您可以创建一个单例 class 来处理仅包含一个侦听器的异步任务进度(Activity 想要侦听您的 AsyncTask 的进度)。 你的单例 class 可以像下面这样:

public class ProgressDialogUtil {

    public interface ProgressDialogUtilListener{
        void showProgressDialog();
        void dismissProgressDialog();
        void updateProgressDialog(int value);
        void setProgressDialogMessage(String message);
    }

    private ProgressDialogUtilListener listener;
    private static ProgressDialogUtil mInstance;
    public static ProgressDialogUtil getInstance() {
        if (mInstance == null) {
            synchronized (ProgressDialogUtil.class) {
                if (mInstance == null) {
                    mInstance = new ProgressDialogUtil();
                }
            }
        }
        return mInstance;
    }

    public void setListener(ProgressDialogUtilListener listener) {
        this.listener = listener;
    }

    public void showProgressDialog(){
        if(listener!=null)
            listener.showProgressDialog();
    }

    public void dismissProgressDialog(){
        if(listener!=null)
            listener.dismissProgressDialog();
    }

    public void updateProgressDialog(int value){
        setProgressDialogMessage("Files Downloaded: "+ value);
        if(listener!=null)
            listener.updateProgressDialog(value);
    }

    public void setProgressDialogMessage(String message){
        if(listener!=null)
            listener.setProgressDialogMessage(message);
    }
}

然后您可以在您的 AsyncTask 中使用此单例 class (ProgressDialogUtil),如下所示,以通知发生的任何更新:

public class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {

    public final ProgressDialogUtil progressDialogUtil;

    public MyAsyncTask(ProgressDialogUtil progressDialogUtil){
       this.progressDialogUtil = progressDialogUtil;
    }

    @MainThread
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialogUtil.setProgressDialogMessage("Start Download files..");
        progressDialogUtil.showProgressDialog();
    }

    @WorkerThread
    @Override
    protected Boolean doInBackground(Void... params) {
        //download your files here in the Background Thread...
        //below is a sample loop
        for (int i=0; i <= 50; i++) {
            try {
                Thread.sleep(1000);
                publishProgress(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    @MainThread
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        progressDialogUtil.updateProgressDialog(values[0]);
    }

    @MainThread
    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        progressDialogUtil.setProgressDialogMessage("Finished Download!");
        progressDialogUtil.dismissProgressDialog();
    }
}

然后在您启动 AsyncTask 的第一个 Activity 中,您可以创建进度对话框的新实例并设置侦听器 ProgressDialogUtilListener 以侦听任何 AsyncTask 进度show/hide/update 如下所示的进度对话框:

ProgressDialog pd = new ProgressDialog(this);
ProgressDialogUtil progressDialogUtil = ProgressDialogUtil.getInstance();
progressDialogUtil.setListener(new ProgressDialogUtil.ProgressDialogUtilListener()
{
    @Override
    public void showProgressDialog() {
       if (!pd.isShowing())
          pd.show();
    }
    @Override
    public void dismissProgressDialog() {
        if (pd.isShowing())
            pd.dismiss();
    }
    @Override
    public void updateProgressDialog(int value) {
       pd.setProgress(value);
    }
    @Override
    public void setProgressDialogMessage(String message) {
       pd.setMessage(message);
    }
});
new MyAsyncTask(progressDialogUtil).execute();

最后,当您导航到新的 Activity 时,您可以使用相同的单例实例 ProgressDialogUtil 并将侦听器更改为新的 Activity 现在所有 AsyncTask事件将被处理到新的 Activity 并且对话框可以通过这个单例 class 的按钮 opened/closed 如下所示:

ProgressDialog pd = new ProgressDialog(this);
ProgressDialogUtil progressDialogUtil = ProgressDialogUtil.getInstance();
progressDialogUtil.setListener(new ProgressDialogUtil.ProgressDialogUtilListener()
{
   @Override
   public void showProgressDialog() {
       if (!pd.isShowing())
           pd.show();
   }
   @Override
   public void dismissProgressDialog() {
       if (pd.isShowing())
           pd.dismiss();
   }
   @Override
   public void updateProgressDialog(int value) {
          pd.setProgress(value);
   }
   @Override
   public void setProgressDialogMessage(String message) {
         pd.setMessage(message);
   }
 });

 //Show Progress Dialog from a Button Click
 showButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        progressDialogUtil.showProgressDialog();
    }
});

//Dismiss Progress Dialog from a Button Click
dismissButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       progressDialogUtil.dismissProgressDialog();
    }
});

您可以像下面这样在任何单例中拥有实时数据 class 以共享活动之间的进度。

object ProgressHelper {
val progress = MutableLiveData<Int>()
}

然后像下面这样从 AsyncTask 更新进度值:

  override fun onProgressUpdate(vararg values: Int?) {
      super.onProgressUpdate(*values)
       ProgressHelper.progress.value = 100
  }
 

在您的 activity 中,您可以观察到如下进度:

  ProgressHelper.progress.observe(this, Observer { 
     val progress = it
 })