我有以下代码来启用沉浸式模式。这是重复的任务,每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()方法中,但是错误仍然存在。谁能告诉我我在做什么错?
答案 0 :(得分:3)
此行:
.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();
}
请注意,此可观察的对象将重复出现,直到您告诉它停止为止。通过致电:
disposable.dispose()