使用createBackgroundTaskDialog执行异步任务时,进度条显示是对的,文字显示一直为0
能提供一个可重现的小项目吗?我这边测试是可以的:
后台任务是上传阿里云视频点播媒体资料,使用的是阿里云的上传文件SDK。
我使用文档中的例子是没问题的:
public Void run(TaskLifeCycle<Integer> taskLifeCycle) throws Exception {
for (int i=1; i< ITERATIONS; i++) {
TimeUnit.SECONDS.sleep(1);
taskLifeCycle.publish(i);
}
return null;
}
那你看看阿里云返回的percent具体值是多少?还有窗口中 withTotal()
设置的总量又是多少?
withTotal设置的是100,percent是计算出来的,0-100之间。total和percent都是正确的,进度条显示也是正确的,只是“处理中”文本中的数字一直是0。
阿里云视频上传sdk通过一个监听类回调来传递进度,在我自己的监听实现类中,通过lamda函数向backgroundTask返回进度(sdk的调用是在backgroundTask中发起的),然后调用publish将进度返回给视图。
这是课程详情视图,自己处理的SaveAction,其中有一个属性是FileRef,是需要上传到阿里云的视频文件。
@Subscribe("saveAction")
public void onSaveAction(final ActionPerformedEvent event) {
ValidationErrors errors = viewValidation.validateUiComponents(form);
if (!errors.isEmpty()) {
viewValidation.showValidationErrors(errors);
return;
}
if (fileId != null && "tempStorage".equals(getEditedEntity().getFile().getStorageName()))
getEditedEntity().setFile(temporaryStorage.putFileIntoStorage(fileId, fileName));
if (coverFileId != null && "tempStorage".equals(getEditedEntity().getCover().getStorageName()))
getEditedEntity().setCover(temporaryStorage.putFileIntoStorage(coverFileId, coverFileName));
if (fileId != null && needUpload)
uploadToAliyun();
else
closeWithSave();
}
private void uploadToAliyun() {
FileRef fileRef = getEditedEntity().getFile();
BackgroundTask<Integer, Void> task = new UploadTask(fileRef.getFileName(), fileUtils.getStorageFilePath(fileRef.getPath()), this.organizationName + ",安全学习课件");
dialogs.createBackgroundTaskDialog(task)
.withHeader("同步中")
.withText(fileRef.getFileName())
.withTotal(100)
.withShowProgressInPercentage(true)
.withCancelAllowed(false)
.open();
}
这个是BackgroundTask实现类,在run方法中调用上传文件至阿里云,通过lamda函数返回上传进度和状态。
private class UploadTask extends BackgroundTask<Integer, Void> {
private final String title;
private final String filePath;
private final String tags;
public UploadTask(String title, String filePath, String tags) {
super(10, TimeUnit.MINUTES, CourseDetailView.this);
this.title = title;
this.filePath = filePath;
this.tags = tags;
}
@Override
public Void run(TaskLifeCycle<Integer> taskLifeCycle) {
aliyunVodUtils.uploadVideo(title, filePath, tags, (videoId, playUrl) -> {
Course course = getEditedEntity();
course.setVideoId(videoId);
course.setVideoPlayUrl(playUrl);
}, (message) -> {
notifications.create("同步发生错误", message).withThemeVariant(NotificationVariant.LUMO_ERROR).show();
}, (bytes, total, percent) -> {
try {
taskLifeCycle.publish(percent);
} catch (InterruptedException ignored) {}
});
return null;
}
public void done(Void result) {
CourseDetailView.this.closeWithSave();
}
}
这个是调用阿里云SDK开始上传,调用upload.uploadVideo()开始上传,并通过ProgressListener返回进度。
public void uploadVideo(String title, String filePath, String tags, Success success, Fail fail, ProgressChange progressChange) {
UploadVideoRequest request = new UploadVideoRequest(accessKeyId, accessKeySecret, title, filePath);
request.setTags(tags);
request.setPrintProgress(true);
request.setProgressListener(new ProgressListener(success, fail, progressChange));
UploadVideoImpl uploader = new UploadVideoImpl();
uploader.uploadVideo(request);
}
这个是ProgressListener,在不同事件中通过lamda函数返回状态。
private static class ProgressListener implements VoDProgressListener {
Success success;
Fail fail;
ProgressChange progressChange;
private long writtenBytes = 0;
private long totalBytes = -1;
private String videoId;
public ProgressListener(Success success, Fail fail, ProgressChange progressChange) {
super();
this.success = success;
this.fail = fail;
this.progressChange = progressChange;
}
public void progressChanged(ProgressEvent progressEvent) {
long bytes = progressEvent.getBytes();
ProgressEventType eventType = progressEvent.getEventType();
switch (eventType) {
case TRANSFER_STARTED_EVENT:
break;
case REQUEST_CONTENT_LENGTH_EVENT:
this.totalBytes = bytes;
break;
case REQUEST_BYTE_TRANSFER_EVENT:
this.writtenBytes += bytes;
if (this.totalBytes != -1) {
int percent = (int) (this.writtenBytes * 100.0 / this.totalBytes);
if (this.progressChange != null)
this.progressChange.callback(this.writtenBytes, totalBytes, percent);
}
break;
case TRANSFER_COMPLETED_EVENT:
if (this.videoId != null) {
try {
DefaultAcsClient client = initAcsClient();
GetPlayInfoRequest req = new GetPlayInfoRequest();
req.setVideoId(videoId);
GetPlayInfoResponse resp = client.getAcsResponse(req);
List<GetPlayInfoResponse.PlayInfo> playInfoList = resp.getPlayInfoList();
if (this.success != null && !ObjectUtils.isEmpty(playInfoList))
this.success.callback(this.videoId, playInfoList.get(0).getPlayURL());
} catch (Exception ignored) {}
}
break;
case TRANSFER_FAILED_EVENT:
if (this.fail != null) {
this.fail.callback("同步失败");
}
break;
}
}
public void onVidReady(String videoId) {
this.videoId = videoId;
}
public void onImageIdReady(String imageId) {
}
}
这个是lamda函数定义。
@FunctionalInterface
public interface Success {
void callback(String videoId, String playUrl);
}
@FunctionalInterface
public interface Fail {
void callback(String message);
}
@FunctionalInterface
public interface ProgressChange {
void callback(long bytes, long total, int percent);
}
嗯。看上去应该是没问题的。你可以打断点跟踪下面的代码:
DialogsImpl.java
的1041行,这里是更新进度文字信息的:
用Debug方式启动,断点处看到percentValue是正确值,界面“处理中”数字显示正确。改回正常启动,界面也正确了。。。哪里的代码也没改,不知道咋回事。现在是正常显示的。
1 个赞