AsyncTask在取消后发布进度

时间:2015-05-22 08:08:50

标签: java android android-asynctask

我的情况是可以下载的发票的RecyclerView。他们有一个动作开始下载,并在下载按钮本身的循环进度视图中显示进度。我使用AsyncTask以PDF格式下载特定发票,并使用自定义侦听器,因此我知道何时取消,执行并在AsyncTask本身之外更新进度(以避免传递View并在AsyncTask中更新它)。

到目前为止,这是我的AsyncTask:

 var test ={  
         "APPLICATION_DETAIL":[
       {  
         "Application1":"",
         "Application2":"",
         "status":{  
            "Application1":"Active",
            "Application2":"Inactive"
         },
         "modifiedBy":"a123453"
      },
      {  
         "Application1":"",
         "Application2":"W",
         "status":{  
            "Application1":"Inactive",
            "Application2":"Inactive"
         },
         "modifiedBy":"a123456"
      }  
   ]
}
for(var i=0 ; i<test.APPLICATION_DETAIL.length ; i++){
  console.log(test.APPLICATION_DETAIL[i].status.Application1);
  console.log(test.APPLICATION_DETAIL[i].status.Application2);
}

我的听众:

public class DownloadTask extends AsyncTask<URL, Integer, String> implements Codes {

    private AsyncTaskProgressListener listener;
    private File file;


    public DownloadTask(AsyncTaskProgressListener listener) {
        this.listener = listener;
    }

    @Override
    protected String doInBackground(URL... urls) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = urls[0];
            file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + url.getFile());
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "Server returned HTTP " + connection.getResponseCode()
                        + " " + connection.getResponseMessage();
            }
            int fileLength = connection.getContentLength();
            LogUtil.log("" + fileLength);
            // download the file
            input = connection.getInputStream();
            output = new FileOutputStream(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), url.getFile()));

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            int lastProgress = 0;
            while ((count = input.read(data)) != -1) {
                if (isCancelled()) {
                    break;
                }
                total += count;
                // publishing the progress....
                int progress = 0;
                if (fileLength > 0) {
                    // only if total length is known
                    progress = (int) (total * 100 / fileLength);
                }
                //Prevent publishing the same progress various times as it would freeze the progress bar.
                if (progress > lastProgress) {
                    publishProgress(progress);
                    lastProgress = progress;
                }
                output.write(data, 0, count);
            }

        } catch (Exception e) {
            LogUtil.log(e.toString());
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (connection != null)
                connection.disconnect();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        listener.onProgressUpdated(values[0]);
    }

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

    @Override
    protected void onCancelled(String s) {
        listener.onCancel();
        file.delete();
        LogUtil.log("CANCELED");
        super.onCancelled(s);
        //noinspection ResultOfMethodCallIgnored
    }

}

当我按下取消按钮时,这就是所谓的:

tasks[0] = new DownloadTask(new AsyncTaskProgressListener() {
                                        @Override
                                        public void onCompleted() {
                                            state = INVOICE_DOWNLOADED;
                                        }

                                        @Override
                                        public void onCancel() {
                                            state = INVOICE_NOT_DOWNLOADED;
                                            progressView.resetAnimation();
                                        }

                                        @Override
                                        public void onProgressUpdated(int progress) {
                                            progressView.setProgress(progress);
                                        }

                                    });

最后我的问题: 我发现当我取消下载时,大部分时间是在50%之后,progressView.setProgress(0); if (tasks[0] != null) tasks[0].cancel(true); 之后最后一次调用onProgressUpdated(progress),因此下载被取消但进度条停留在最后一次进度转到0(当你设置一个新的进度时,它会以非常酷的方式激活自己。)

我试图以各种方式解决这个问题,例如在AsyncTask上有一个布尔值来知道它是否被取消,一个方法将它设置为true,并在调用之前在AsyncTask的progressView.setProgress(0)中检查它监听器的onProgressUpdated(progress),用于设置视图的进度;而且我无法找到解决方案。

2 个答案:

答案 0 :(得分:1)

onProgressUpdated()progressView.setProgress(0);都在UI线程上运行,因此您可以添加布尔检查。

  1. 添加布尔字段boolean noMoreProgressUpdate = false
  2. noMoreProgressUpdate = true
  3. 之后添加progressView.setProgress(0);
  4. 更改

    public void onProgressUpdated(int progress) { progressView.setProgress(progress); }

  5.  `
        public void onProgressUpdated(int progress) {
            if(!noMoreProgressUpdate) {
                progressView.setProgress(progress);
            }
        }
     `
    

答案 1 :(得分:0)

我使用

onPreExecute() {
  //do progress bar here
}

然后在onPostExecute()

onPostExecute(String result) {
   //dismiss progress bar before anything else
}