RxAndroid 重复ui 操作任务错误

RxAndroid repeated ui manipulation task error

我有以下代码来启用沉浸式模式。这是一个重复的任务,每 1 秒执行一次:

Completable
                        .fromAction(() -> {
                                if (uiSystemVisibility == 0) enableImmersiveMode();
                        })
                        .subscribeOn(Schedulers.io())
                        .repeatWhen(objectFlowable -> objectFlowable.delay(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread()))
                        .subscribe();

enableImmersiveMode():

public void enableImmersiveMode() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        return;
    }

    getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_IMMERSIVE);
}

调用 enableImmersiveMode() 时出现以下错误:

Only the original thread that created a view hierarchy can touch its views

我已将要运行的 mainThread 调度程序添加到 delay() 方法,但错误仍然存​​在。谁能告诉我我做错了什么?

这一行:

.subscribeOn(Schedulers.io())

意味着您的可调用代码中的代码将 运行 在 IO 线程上。 所以第一次调用该方法时,它将在 IO 线程上而不是主线程上。如果这不是您的意图,请删除该行。默认行为是订阅可观察对象的线程将是执行可调用对象中代码的线程。

此外,您在 repeatWhen 的延迟运算符中定义的调度程序是将用于延迟的调度程序,默认为 Schedulers.computation()。但是您永远不会接触到这部分代码,因为这是针对可观察对象在初始订阅后重新订阅的情况。但是在初始订阅中,由于您从 IO 线程访问 UI,您的应用程序崩溃了。

如果你只想让这段代码每 1 秒执行一次,你可以试试这个:

val disposable = Observable.interval(1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    if (uiSystemVisibility == 0) enableImmersiveMode();
                }

请注意,此 observable 会一直重复,直到您告诉它停止。通过调用:

disposable.dispose()