AsyncTask - 如何防止onPostExecute和onPreExecute在后续调用中相互干扰?

时间:2018-03-11 08:18:53

标签: android android-asynctask

我的AsyncTask有问题。 我使ProgressBar在onPreExecute中可见,在onPostExecute中不可见。这适用于连续1次调用或者如果我在最后一次完成之前等待。但是当我连续启动多个这些AsyncTasks时,最后一个的onPostExecute似乎被称为下一个onPreExecute,导致ProgressBar不可见。知道我能做什么吗?

private static class ExampleAsyncTask extends AsyncTask<Integer, Integer, String> {
    private WeakReference<MainActivity> activityReference;

    ExampleAsyncTask(MainActivity context) {
        activityReference = new WeakReference<>(context);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        MainActivity activity = activityReference.get();
        if (activity == null || activity.isFinishing()) {
            return;
        }

        activity.progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected String doInBackground(Integer... integers) {
        Log.i("TAG", "doInBackground started");
        for (int i = 1; i < integers[0]; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            publishProgress((i * 100) / integers[0]);
        }

        return "Finished";
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

        MainActivity activity = activityReference.get();
        if (activity == null || activity.isFinishing()) {
            return;
        }

        activity.progressBar.setProgress(values[0]);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        MainActivity activity = activityReference.get();
        if (activity == null || activity.isFinishing()) {
            return;
        }

        activity.progressBar.setProgress(0);
        activity.progressBar.setVisibility(View.INVISIBLE);
        Toast.makeText(activity, s, Toast.LENGTH_SHORT).show();
    }
}

2 个答案:

答案 0 :(得分:0)

我有一个非常简单的解决方案。只需使用计数器。在开始时保持你的计数器0.

<强>释

当您使进度条可见时,每次将计数器递增1.在onPostExecute方法中,只需将计数器递减1并检查计数器。如果它为0然后使您的进度条不可见。

解决方案代码:       int counter = 0; //在类

中定义的字段
  @Override
    protected void onPreExecute() {
            super.onPreExecute();

            MainActivity activity = activityReference.get();
            if (activity == null || activity.isFinishing()) {
                return;
            }
            counter = counter + 1;
            activity.progressBar.setVisibility(View.VISIBLE);
        }
        ....
        ....
        ....
@Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        counter--;
        if(counter == 0)//there is no active background tasks
        {
        activity.progressBar.setVisibility(View.INVISIBLE);
        ....// do what you want 
        }
    }

答案 1 :(得分:0)

除非您想使用progressBar显示所有任务的进度,否则如果您并行运行它们,则对所有任务都有一个进度条是没有意义的。根据每个任务完成的时间,他们将不断更改进度条。要么为您的任务分别设置进度条,要么系列地运行您的任务。您可以使用以下命令运行asyncTasks:

asyncTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);

注意:使用它的最低API级别为11