Observable Timer for screen timeout android

爷,独闯天下 提交于 2020-01-24 20:08:48

问题


I'm working on a use-case where I have to implement a sort of screen timeout after the completion of which application navigates to the main screen. I want it to implemente it using Observable and use Observable.timer() or Observable.interval() for the timing. (Either is suitable for my use-case.). Every time the user interacts with the activity I have to reset or refresh my timer Observable.

This is where I am stuck. I don't know how to refresh or reset an Observable. A simple way would be to dispose the previous one and create a new one each time in onUserInteraction(), but I do not think that a good approach. What are the alternatives?


回答1:


Solution to this problem is not as simple as one might think. I have tried implement different approach. Instead of "clear or reset" observable, I'm using BehaviorSubject what is both Observer and Observable.

public class RxTimerNavigation {
    private final long TIMEOUT_INTERVAL = 4;
    private final BehaviorSubject<UserInteraction> userInteractionsSubject = BehaviorSubject.create(UserInteraction.IGNORED); // (1)

    public void onInteraction() {
        userInteractionsSubject.onNext(UserInteraction.IGNORED); // (2)
    }

    public Observable<UserInteraction> getTimerExpiration() {
        return userInteractionsSubject
                .timeout(TIMEOUT_INTERVAL, TimeUnit.SECONDS) // (3)
                .filter(__ -> false) // (4)
                .onErrorReturn(__ -> UserInteraction.FINISHED) // (5)
                .first() // (6)
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .asObservable();
    }

    static class UserInteraction {
        static final UserInteraction IGNORED = new UserInteraction();
        static final UserInteraction FINISHED = new UserInteraction();
    }
}

Let's explain marked parts:

  1. BehaviorSubject receives and emits UserInteraction objects
  2. Everytime user interacts with UI, you should call method onInteraction() and new item is "added" to Subject.
  3. Sets Timeout. It throws TimeoutException, when there is no emitted item for specified amount of time (TIMEOUT_INTERVAL). Timer is started when you call subscribe() on Observable provided by getTimerExpiration() method.
  4. We ignore all the emitted items, because we are waiting for the exception
  5. We are "transforming" exception to UserInteraction.FINISHED object
  6. We want emit only one value, because we are finishing



回答2:


That's a perfectly valid approach. Dispose / unsubscribe the existing, obsolete timer and start a new observable with the now-correct values. If you have too many user interactions that may cause undue performance

The other way to do this is to have something like a volatile expected-blank value that is updated every time the user interacts with the application. You start a timer that will trigger on that expected-blank moment, and which checks whether that value is in the future. If it is, it starts a new instance of the timer and completes. If it is in the present/past, it blanks the screen and completes.



来源:https://stackoverflow.com/questions/44239862/observable-timer-for-screen-timeout-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!