Slide 1

Slide 1 text

Hiroyuki Mori @moridroid Inside LifecycleObserver

Slide 2

Slide 2 text

Lifecycle Problems in Android

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

case 1: fetching data every onCreate

Slide 6

Slide 6 text

case 1: fetching data every onCreate

Slide 7

Slide 7 text

case 1: fetching data every onCreate

Slide 8

Slide 8 text

case 1: fetching data every onCreate

Slide 9

Slide 9 text

case 1: fetching data every onCreate

Slide 10

Slide 10 text

case 1: fetching data every onCreate Wasteful

Slide 11

Slide 11 text

case 2: showing after activity’s death

Slide 12

Slide 12 text

case 2: showing after activity’s death

Slide 13

Slide 13 text

case 2: showing after activity’s death

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

case 3: forgetting to stop observing

Slide 16

Slide 16 text

case 3: forgetting to stop observing

Slide 17

Slide 17 text

case 3: forgetting to stop observing

Slide 18

Slide 18 text

case 3: forgetting to stop observing memory leak

Slide 19

Slide 19 text

Handling lifecycles

Slide 20

Slide 20 text

Lifecycle library

Slide 21

Slide 21 text

Observer pattern

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

×

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

loose coupled

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Event Channel

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

notify events

Slide 38

Slide 38 text

observe

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

Inside Lifecycle library

Slide 41

Slide 41 text

subscribing lifecycle events

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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);

Slide 44

Slide 44 text

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);

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

publishing lifecycle events

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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); } ... }

Slide 50

Slide 50 text

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); } } } }

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

ReportFragment SupportActivity LifecycleRegistry attach dispatch event

Slide 53

Slide 53 text

FooObserver ReportFragment SupportActivity LifecycleRegistry addObserver attach dispatch event

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

Subscriber Publisher EventChannel subscribe publish event fire event

Slide 56

Slide 56 text

How to use

Slide 57

Slide 57 text

example: Observing network state

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

without LifecycleObserver

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

with LifecycleObserver

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

@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

Slide 70

Slide 70 text

@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

Slide 71

Slide 71 text

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 !

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

Conclusion

Slide 74

Slide 74 text

Lifecycle Management

Slide 75

Slide 75 text

Lifecycle Management - is a hard and hassle task

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

Hiroyuki Mori @moridroid Thank you