Share
Embed
Transcript
116 slides
-
The Challenge Android activity lifecycle - Many states - Repeats
on configuration changes -
The Challenge Android activity lifecycle - Many states - Repeats
on configuration changes Not to forget... -
Lifecycle Components Series of classes designed to help deal with
lifecycles in a more consistent fashion. -
Lifecycle Components Series of classes designed to help deal with
lifecycles in a more consistent fashion. - Lifecycle - LifecycleOwner - LifecycleObserver -
Lifecycle Series of states an object can be in. For
Android: Object that defines Android lifecycle states. i.e. Activity & Fragment -
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" ... } -
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) ... } -
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) ... } -
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) ... } -
LifecycleOwner Interface that goes through Android Lifecycle. // Source code
public interface LifecycleOwner { // Returns the Lifecycle of the provider. @NonNull Lifecycle getLifecycle(); } -
LifecycleOwner class MainActivity : AppCompatActivity() { // Missing myLifecycleObserver override
fun onResume() { // Add lifecycle observer lifecycle.addObserver(myLifecycleObserver) } override fun onStop() { // Remove lifecycle observer lifecycle.removeObserver(myLifecycleObserver) } } -
LifecycleOwner Fun Fact: Activities & fragments are not the only
things with lifecycle by default -
LifecycleOwner Fun Fact: Activities & fragments are not the only
things with lifecycle by default You also have - LifecycleService - ProcessLifecycleOwner -
LifecycleService A service that is also a LifecycleOwner // Source
code public class LifecycleService extends Service implements LifecycleOwner { ... } -
ProcessLifecycleOwner - Class that tracks the lifecycle of - whole
application process or - all the activities combined -
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 -
ProcessLifecycleOwner dependencies { def lifecycle_version = "1.1.1" // For ProcessLifecycleOwner
implementation "android.arch.lifecycle:extensions:$lifecycle_version" ... } -
ProcessLifecycleOwner ON_CREATE (Only 1 time) ON_START & ON_RESUME (First Activity
pass) ON_PAUSE & ON_STOP ON_DESTROY -
ProcessLifecycleOwner ON_CREATE (Only 1 time) ON_START & ON_RESUME (First Activity
pass) ON_PAUSE & ON_STOP (after 700ms delay) ON_DESTROY -
ProcessLifecycleOwner ON_CREATE (Only 1 time) ON_START & ON_RESUME (First Activity
pass) ON_PAUSE & ON_STOP (after 700ms delay) ON_DESTROY -
ProcessLifecycleOwner ON_CREATE (Only 1 time) ON_START & ON_RESUME (First Activity
pass) ON_PAUSE & ON_STOP (after 700ms delay) ON_DESTROY -
ProcessLifecycleOwner ON_PAUSE & ON_STOP (after 700ms delay) // Source code
public class ProcessLifecycleOwner implements LifecycleOwner { static final long TIMEOUT_MS = 700; //mls ... } -
ProcessLifecycleOwner Guarantee that ProcessLifecycleOwner won’t send any events if activities
are - Destroyed - Recreated due to configuration change -
ProcessLifecycleOwner // Source code // Internal class to initialize Lifecycles.
public class ProcessLifecycleOwnerInitializer extends ContentProvider { @Override public boolean onCreate() { ... ProcessLifecycleOwner.init(getContext()); return true; } ... } -
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 -
Application.ActivityLifecycleCallback // Source code public interface ActivityLifecycleCallbacks { void onActivityCreated(Activity
var1, Bundle var2); ... void onActivitySaveInstanceState(Activity var1, Bundle var2); void onActivityDestroyed(Activity var1); } -
Application.ActivityLifecycleCallback // Register for the callback application .registerActivityLifecycleCallbacks(object: Application.ActivityLifecycleCallbacks{ override
fun onActivityCreated(activity: Activity?, bundle: Bundle?) {} ... }) -
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) { .. } ... }); } } -
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) { .. } ... }); } } -
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) { .. } ... }); } } -
ProcessLifecycleOwner // Source code class EmptyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { @Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { //Empty method body } ... } -
ProcessLifecycleOwner // Source code class EmptyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { @Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { //Empty method body } ... } -
LifecycleRegistry Implementation of Lifecycle that can handle multiple observers //
Source code public class LifecycleRegistry extends Lifecycle { ... } -
LifecycleRegistry Implementation of Lifecycle that can handle multiple observers //
Source code public class LifecycleRegistry extends Lifecycle { ... } However, you need to dispatch the events yourself. -
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) } } -
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) } } -
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) } } -
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) } } -
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) } } -
LifecycleRegistry val myLifecycleOwner = MyLifecycleOwner() // Missing myLifecycleObserver // Add
lifecycle observer myLifecycleOwner.lifecycle.addObserver(myLifecycleObserver) // Remove lifecycle observer myLifecycleOwner.lifecycle.removeObserver(myLifecycleObserver) -
LifecycleObserver An interface for observing a Lifecycle // Source code
public interface LifecycleObserver { // Empty } -
LifecycleObserver dependencies { def lifecycle_version = "1.1.1" // For Annotation
Support annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" ... } -
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() {} } -
LifecycleObserver val myLifecycleOwner = MyLifecycleOwner() // Add lifecycle observer myLifecycleOwner.lifecycle.addObserver(myLifecycleObserver)
// Remove lifecycle observer myLifecycleOwner.lifecycle.removeObserver(myLifecycleObserver) -
LifecycleObserver val myLifecycleOwner = MyLifecycleOwner() val myLifecycleObserver = MyLifecycleObserver() //
Add lifecycle observer myLifecycleOwner.lifecycle.addObserver(myLifecycleObserver) // Remove lifecycle observer myLifecycleOwner.lifecycle.removeObserver(myLifecycleObserver) -
LifecycleObserver val myLifecycleOwner = MyLifecycleOwner() val myLifecycleObserver = MyLifecycleObserver() //
Add lifecycle observer myLifecycleOwner.lifecycle.addObserver(myLifecycleObserver) // Remove lifecycle observer myLifecycleOwner.lifecycle.removeObserver(myLifecycleObserver) -
DefaultLifecycleObserver Callback interface for listening to LifecycleOwner state changes. Recommended
over annotations if using Java 8 language. -
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" ... } -
DefaultLifecycleObserver // Source code public interface DefaultLifecycleObserver extends FullLifecycleObserver {
@Override default void onCreate(@NonNull LifecycleOwner owner) { ... } ... @Override default void onDestroy(@NonNull LifecycleOwner owner) { ... } } -
DefaultLifecycleObserver // Source code interface FullLifecycleObserver extends LifecycleObserver { void
onCreate(LifecycleOwner owner); void onStart(LifecycleOwner owner); ... void onDestroy(LifecycleOwner owner); } -
DefaultLifecycleObserver class MyLifecycleObserver : DefaultLifecycleObserver { override fun onCreate(owner: LifecycleOwner)
{} ... override fun onDestroy(owner: LifecycleOwner) {} } -
LiveData A lifecycle aware base class for encapsulating loading data
Lightweight implementation of Observer pattern -
LiveData dependencies { def lifecycle_version = "1.1.1" // For LiveData
implementation "android.arch.lifecycle:livedata:$lifecycle_version" ... } -
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() {...} } -
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() {...} } -
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() {...} } -
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() {...} } -
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 } -
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)) } ... } } -
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)) } ... } } -
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) } } -
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) } } -
LiveData val mySensorLiveData = MySensorLiveData(this) // Observe for values mySensorLiveData.observe(this,
Observer<Float>{ floatVal -> // Update the UI }) -
ViewModel - Hold & manage UI related data in Lifecycle
conscious way - Survives configuration changes - Prevents unnecessary reloading of data -
ViewModel dependencies { def lifecycle_version = "1.1.1" // For ViewModel
implementation "android.arch.lifecycle:viewmodel:$lifecycle_version" ... } -
ViewModel // Source code public abstract class ViewModel { //
Called when ViewModel is destroyed protected void onCleared() { } } -
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 } } -
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 } } -
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 } } -
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 } } -
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 } } -
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 } } -
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