我基本上使用下面的代码在Executor中复制文件,并希望在将数据复制到文件过程中发布进度.问题是,直到复制文件完成后,ProgressBar才会更新.进度一下子从0%提高到100%,而不是显示出进度.

 int x=0;
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(()->{
            myDataBase.sendJsonToFile(path,"myFile"+".json");
            for(int i=0;i<=100;i++){
                new Handler(Looper.getMainLooper()).post(()->{
                    progressbar.setProgress(x);
                });
                x++;
            }
        });

如果有任何帮助,我很感激.

推荐答案

You can use the Executor service abstraction like this,

public abstract class AsyncTaskV2<Params, Progress, Result> {

    public enum Status {
        FINISHED,
        PENDING,
        RUNNING
    }

    // This handler will be used to communicate with main thread
    private final Handler handler = new Handler(Looper.getMainLooper());
    private final AtomicBoolean cancelled = new AtomicBoolean(false);

    private Result result;
    private Future<Result> resultFuture;
    private ExecutorService executor;
    private Status status = Status.PENDING;

    // Base class must implement this method
    protected abstract Result doInBackground(Params params);

    // Methods with default implementation
// Base class can optionally override these methods.
    protected void onPreExecute() {
    }

    protected void onPostExecute(Result result) {
    }

    protected void onProgressUpdate(Progress progress) {
    }

    protected void onCancelled() {
    }

    protected void onCancelled(Result result) {
        onCancelled();
    }

    protected boolean isShutdown() {
        return executor.isShutdown();
    }

    @MainThread
    public final Future<Result> execute(@Nullable Params params) {
        status = Status.RUNNING;
        onPreExecute();
        try {
            executor = Executors.newSingleThreadExecutor();
            Callable<Result> backgroundCallableTask = () -> doInBackground(params);
// Execute the background task
            resultFuture = executor.submit(backgroundCallableTask);

// On the worker thread — wait for the background task to complete
            executor.submit(this::getResult);
            return resultFuture;
        } finally {
            if (executor != null) {
                executor.shutdown();
            }
        }
    }

    private Runnable getResult() {
        return () -> {
            try {
                if (!isCancelled()) {
// This will block the worker thread, till the result is available
                    result = resultFuture.get();

// Post the result to main thread
                    handler.post(() -> onPostExecute(result));
                } else {
// User cancelled the operation, ignore the result
                    handler.post(this::onCancelled);
                }
                status = Status.FINISHED;
            } catch (InterruptedException | ExecutionException e) {
                Log.e("TAG", "Exception while trying to get result" + e.getMessage());
            }
        };
    }

    @WorkerThread
    public final void publishProgress(Progress progress) {
        if (!isCancelled()) {
            handler.post(() -> onProgressUpdate(progress));
        }
    }

    @MainThread
    public final void cancel(boolean mayInterruptIfRunning) {
        cancelled.set(true);
        if (resultFuture != null) {
            resultFuture.cancel(mayInterruptIfRunning);
        }
    }

    @AnyThread
    public final boolean isCancelled() {
        return cancelled.get();
    }

    @AnyThread
    public final Status getStatus() {
        return status;
    }
}

现在,就像异步任务一样,这个类有onPreExecute()onPostExecute()doInBackground()个.你可以用publishProgress()方法发布你的进展.

Here is how to use it,

new AsyncTaskV2<Void, Integer, Void>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

            @Override
            protected Void doInBackground(Void unused) {
                myDataBase.sendJsonToFile(path,"myFile"+".json");
                for(int i=0;i<=100;i++){
                    publishProgress(x);
                    x++;
                }
                publishProgress();
                return null;
            }

            @Override
            protected void onProgressUpdate(Integer integer) {
                super.onProgressUpdate(integer);
            }

            @Override
            protected void onPostExecute(Void unused) {
                super.onPostExecute(unused);
            }
        }.execute(null);

Android相关问答推荐

如何在cordova 中播放html5视频标签?

将动作传递给嵌套的可组合物

如何在"不同活动"中添加不同按钮?

如何go 除回调流中不可用的状态?

在Android Studio中,如何在BuildSrc Dependenices Kotlin文件中指定时标记与旧版本的依赖关系

穿戴与iPhone连接的安卓操作系统

如何在android库中关联应用程序链接?

在 Compose 中,当用户持续向下滚动时,LazyColumn 不会显示新项目

React-Native Manifest 合并失败并出现多个错误

列表更改时,RecyclerView 中的列表不会更新

在Android RoomDB中使用Kotlin Flow和删除数据时如何解决错误?

获取模板向导配方类 Intellij 中的应用程序包名称

有什么方法可以确定正在使用哪个 Android 手机的麦克风进行录音?

前台服务通知需要几秒钟才能显示

为什么我不能直接记住 mutableStateOf 可组合函数?

TextField 溢出和软包装不适用于 Compose 约束布局

对话框中的内容不可见

Kotlin:如何在另一个变量的名称中插入一个变量的值

构成material 3 中的分隔符

在delphi中将Jnet_uri转换为Tbitmap