[JAVA] A story about using Lifecycle Observer and Rx Lifecycle for life cycle monitoring such as Presenter

Introduction

At Google IO 2017, Lifecycle Observer was announced as one of the Android Architecture Components. LifecycleObserver, as the name implies, has the role of monitoring life cycle events such as Activity and Fragment and easily notifying them on an annotation basis. RxLifecycle is a library that manages RxAndroid disposables created by Trello. The feature is that you can easily manage the disposables such as RxJava from the compose clause, and you can easily manage the disposables from the specified event. For detailed explanations, this article is recommended. How to bind to life cycle from RxAndroid v1.0.0

Presenter life cycle monitoring

Now, what are you doing to monitor Presenter's life cycle events in the first place? In many cases, onResume, onPause, and other Fragments to be handled are prepared and called. However, in that case, I think that it was difficult to solve it very simply because it was difficult to create a base class that makes these calls, or if you call each one steadily, the amount of code is large.

That's where Lifecycle Observer came in. By implementing LifecycleRegistryOwner in Fragment, Activity, etc., it will be possible to inform LifecycleObserver of lifecycle events. This allows you to add life cycle events to classes that you want to respect their life cycle, even if you are not an MVP Presenter.

RxLifecycleObserver

Since RxLifecycle can bind the life cycle to the class that implements LifecycleProvider, this time, LifecycleObserver and LifecycleObserver are made compatible with RxLifecycle by creating a class that implements LifecycleProvider. Below is the actual code.

/**
 * LifecycleObserver convert to Rx
 */
abstract class RxLifecycleObserver : LifecycleProvider<Lifecycle.Event>, LifecycleObserver {
    companion object {
        // For Architecture LifeCycle Binder
        val ARCH_LIFECYCLE = Function<Lifecycle.Event, Lifecycle.Event> { lastEvent ->
            when (lastEvent) {
                Lifecycle.Event.ON_CREATE -> Lifecycle.Event.ON_DESTROY
                Lifecycle.Event.ON_START -> Lifecycle.Event.ON_STOP
                Lifecycle.Event.ON_RESUME -> Lifecycle.Event.ON_PAUSE
                Lifecycle.Event.ON_PAUSE -> Lifecycle.Event.ON_STOP
                Lifecycle.Event.ON_STOP -> Lifecycle.Event.ON_DESTROY
                Lifecycle.Event.ON_ANY -> Lifecycle.Event.ON_DESTROY
                Lifecycle.Event.ON_DESTROY -> throw OutsideLifecycleException("Cannot bind to Architecture lifecycle when outside of it.")
            }
        }
    }

    private val lifecycleSubject = BehaviorSubject.create<Lifecycle.Event>()

    override fun lifecycle(): Observable<Lifecycle.Event> = lifecycleSubject.hide()

    override fun <T : Any?> bindToLifecycle(): LifecycleTransformer<T> = RxLifecycle.bind(lifecycleSubject, ARCH_LIFECYCLE)

    override fun <T : Any?> bindUntilEvent(event: Lifecycle.Event): LifecycleTransformer<T> = RxLifecycle.bindUntilEvent(lifecycleSubject, event)

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    open fun onCreate() {
        lifecycleSubject.onNext(Lifecycle.Event.ON_CREATE)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    open fun onStart() {
        lifecycleSubject.onNext(Lifecycle.Event.ON_START)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    open fun onResume() {
        lifecycleSubject.onNext(Lifecycle.Event.ON_RESUME)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    open fun onPause() {
        lifecycleSubject.onNext(Lifecycle.Event.ON_PAUSE)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    open fun onStop() {
        lifecycleSubject.onNext(Lifecycle.Event.ON_STOP)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    open fun onDestroy() {
        lifecycleSubject.onNext(Lifecycle.Event.ON_DESTROY)
    }
}

GistCode

Each receives LifecycleObserver events in the form of @OnLifecycleEvent and sends values to the Subject that holds the current event. Then, ARCH_LIFECYCLE determines the lifetime of each disposable disposable when bound.

At the end

LifecycleObserver receives the life cycle events of Activity and Fragment in a merged form, so I felt that it was perfect for managing the life cycle in the first place. Also, due to the high extensibility of RxLifecycle, I thought that it would be possible to write lifecycle monitoring events in a very good form.

Please give it a try.

Recommended Posts

A story about using Lifecycle Observer and Rx Lifecycle for life cycle monitoring such as Presenter
A story about Java 11 support for Web services
A story about Apache Wicket and atomic design