繁体   English   中英

在任务期间显示进度对话框而不阻塞 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 线程被阻塞,任务被执行,然后才显示进度对话框,然后立即解除。

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

一个简单的工作线程

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 以避免潜在的内存泄漏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM