Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Inside LifecycleObserver

kobito-kaba
July 18, 2018
34

Inside LifecycleObserver

How to handle components' lifecycle in Android app developing.

kobito-kaba

July 18, 2018
Tweet

Transcript

  1. Hiroyuki Mori
    @moridroid
    Inside LifecycleObserver

    View Slide

  2. Lifecycle Problems
    in Android

    View Slide

  3. in early days
    https://developer.android.com/guide/components/activities/activity-lifecycle.html

    View Slide

  4. today
    Steve Pomeroy https://github.com/xxv/android-lifecycle CC-BY-SA 4.0

    View Slide

  5. case 1:
    fetching data every onCreate

    View Slide

  6. case 1:
    fetching data every onCreate

    View Slide

  7. case 1:
    fetching data every onCreate

    View Slide

  8. case 1:
    fetching data every onCreate

    View Slide

  9. case 1:
    fetching data every onCreate

    View Slide

  10. case 1:
    fetching data every onCreate
    Wasteful

    View Slide

  11. case 2:
    showing after activity’s death

    View Slide

  12. case 2:
    showing after activity’s death

    View Slide

  13. case 2:
    showing after activity’s death

    View Slide

  14. case 2:
    showing after activity’s death
    Crash !!

    View Slide

  15. case 3:
    forgetting to stop observing

    View Slide

  16. case 3:
    forgetting to stop observing

    View Slide

  17. case 3:
    forgetting to stop observing

    View Slide

  18. case 3:
    forgetting to stop observing
    memory
    leak

    View Slide

  19. Handling lifecycles

    View Slide

  20. Lifecycle library

    View Slide

  21. Observer pattern

    View Slide

  22. View Slide

  23. View Slide

  24. View Slide

  25. View Slide

  26. View Slide

  27. View Slide

  28. ×

    View Slide

  29. View Slide

  30. View Slide

  31. View Slide

  32. loose coupled

    View Slide

  33. View Slide

  34. View Slide

  35. Event Channel

    View Slide

  36. View Slide

  37. notify events

    View Slide

  38. observe

    View Slide

  39. View Slide

  40. Inside Lifecycle library

    View Slide

  41. subscribing lifecycle events

    View Slide

  42. class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
      ...
    lifecycle.addObserver(yourObservable)
    }
    }

    View Slide

  43. public class LifecycleRegistry extends Lifecycle {
    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver
    = new ObserverWithState(observer, initialState);
    ObserverWithState previous
    = mObserverMap.putIfAbsent(observer, statefulObserver);

    View Slide

  44. public class LifecycleRegistry extends Lifecycle {
    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver
    = new ObserverWithState(observer, initialState);
    ObserverWithState previous
    = mObserverMap.putIfAbsent(observer, statefulObserver);

    View Slide

  45. static class ObserverWithState {
    ...
    ObserverWithState(LifecycleObserver observer, State initialState) {
    mLifecycleObserver = Lifecycling.getCallback(observer);
    ...
    }
    void dispatchEvent(LifecycleOwner owner, Event event) {
    ...
    mLifecycleObserver.onStateChanged(owner, event);
    ...
    }
    }

    View Slide

  46. static class ObserverWithState {
    ...
    ObserverWithState(LifecycleObserver observer, State initialState) {
    mLifecycleObserver = Lifecycling.getCallback(observer);
    ...
    }
    void dispatchEvent(LifecycleOwner owner, Event event) {
    ...
    mLifecycleObserver.onStateChanged(owner, event);
    ...
    }
    }

    View Slide

  47. publishing lifecycle events

    View Slide

  48. public class SupportActivity extends Activity implements LifecycleOwner {
    ...
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
    }
    ...
    }

    View Slide

  49. public class ReportFragment extends Fragment {
    ...
    public void onActivityCreated(Bundle savedInstanceState) {
    dispatch(Lifecycle.Event.ON_CREATE);
    }
    public void onStart() {
    dispatch(Lifecycle.Event.ON_START);
    }
    public void onResume() {
    dispatch(Lifecycle.Event.ON_RESUME);
    }
    public void onPause() {
    dispatch(Lifecycle.Event.ON_PAUSE);
    }
    public void onStop() {
    dispatch(Lifecycle.Event.ON_STOP);
    }
    ...
    }

    View Slide

  50. public class ReportFragment extends Fragment {
    ...
    private void dispatch(Lifecycle.Event event) {
    ...
    if (activity instanceof LifecycleOwner) {
    Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
    if (lifecycle instanceof LifecycleRegistry) {
    ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
    }
    }
    }
    }

    View Slide

  51. ObserverWithState
    AdapterObserver
    Adapter
    FooObserver
    ReportFragment
    SupportActivity
    LifecycleRegistry
    addObserver
    attach
    dispatch event
    sync

    View Slide

  52. ReportFragment
    SupportActivity
    LifecycleRegistry
    attach
    dispatch event

    View Slide

  53. FooObserver
    ReportFragment
    SupportActivity
    LifecycleRegistry
    addObserver
    attach
    dispatch event

    View Slide

  54. ObserverWithState
    AdapterObserver
    Adapter
    FooObserver
    ReportFragment
    SupportActivity
    LifecycleRegistry
    addObserver
    attach
    dispatch event
    sync

    View Slide

  55. Subscriber
    Publisher
    EventChannel
    subscribe
    publish event
    fire event

    View Slide

  56. How to use

    View Slide

  57. example:
    Observing network state

    View Slide

  58. View Slide

  59. View Slide

  60. without LifecycleObserver

    View Slide

  61. class NetworkStateReceiver(private val callback : (NetworkInfo?) -> Unit) : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
    val conn = context?.getSystemService(ConnectivityManager::class.java) ?: return
    callback(conn.activeNetworkInfo)
    }
    }
    Step1 : Create a BroadcastReceiver

    View Slide

  62. receiver = NetworkStateReceiver {
    if (it != null && it.isConnected) {
    textView.text = "online"
    } else {
    textView.text = "offline"
    }
    }
    Step2 : create an instance
    create an instance

    View Slide

  63. Step3 : register it at onResume
    override fun onResume() {
    super.onResume()
    val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
    registerReceiver(receiver, filter)
    }
    register at onResume

    View Slide

  64. override fun onPause() {
    super.onPause()
    unregisterReceiver(receiver)
    }
    Step4 : unregister it at onPause
    unregister at onPause

    View Slide

  65. override fun onPause() {
    super.onPause()
    unregisterReceiver(receiver)
    }
    Step5 : Never forget to unregister
    unregister at onPause
    Don’t miss it

    View Slide

  66. with LifecycleObserver

    View Slide

  67. enum class Connectivity { OFFLINE, ONLINE }
    class NetworkObservable(
    private var activity: Activity?,
    private val callback : (Connectivity) -> Unit) : LifecycleObserver {
    private val receiver = NetworkStateReceiver {
    if (it != null && it.isConnected) {
    callback(Connectivity.ONLINE)
    } else {
    callback(Connectivity.OFFLINE)
    }
    }
    }
    Step1 : Wrap the receiver

    View Slide

  68. enum class Connectivity { OFFLINE, ONLINE }
    class NetworkObservable(
    private var activity: Activity?,
    private val callback : (Connectivity) -> Unit) : LifecycleObserver {
    private val receiver = NetworkStateReceiver {
    if (it != null && it.isConnected) {
    callback(Connectivity.ONLINE)
    } else {
    callback(Connectivity.OFFLINE)
    }
    }
    }
    Step1 : Wrap the receiver
    implements
    LifecycleObserver

    View Slide

  69. @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun registerReceiver() {
    activity?.registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun unregisterReceiver() {
    activity?.unregisterReceiver(receiver)
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun release() {
    activity = null
    }
    Step2 : register / unregister at lifecycle events

    View Slide

  70. @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun registerReceiver() {
    activity?.registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun unregisterReceiver() {
    activity?.unregisterReceiver(receiver)
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun release() {
    activity = null
    }
    Step2 : register / unregister at lifecycle events
    @OnLifecycleEvent

    View Slide

  71. class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    ...
    lifecycle.addObserver( NetworkObservable(this) {
    if (it == Connectivity.ONLINE) {
    textView.text = "online"
    } else {
    textView.text = "offline"
    }
    })
    }
    }
    Step3 : Use it !

    View Slide

  72. class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    ...
    lifecycle.addObserver( NetworkObservable(this) {
    if (it == Connectivity.ONLINE) {
    textView.text = "online"
    } else {
    textView.text = "offline"
    }
    })
    }
    }
    Step3 : Use it !
    easy to use

    View Slide

  73. Conclusion

    View Slide

  74. Lifecycle Management

    View Slide

  75. Lifecycle Management
    - is a hard and hassle task

    View Slide

  76. Lifecycle Management
    - is a hard and hassle task
    - can cause problems

    View Slide

  77. Lifecycle Management
    - is a hard and hassle task
    - can cause problems
    The Lifecycle library

    View Slide

  78. Lifecycle Management
    - is a hard and hassle task
    - can cause problems
    The Lifecycle library
    - provides the feature to observe lifecycles

    View Slide

  79. Lifecycle Management
    - is a hard and hassle task
    - can cause problems
    The Lifecycle library
    - provides the feature to observe lifecycles
    - can create lifecycle-aware components easily

    View Slide

  80. Hiroyuki Mori
    @moridroid
    Thank you

    View Slide