android 如何在ExecutorService中设置progressBar的进度?不想使用AsyncTask,因为它已过时

fdx2calv  于 2023-05-21  发布在  Android
关注(0)|答案(1)|浏览(151)

我使用下面的代码基本上复制一个文件内的执行器,我想在复制数据到一个文件发布进度。问题是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++;
            }
        });

任何帮助感激不尽。

4si2a6ki

4si2a6ki1#

您可以这样使用Executor服务抽象,

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()方法中发布您的进度。

这里是如何使用它,

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

相关问题