听起来很傻吧? 我有一个带有物品卡的RecyclerView。这些卡具有一个按钮,该按钮在另一个RecyclerView中显示PopupWindow列出“附件”。这些附件卡有一个按钮,您可以在其中下载它们,并且应该在进度栏中显示下载进度。
现在,当执行并行asynctask下载时,我不知道刷新进度条的正确方法。
基本上,我有一个带有进度侦听器的asyncTask,用于更新AttachmentData对象(与附件卡关联的数据)中的进度字段。持有人应该阅读AttachmentData进度并更新进度栏...
...在回收者视图中该项目的弹出窗口中。
我的问题是,每当我在其他AsyncTask之上启动一个新的asyncTask时,最新的asyncTask就会拦截前一个的所有进度,而不是三个附件显示其各自的进度,而是有两个附件显示其冻结的进度(直到单击了第三个附件为止),第三个附件显示了三个附件的进度,每当其中一个附件更新其进度时都会刷新。
这很令人困惑。
问题是,我有理由怀疑它与RecyclerView无关,因为我发送的通知的行为完全像这样。
在ViewHolder中绑定数据时,一切都会发生
public <T extends DownloadableData> void bindData(T data, ItemProgressListener ipl) {
this.data = data;
this.ipl = ipl;
//....
button.setOnClickListener(v->openDoc());
//....
}
public void openDoc(){
data.pdfStatus = PDF_DOWNLOADING;
NotificationCompat.Builder builder = new NotificationCompat.Builder(parentFragment.getActivity(), CHANNEL_ID)
.setSmallIcon(R.drawable.logo_white)
.setContentTitle("Downloading " + data.title)
.setContentText("Current Progress: " + data.progress + " %")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Current Progress: " + data.progress + " %"))
.setAutoCancel(false);
int PROGRESS_MAX = 100;
builder.setProgress(PROGRESS_MAX, 0, false);
int notificationId = Integer.parseInt(data.uuid);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(notificationId, builder.build());
CloudManager.PaperDownloader pd = new CloudManager.PaperDownloader() {
@Override
public String getFilePath() {
return data.filepath;
}
@Override
public void progressUpdate(Integer... values) {
data.pdfStatus = PDF_DOWNLOADING;
data.setProgress(values[0]);
if ((values[0] % 5 == 1 || values[0] == 100) && data.previousProgress < data.progress) {
if (ipl != null)
ipl.onItemProgressChanged(position, data);
builder.setContentText("Current Progress: " + values[0] + " %")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Current Progress: " + values[0] + " %"))
.setProgress(PROGRESS_MAX, values[0], false);
notificationManager.notify(notificationId, builder.build());
}
}
@Override
public void downloadSuccess(Integer... positions) {
data.pdfStatus = PDF_DOWNLOADED;
data.setProgress(100);
if (ipl != null)
ipl.onItemProgressChanged(position, data);
builder.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Current Progress: 100 %"))
.setProgress(0, 0, false);
notificationManager.notify(notificationId, builder.build());
notificationManager.cancel(notificationId);
}
@Override
public void downloadCancelled(String errorMessage) {
data.pdfStatus = PDF_DOWNLOAD_CANCELLED;
data.setProgress(-1);
if (ipl != null)
ipl.onItemProgressChanged(position, data);
builder.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Operation has been cancelled!:\n" + errorMessage))
.setProgress(0, 0, false);
notificationManager.notify(notificationId, builder.build());
}
@Override
public void downloadFailed(String errorMessage) {
data.pdfStatus = PDF_DOWNLOAD_FAILED;
data.setProgress(-1);
if (ipl != null)
ipl.onItemProgressChanged(position, data);
builder.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Operation has been cancelled!:\n" + errorMessage))
.setProgress(0, 0, false);
notificationManager.notify(notificationId, builder.build());
}
};
try {
String finalPath = cloudManager.getRemoteFilePath(data.filepath, true);
cloudManager.getArticlePdfDownloader(pd)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, finalPath);
} catch (NullPointerException npe) {
npe.printStackTrace();
parentFragment.alert(context.getString(R.string.alert_cloud_not_set));
}
}
为了清楚起见,“ ipl”是适配器传递给Holder的另一个接口,试图让我在下载进行时更新尽可能少的卡。定义ipl的最懒/最愚蠢的方式是:
adapter.setOnItemProgressListener((position, data)->adapter.notifyDataSetChanged());
最后,bindData由适配器调用
@Override
public void onBindViewHolder(@NonNull AbstractDownloadableHolder holder, int position) {
DownloadableData currentPaper = this.dataList.get(position);
holder.bindData(currentPaper, ipl);
}