使用createBackgroundTaskDialog执行异步任务时,进度显示一直为0

使用createBackgroundTaskDialog执行异步任务时,进度条显示是对的,文字显示一直为0

image

能提供一个可重现的小项目吗?我这边测试是可以的:
image

后台任务是上传阿里云视频点播媒体资料,使用的是阿里云的上传文件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行,这里是更新进度文字信息的:

image

用Debug方式启动,断点处看到percentValue是正确值,界面“处理中”数字显示正确。改回正常启动,界面也正确了。。。哪里的代码也没改,不知道咋回事。现在是正常显示的。

1 个赞