gpt4 book ai didi

java - AsyncTask 取消后正在发布进度

转载 作者:行者123 更新时间:2023-12-01 11:30:57 25 4
gpt4 key购买 nike

我的情况是可以下载发票的RecyclerView。他们有一个启动下载的操作,并在下载按钮本身周围的圆形进度 View 中显示进度。我使用 AsyncTask 下载 PDF 格式的特定发票,并使用自定义监听器,以便我知道何时在 AsyncTask 本身之外取消、执行和更新进度(以避免在 AsyncTask 内部传递 View 并更新它)。

这是到目前为止我的 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
}

}

还有我的听众:

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);
}

});

这就是我按下取消按钮时所调用的内容:

progressView.setProgress(0);
if (tasks[0] != null)
tasks[0].cancel(true);

最后是我的问题:我发现当我取消下载时,大多数时候是在 50% 之后,在 progressView.setProgress(0) 之后最后一次调用 onProgressUpdated(progress) ,所以下载被取消,但进度条停留在最后一个进度而不是 0(当您设置新进度时,它会以一种非常酷的方式自行动画)。

我尝试以各种方式解决这个问题,比如在 AsyncTask 上设置一个 boolean 值来了解它是否被取消,一个将其设置为 true 的方法,以及在 onProgressUpdated(progress) 中检查它在调用监听器的 onProgressUpdated(progress) 之前调用 AsyncTask 来设置 View 上的进度;我找不到解决方案。

最佳答案

onProgressUpdated()progressView.setProgress(0); 都在 UI 线程上运行,因此您可以使用它们添加 boolean 检查。

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


    公共(public)无效onProgressUpdated(int进度){
    ProgressView.setProgress(进度);
    }

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

关于java - AsyncTask 取消后正在发布进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30391509/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com