[英]AsyncTask is publishing progress after cancelled
My situation is a RecyclerView of invoices that can be downloaded. 我的情况是可以下载发票的RecyclerView。 They have an action that starts the download and shows the progress in a circular progress view around the download button itself.
他们具有启动下载并在“下载”按钮本身周围的圆形进度视图中显示进度的操作。 I use an AsyncTask to download the particular invoice in PDF format, with a custom listener so I know when is cancelled, executed and progress updated outside the AsyncTask itself (to avoid passing the View and updating it inside the AsyncTask mostly).
我使用AsyncTask通过自定义侦听器下载PDF格式的特定发票,因此我知道何时在AsyncTask本身之外取消,执行和更新进度(以避免在AsyncTask内部通过View并对其进行更新)。
This is my AsyncTask so far: 到目前为止,这是我的AsyncTask:
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
}
}
And my listener: 而我的听众:
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);
}
});
This is what's called when I press the cancel button: 当我按下取消按钮时,这就是所谓的:
progressView.setProgress(0);
if (tasks[0] != null)
tasks[0].cancel(true);
And finally my problem: I found that when I cancel the download, mostly when it's after 50%, there is one last call to onProgressUpdated(progress)
AFTER the progressView.setProgress(0)
so the download is cancelled but the progress bar is stuck at the last progress instead of going to 0 (When you set a new progress, it animates itself in a very cool way). 最后是我的问题:我发现当取消下载时(主要是在下载50%之后
onProgressUpdated(progress)
在progressView.setProgress(0)
之后最后一次调用了onProgressUpdated(progress)
,因此取消了下载,但进度条卡住了最后的进度而不是0(设置新进度时,它会以非常酷的方式进行动画处理)。
I tried to workaround this in various ways, like having a boolean on the AsyncTask to know if it's canceled, a method that sets it to true, and a check of it in onProgressUpdated(progress)
of the AsyncTask before calling the onProgressUpdated(progress)
of the listener which sets the progress on the view; 我试图以各种方式来解决此,就像上的AsyncTask一个布尔值,知道它是否取消,它设置为true的方法,以及它在一个检查
onProgressUpdated(progress)
的的AsyncTask的调用之前onProgressUpdated(progress)
设置视图进度的侦听器; and I didn't be able to find a solution. 我无法找到解决方案。
the onProgressUpdated()
and progressView.setProgress(0);
onProgressUpdated()
和progressView.setProgress(0);
both run on UI thread, so you can add a boolean check with them. 两者都在UI线程上运行,因此您可以对其添加布尔检查。
boolean noMoreProgressUpdate = false
boolean noMoreProgressUpdate = false
noMoreProgressUpdate = true
after progressView.setProgress(0);
progressView.setProgress(0);
之后添加noMoreProgressUpdate = true
progressView.setProgress(0);
change 更改
public void onProgressUpdated(int progress) { progressView.setProgress(progress); }
to 至
`
public void onProgressUpdated(int progress) {
if(!noMoreProgressUpdate) {
progressView.setProgress(progress);
}
}
`
I'd use 我会用
onPreExecute() {
//do progress bar here
}
and then in onPostExecute()
然后在
onPostExecute()
onPostExecute(String result) {
//dismiss progress bar before anything else
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.