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

Nishant Srivastava - The A, B and C of Lifecycl...

Nishant Srivastava - The A, B and C of Lifecycle Components

droidcon Berlin

July 17, 2018
Tweet

More Decks by droidcon Berlin

Other Decks in Programming

Transcript

  1. The Challenge Android activity lifecycle - Many states - Repeats

    on configuration changes Not to forget...
  2. Lifecycle Components Series of classes designed to help deal with

    lifecycles in a more consistent fashion. - Lifecycle - LifecycleOwner - LifecycleObserver
  3. Lifecycle Series of states an object can be in. For

    Android: Object that defines Android lifecycle states. i.e. Activity & Fragment
  4. Lifecycle dependencies { def lifecycle_version = "1.1.1" // Support library

    already depends on this (since v26.1.0) // Both AppCompatActivity & Support Fragment implement // LifecycleOwner interface. // Lifecycles only implementation "android.arch.lifecycle:runtime:$lifecycle_version" ... }
  5. Lifecycle // Source code public abstract class Lifecycle { //

    Adds a LifecycleObserver addObserver(@NonNull LifecycleObserver observer) // Removes the given observer from the observers list removeObserver(@NonNull LifecycleObserver observer) // Current state of the Lifecycle getCurrentState() // Compares the lifecycle states isAtLeast(@NonNull State state) ... }
  6. Lifecycle // Source code public abstract class Lifecycle { //

    Adds a LifecycleObserver addObserver(@NonNull LifecycleObserver observer) // Removes the given observer from the observers list removeObserver(@NonNull LifecycleObserver observer) // Current state of the Lifecycle getCurrentState() // Compares the lifecycle states isAtLeast(@NonNull State state) ... }
  7. Lifecycle // Source code public abstract class Lifecycle { //

    Adds a LifecycleObserver addObserver(@NonNull LifecycleObserver observer) // Removes the given observer from the observers list removeObserver(@NonNull LifecycleObserver observer) // Current state of the Lifecycle getCurrentState() // Compares the lifecycle states isAtLeast(@NonNull State state) ... }
  8. LifecycleOwner Interface that goes through Android Lifecycle. // Source code

    public interface LifecycleOwner { // Returns the Lifecycle of the provider. @NonNull Lifecycle getLifecycle(); }
  9. LifecycleOwner class MainActivity : AppCompatActivity() { // Missing myLifecycleObserver override

    fun onResume() { // Add lifecycle observer lifecycle.addObserver(myLifecycleObserver) } override fun onStop() { // Remove lifecycle observer lifecycle.removeObserver(myLifecycleObserver) } }
  10. LifecycleOwner Fun Fact: Activities & fragments are not the only

    things with lifecycle by default You also have - LifecycleService - ProcessLifecycleOwner
  11. LifecycleService A service that is also a LifecycleOwner // Source

    code public class LifecycleService extends Service implements LifecycleOwner { ... }
  12. ProcessLifecycleOwner - Class that tracks the lifecycle of - whole

    application process or - all the activities combined
  13. ProcessLifecycleOwner - Class that tracks the lifecycle of - whole

    application process or - all the activities combined - Useful for reacting to app coming to foreground or going to background
  14. ProcessLifecycleOwner dependencies { def lifecycle_version = "1.1.1" // For ProcessLifecycleOwner

    implementation "android.arch.lifecycle:extensions:$lifecycle_version" ... }
  15. ProcessLifecycleOwner ON_CREATE (Only 1 time) ON_START & ON_RESUME (First Activity

    pass) ON_PAUSE & ON_STOP (after 700ms delay) ON_DESTROY
  16. ProcessLifecycleOwner ON_CREATE (Only 1 time) ON_START & ON_RESUME (First Activity

    pass) ON_PAUSE & ON_STOP (after 700ms delay) ON_DESTROY
  17. ProcessLifecycleOwner ON_CREATE (Only 1 time) ON_START & ON_RESUME (First Activity

    pass) ON_PAUSE & ON_STOP (after 700ms delay) ON_DESTROY
  18. ProcessLifecycleOwner ON_PAUSE & ON_STOP (after 700ms delay) // Source code

    public class ProcessLifecycleOwner implements LifecycleOwner { static final long TIMEOUT_MS = 700; //mls ... }
  19. ProcessLifecycleOwner // Source code // Internal class to initialize Lifecycles.

    public class ProcessLifecycleOwnerInitializer extends ContentProvider { @Override public boolean onCreate() { ... ProcessLifecycleOwner.init(getContext()); return true; } ... }
  20. ProcessLifecycleOwner Side-effect: Inits ProcessLifecycleOwner even if your app does not

    use it! Why? So that ProcessLifecycleOwner can be invoked as soon as process starts
  21. Application.ActivityLifecycleCallback // Source code public interface ActivityLifecycleCallbacks { void onActivityCreated(Activity

    var1, Bundle var2); ... void onActivitySaveInstanceState(Activity var1, Bundle var2); void onActivityDestroyed(Activity var1); }
  22. ProcessLifecycleOwner // Source code public class ProcessLifecycleOwner implements LifecycleOwner {

    ... void attach(Context context) { ... Application app = (Application) context.getApplicationContext(); app.registerActivityLifecycleCallbacks (new EmptyActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { .. } ... }); } }
  23. ProcessLifecycleOwner // Source code public class ProcessLifecycleOwner implements LifecycleOwner {

    ... void attach(Context context) { ... Application app = (Application) context.getApplicationContext(); app.registerActivityLifecycleCallbacks (new EmptyActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { .. } ... }); } }
  24. ProcessLifecycleOwner // Source code public class ProcessLifecycleOwner implements LifecycleOwner {

    ... void attach(Context context) { ... Application app = (Application) context.getApplicationContext(); app.registerActivityLifecycleCallbacks (new EmptyActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { .. } ... }); } }
  25. ProcessLifecycleOwner // Source code class EmptyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { @Override

    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { //Empty method body } ... }
  26. ProcessLifecycleOwner // Source code class EmptyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { @Override

    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { //Empty method body } ... }
  27. LifecycleRegistry Implementation of Lifecycle that can handle multiple observers //

    Source code public class LifecycleRegistry extends Lifecycle { ... }
  28. LifecycleRegistry Implementation of Lifecycle that can handle multiple observers //

    Source code public class LifecycleRegistry extends Lifecycle { ... } However, you need to dispatch the events yourself.
  29. LifecycleRegistry class MyLifecycleOwner : LifecycleOwner { private var registry: LifecycleRegistry

    = LifecycleRegistry(this) init { registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) } override fun getLifecycle(): Lifecycle = registry fun startListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_START) } fun stopListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_STOP) } }
  30. LifecycleRegistry class MyLifecycleOwner : LifecycleOwner { private var registry: LifecycleRegistry

    = LifecycleRegistry(this) init { registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) } override fun getLifecycle(): Lifecycle = registry fun startListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_START) } fun stopListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_STOP) } }
  31. LifecycleRegistry class MyLifecycleOwner : LifecycleOwner { private var registry: LifecycleRegistry

    = LifecycleRegistry(this) init { registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) } override fun getLifecycle(): Lifecycle = registry fun startListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_START) } fun stopListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_STOP) } }
  32. LifecycleRegistry class MyLifecycleOwner : LifecycleOwner { private var registry: LifecycleRegistry

    = LifecycleRegistry(this) init { registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) } override fun getLifecycle(): Lifecycle = registry fun startListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_START) } fun stopListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_STOP) } }
  33. LifecycleRegistry class MyLifecycleOwner : LifecycleOwner { private var registry: LifecycleRegistry

    = LifecycleRegistry(this) init { registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE) } override fun getLifecycle(): Lifecycle = registry fun startListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_START) } fun stopListening() { registry.handleLifecycleEvent(Lifecycle.Event.ON_STOP) } }
  34. LifecycleRegistry val myLifecycleOwner = MyLifecycleOwner() // Missing myLifecycleObserver // Add

    lifecycle observer myLifecycleOwner.lifecycle.addObserver(myLifecycleObserver) // Remove lifecycle observer myLifecycleOwner.lifecycle.removeObserver(myLifecycleObserver)
  35. LifecycleObserver An interface for observing a Lifecycle // Source code

    public interface LifecycleObserver { // Empty }
  36. LifecycleObserver dependencies { def lifecycle_version = "1.1.1" // For Annotation

    Support annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" ... }
  37. LifecycleObserver class MyLifecycleObserver : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun init() {}

    @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onStart() {} ... @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun cleanup() {} }
  38. LifecycleObserver val myLifecycleOwner = MyLifecycleOwner() val myLifecycleObserver = MyLifecycleObserver() //

    Add lifecycle observer myLifecycleOwner.lifecycle.addObserver(myLifecycleObserver) // Remove lifecycle observer myLifecycleOwner.lifecycle.removeObserver(myLifecycleObserver)
  39. LifecycleObserver val myLifecycleOwner = MyLifecycleOwner() val myLifecycleObserver = MyLifecycleObserver() //

    Add lifecycle observer myLifecycleOwner.lifecycle.addObserver(myLifecycleObserver) // Remove lifecycle observer myLifecycleOwner.lifecycle.removeObserver(myLifecycleObserver)
  40. DefaultLifecycleObserver android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }

    } dependencies { def lifecycle_version = "1.1.1" // For DefaultLifecycleObserver implementation "android.arch.lifecycle:common-java8:$lifecycle_version" ... }
  41. DefaultLifecycleObserver // Source code public interface DefaultLifecycleObserver extends FullLifecycleObserver {

    @Override default void onCreate(@NonNull LifecycleOwner owner) { ... } ... @Override default void onDestroy(@NonNull LifecycleOwner owner) { ... } }
  42. DefaultLifecycleObserver // Source code interface FullLifecycleObserver extends LifecycleObserver { void

    onCreate(LifecycleOwner owner); void onStart(LifecycleOwner owner); ... void onDestroy(LifecycleOwner owner); }
  43. LiveData A lifecycle aware base class for encapsulating loading data

    Lightweight implementation of Observer pattern
  44. LiveData dependencies { def lifecycle_version = "1.1.1" // For LiveData

    implementation "android.arch.lifecycle:livedata:$lifecycle_version" ... }
  45. LiveData // Source Code public abstract class LiveData<T> { ...

    protected void postValue(T value) {...} ... @MainThread protected void setValue(T value) {...} ... protected void onActive() {...} protected void onInactive() {...} }
  46. LiveData // Source Code public abstract class LiveData<T> { ...

    protected void postValue(T value) {...} // Sets the value async ... @MainThread protected void setValue(T value) {...} ... protected void onActive() {...} protected void onInactive() {...} }
  47. LiveData // Source Code public abstract class LiveData<T> { ...

    protected void postValue(T value) {...} // Sets the value async ... @MainThread protected void setValue(T value) {...} // Sets the value sync ... protected void onActive() {...} protected void onInactive() {...} }
  48. LiveData // Source Code public abstract class LiveData<T> { ...

    protected void postValue(T value) {...} // Sets the value async ... @MainThread protected void setValue(T value) {...} // Sets the value sync ... protected void onActive() {...} // Has active observers i.e in Start/Resume state protected void onInactive() {...} }
  49. LiveData // Source Code public abstract class LiveData<T> { ...

    protected void postValue(T value) {...} // Sets the value async ... @MainThread protected void setValue(T value) {...} // Sets the value sync ... protected void onActive() {...} // Has active observers i.e in Start/Resume state protected void onInactive() {...} // Has 0 active observers }
  50. LiveData class MySensorLiveData(context: Context?) : LiveData<Float>() { val sensorManager: SensorManager?

    = context? .getSystemService(Service.SENSOR_SERVICE) as SensorManager val sensorListener: SensorEventListener = object : SensorEventListener { override fun onSensorChanged(event: SensorEvent?) { // Set Value setValue(event?.values?.get(0)) } ... } }
  51. LiveData class MySensorLiveData(context: Context?) : LiveData<Float>() { val sensorManager: SensorManager?

    = context? .getSystemService(Service.SENSOR_SERVICE) as SensorManager val sensorListener: SensorEventListener = object : SensorEventListener { override fun onSensorChanged(event: SensorEvent?) { // Set Value setValue(event?.values?.get(0)) } ... } }
  52. LiveData class MySensorLiveData(context: Context?) : LiveData<Float>() { ... override fun

    onActive() { ... sensorManager?.registerListener(sensorListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST) } override fun onInactive() { ... sensorManager.unregisterListener(sensorListener) } }
  53. LiveData class MySensorLiveData(context: Context?) : LiveData<Float>() { ... override fun

    onActive() { ... sensorManager?.registerListener(sensorListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST) } override fun onInactive() { ... sensorManager.unregisterListener(sensorListener) } }
  54. ViewModel - Hold & manage UI related data in Lifecycle

    conscious way - Survives configuration changes - Prevents unnecessary reloading of data
  55. ViewModel dependencies { def lifecycle_version = "1.1.1" // For ViewModel

    implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" ... }
  56. ViewModel // Source code public abstract class ViewModel { //

    Called when ViewModel is destroyed protected void onCleared() { } }
  57. ViewModel class MyViewModel : ViewModel() { private val username =

    MutableLiveData<String>() fun initExpensiveOperation() { // expensive operation, e.g. network request username.value = "Nishant" // username.setValue(“Nishant”) } fun getUsername(): LiveData<String> { return username } }
  58. ViewModel class MyViewModel : ViewModel() { private val username =

    MutableLiveData<String>() fun initExpensiveOperation() { // expensive operation, e.g. network request username.value = "Nishant" // username.setValue(“Nishant”) } fun getUsername(): LiveData<String> { return username } }
  59. ViewModel class MyViewModel : ViewModel() { private val username =

    MutableLiveData<String>() fun initExpensiveOperation() { // expensive operation, e.g. network request username.value = "Nishant" // username.setValue(“Nishant”) } fun getUsername(): LiveData<String> { return username } }
  60. ViewModel class MyViewModel : ViewModel() { private val username =

    MutableLiveData<String>() fun initExpensiveOperation() { // expensive operation, e.g. network request username.value = "Nishant" // username.setValue(“Nishant”) } fun getUsername(): LiveData<String> { return username } }
  61. ViewModel class MyViewModel : ViewModel() { private val username =

    MutableLiveData<String>() fun initExpensiveOperation() { // expensive operation, e.g. network request username.value = "Nishant" // username.setValue(“Nishant”) } fun getUsername(): LiveData<String> { return username } }
  62. ViewModel class MyViewModel : ViewModel() { private val username =

    MutableLiveData<String>() fun initExpensiveOperation() { // expensive operation, e.g. network request username.value = "Nishant" // username.setValue(“Nishant”) } fun getUsername(): LiveData<String> { return username } }
  63. More Info Is your Android Library, Lifecycle-Aware? https://android.jlelse.eu/is-your-android-library-lifecycle-aware-127629d32dcc Official documentation

    about lifecycle components d.android.com/topic/libraries/architecture/lifecycle Using ProcessLifecycleOwner for libraries example https://github.com/nisrulz/android-examples/tree/develop/UsingProcessLifecycleOwnerForLibs Using Lifecycle Components for libraries example https://github.com/nisrulz/android-examples/tree/develop/LifeCycleCompForLib