在任务期间显示进度对话框而不阻塞 Android 中的 UI 线程

Show progress dialog during task without blocking UI thread in Android

@Override
protected void onCreate (Bundle savedInstanceState) {
    
    progressDialog.show();

    if (/* task that returns a boolean value */) {
        // Do stuff        
    }
    else {
        // Do other stuff     
    }

    progressDialog.dismiss();

}

此代码应显示进度对话框,等待任务产生结果,然后计算 if 语句并关闭对话框。但这不会发生:UI 线程被阻塞,任务被执行,然后才显示进度对话框,然后立即被关闭。

解决这个问题的正确方法是什么?

一个简单的worker thread.

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            // a potentially time consuming task
        }
    }).start();
}

根据您在本 中提到的要求,可以考虑其他替代方案。

您可以为此目的使用 AsyncTask,但是,它已在 Sdk 30 中弃用,建议直接使用 java.concurrent.* 实用程序 docs。以下是使用 ExecutorService 的解决方法,虽然它并不完美,但它绝对满足您的功能:

在您的Activity(例如,MyActivity)中,创建一个ExecutorService 成员并对其进行初始化。添加方法和回调如下,当你想执行一些后台任务时,只需调用它:

public class MyActivity extends AppCompatActivity {
    // You can use your preferred executor
    private final ExecutorService executor = new ThreadPoolExecutor(0, 1,
            3L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>());

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        // Initiate the task
        executeParallel(new Callable<Boolean> {
            @Override
            public Boolean call() {
                // Perform your task and return boolean
                return trueOrFalse;
            }
        }, new Callback<Boolean>() {
            @Override
            public void onStart() {
                // Show progress dialog
                progressDialog.show();
            }

            @Override
            public void onComplete(Boolean result) {
                if (result) {
                    // Do some tasks
                } else {
                    // Do other tasks
                }
                // Remove dialog
                progressDialog.dismiss();
            }
        }, new Handler(Looper.getMainLooper()));
    }

    public <R> void executeParallel(@NonNull Callable<R> callable, @Nullable Callback<R> callback, Handler handler) {
        executor.execute(() -> {
            handler.post(() -> {
                if (callback != null) {
                    callback.onStart();
                }
            });
            R r = null;
            try {
                r = callable.call();
            } catch (Exception e) {
                // Ignore
            } finally {
                R result = r;
                handler.post(() -> {
                    if (callback != null) {
                        callback.onComplete(result);
                    }
                });
            }
        });
    }

    public interface Callback<R> {
        void onStart();
        void onComplete(R result);
    }
}

完成后,只需关闭 ExecutorService。如果您使用它们进行更好的设计,可以将此 Executor 和相关方法移动到 ViewModel 中。请记住,您不应直接使用 Thread 以避免潜在的内存泄漏。