Lifecycle components include: Lifecycle, LiveData, ViewModle, other extension components (Process, Service), etc. This article begins with a detailed analysis of Lifecycle.
The androidX.Lifecycle component package is shown below:
Lifecycle issues summary
- What is the Lifecycle
- How can Lifecycle be used to observe host state
- How will Lifecycle distribute the status of the Lifecycle
- How does Fragment implement Lifecycle
- How does an Activity implement Lifecycle
- How does an Application implement Lifecycle
- How does a Service implement Lifecycle
- How does a View View View host Lifecycle
- How are the dependent libraries involved in Lifecycle divided
- Lifecycle implementations observe host state in several ways
- Why is annotation + reflection/generated code obsolete again
- Why is Activity lifecycle distribution implemented through ReportFragment
- Lifecycle Event and State
- Register an observer in the onResume method to see if other lifecycle callbacks can be observed
- How are events and States synchronized during host State distribution
2. What is Lifecycle
Lifecycle is a Lifecycle Aware component that is Aware of changes in the Lifecycle of the host. The observable host components currently provided in Android include activities/fragments/services/Applications, etc. In addition to the observable host built into the Jetpack component LifeCycle can be implemented by LifeCycle itself. For example, activities in the SDK are not implemented LifeCycle and can be self-timed to meet business needs.
Lifecycle’s core implementation idea is the observer model. The Activity/Fragment component in Jetpack has access to the code for the observed part of Lifecycle. We simply implement our own observer and register our observer in the Activity/Fragment component to listen for changes in life cycle events.
The LifecycleOwner interface is implemented for Fragments and Activities in support library 26.1.0 and later.
Lifecycle components can be used to separate the code from the Lifecycle methods of activities and fragments. Lifecycle components can be used to separate the code from the Lifecycle methods of activities and fragments. This helps developers write clean and maintainable code.
The Observer Design Pattern is also known as the publish-subscribe Design Pattern.
The observer pattern defines a one-to-many dependency between objects. When an object’s state changes, all dependent objects are notified and automatically updated. In general, the dependent object is called an Observable and the dependent object is called an Observer.
Observer mode belongs to behavioral design mode. The purpose of behavioral design mode is to decouple different behavioral codes. Specifically, observer mode is to decouple the codes of the observer and the observed.
The implementation of the Observer pattern is generally divided into two roles: Observable and Observer, both of which provide an abstraction layer.
The abstraction layer of the observed part is generally abstract class, which provides the necessary abstraction methods as well as the reuse logic of adding, deleting, etc.
The observer part’s abstraction layer is typically a Single Abstract Method (SAM) interface that the observer can implement to make updates.
How does Lifecycle incorporate the observer pattern into the Lifecycle awareness of Activity and Fragment components
Lifecycle does not implement the observed in the traditional way of directly inheriting abstract classes, but rather encapsulates the observed logic code in a LifecycleRegistry class using a delegate-like pattern. LifecycleRegistry is the true observer that manages the addition, removal, storage, distribution, and more of all observers. LifecycleRegistry implements the lifecycle awareness of the client class by performing specific distribution operations when lifecycle events are generated by the client Activity/Fragment.
This has the advantage of adhering to a single principle, making it easier to reuse by code on the observer side without breaking the inheritance structure of the Activity/Fragment component.
3. What does Lifecycle have
Android X. Lifecycle group. Understand what Lifecycle has to offer. Lifecycle module implements observer pattern-related code itself
lifecycle-common lifecycle-common-java8 lifecycle-compiler lifecycle-runtime lifecycle-runtime-ktx lifecycle-runtime-ktx- lint lifecycle-runtime-testing |
lifecycle-livedata lifecycle-livedata-core lifecycle-livedata-core-ktx lifecycle-livedata-core-ktx-lint lifecycle-livedata-core-truth lifecycle-livedata-ktx lifecycle-reactivestreams lifecycle-reactivestreams-ktx |
lifecycle-viewmodel lifecycle-viewmodel-compose lifecycle-viewmodel-ktx lifecycle-viewmodel-savedstate |
lifecycle-process lifecycle-service lifecycle-extensions |
---|---|---|---|
Lifecycle related | Livedata related | The viewmodel related | Related to other extension components |
Common-java 8 has been abandoned | – | – | The Extensions coupling weight has been deprecated |
Take a look at the dependencies between several of the core components
Add dependencies for Lifecycle as needed at development time
def lifecycle_version = "2.4.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// ViewModel utilities for Compose
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
Copy the code
The dependencies of other components on Lifecycle
implementation 'androidx. Core: the core - KTX: 1.7.0'
Copy the code
The core – the core KTX API
The core lifecycle – the runtime API
Lifecycle – lifecycle – common runtime API
implementation 'androidx. Appcompat: appcompat: 1.3.0'
Copy the code
Appcompat API core, activity, fragment
The activity API includes core, lifecycle- Runtime, lifecycle- viewModel, lifecycle- viewModel-savedState
Fragment API includes core, activity, lifecycle- Livedata-core, lifecycle- viewModel, lifecycle- viewModel-savedState
Lifecycle – lifecycle – common runtime API
Lifecycle – livedata – core API lifecycle – livedata
So, by default, every new Android project we build will provide core-KTX, AppCompat and they will indirectly rely on lifecycle components
Lifecycle system components that depend indirectly on AppCompat
Lifecycle system components that depend indirectly on Core-KTX
4. Application of life-cycle aware components
Life-cycle-aware components make it easier to manage the lifecycle in a variety of situations. Here are a few examples:
- Toggle between coarse-grained and fine-grained position updates. Use lifecycle aware components to enable fine-grained location updates when the location application is visible and switch to coarse-grained updates when the application is in the background.
- Stop and start video buffering. Use lifecycle aware components to start video buffering as soon as possible, but delay playback until the application is fully started. In addition, lifecycle aware components can be used to terminate buffering after application destruction.
- Start and stop network connections. Life-cycle aware components enable real-time updates (streaming) of network data when the application is in the foreground and automatically pauses when the application is in the background.
- Pause and resume animation drawable resources. Life-cycle-aware components allow you to pause animatable drawable resources while the application is in the background and restore drawable resources after the application is in the foreground.
- The Handler message was removed.
- Attach&detach View for Presenter.
- Add lifecycle awareness capabilities to other three-party libraries, such as RxJava, EventBus, etc.
5. How does Lifecycle work
5.1 Summary of observer usage
The following uses of Lifecycle are hosted by an Activity or Fragment for example.
- Method 1: runtime annotation + reflection
- Custom LifecycleObserver, annotate Lifecycle methods with OnLifecycleEvent annotation and Lifecycle.Event enumeration;
- Register the defined observer in the host Activity or Fragment with the getLifecycle().addobServer () method;
- Method 2: Compile-time annotations + generate helper classes (XXX_LifecycleAdapter)
- Add the annotation processor component: lifecycle- Compiler
- Custom LifecycleObserver, annotate Lifecycle methods with OnLifecycleEvent annotation and Lifecycle.Event enumeration;
- Register the defined observer in the host Activity or Fragment with the getLifecycle().addobServer () method;
- Method 3: Implement FullLifecycleObserver (non-public method, you can implement one yourself)
- Custom FullLifecycleObserver observer, FullLifecycleObserver is a common interface that needs to implement all lifecycle methods defined in it;
- Register the defined observer in the host Activity or Fragment with the getLifecycle().addobServer () method;
- Way 4: Implement LifecycleEventObserver(recommended)
- Customize LifecycleEventObserver observer to determine Lifecycle method callbacks by implementing onStateChanged(LifecycleOwner,Lifecycle.Event) method;
- Register the defined observer in the host Activity or Fragment with the getLifecycle().addobServer () method;
- Option 5: Implement DefaultLifecycleObserver (recommended)
- Custom DefaultLifecycleObserver observer, DefaultLifecycleObserver through the Java default keyword are implemented in the method body, so only need to achieve the required declaration of late method;
- Register the defined observer in the host Activity or Fragment with the getLifecycle().addobServer () method;
DefaultLifecycleObserver The default keyword in the interface
Methods decorated with the default keyword that can add new functional methods to an interface must provide a method body and ensure that previous classes compatible with implementing the interface do not implement the methods individually in subclasses of the interface. It can be implemented on demand
Default is used when you need to add methods to an interface, but there are too many subclasses, or the subclasses are not necessary. For example, the List interface in java8 added the sort() method
/ / @ since 1.8 public interface List<E> extends Collection<E> {...default void sort(Comparator<? super E> c) { Object[] a = this.toArray(); Arrays.sort(a, (Comparator) c); ListIterator<E> i = this.listIterator(); for(Object e : a) { i.next(); i.set((E) e); }}Copy the code
5.2 Observe Activity Lifecycle
class MyLifecycleActivityObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
Log.d("MyLifecycleActivity"."onStart")}override fun onStop(owner: LifecycleOwner) {
super.onStop(owner)
Log.d("MyLifecycleActivity"."onStop")}}Copy the code
class MyLifecycleActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?). {
addLifecycleObserver()
}
private fun addLifecycleObserver(a) {
lifecycle.addObserver(MyLifecycleActivityObserver())
}
}
Copy the code
5.3 Observing the SDK Activity Lifecycle
class MySdkActivity : Activity(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
addLifecycleObserver()
MySDKFragment.inject(this)}private fun addLifecycleObserver(a) {
lifecycle.addObserver(MySDKActivityObserver())
}
override fun getLifecycle(a): Lifecycle {
return lifecycleRegistry
}
}
class MySDKActivityObserver : DefaultLifecycleObserver {
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
Log.i("SDKActivity"."Observer onPause")}override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
Log.i("SDKActivity"."Observer onResume")}}Copy the code
5.4 Observing Fragment Lifecycle
class MyLifecycleFragmentObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectListener(a) {
Log.i("MyLifecycleFragment"."onResume")}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun disconnectListener(a) {
Log.i("MyLifecycleFragment"."onPause")}}Copy the code
class MyLifecycleFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
addLifecycleObserver()
}
private fun addLifecycleObserver(a) {
lifecycle.addObserver(MyLifecycleFragmentObserver())
}
}
Copy the code
5.5 Observing the SDK Fragment Lifecycle
class MySDKFragment : Fragment(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
addLifecycleObserver()
}
private fun addLifecycleObserver(a) {
lifecycle.addObserver(MySDKFragmentObserver())
}
companion object {
fun inject(activity: Activity) {
val manager = activity.fragmentManager
if (manager.findFragmentByTag("MyLifecycleFragment") = =null) {
manager.beginTransaction()
.add(MySDKFragment(), "MyLifecycleFragment")
.commit()
manager.executePendingTransactions()
}
}
}
override fun onResume(a) {
super.onResume()
Log.i("SDKFragment"." onResume")
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
}
override fun onPause(a) {
super.onPause()
Log.i("SDKFragment"." onPause")
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
}
override fun getLifecycle(a): Lifecycle {
return lifecycleRegistry
}
}
class MySDKFragmentObserver : DefaultLifecycleObserver {
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
Log.i("SDKFragment"."Observer onPause")}override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
Log.i("SDKFragment"."Observer onResume")}}Copy the code
5.6 Observing Service Lifecycle
public class MyLifecycleServiceObserver implements LifecycleEventObserver {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_START) {
Log.d("MyLifecycleService"."onStart()");
} else if (event == Lifecycle.Event.ON_DESTROY) {
Log.d("MyLifecycleService"."onDestroy()"); }}}Copy the code
public class MyLifecycleService extends LifecycleService {
publicMyLifecycleService() { getLifecycle().addObserver(new MyLifecycleServiceObserver()); }}Copy the code
5.7 Observing Application Lifecycle
class MyLifecycleApplicationObserver(private val application: Application) :
LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun appInResumeState(a) {
Toast.makeText(application, "In Foreground", Toast.LENGTH_LONG).show()
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun appInPauseState(a) {
Toast.makeText(application, "In Background", Toast.LENGTH_LONG).show()
}
}
Copy the code
public class MyLifecycleApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
// Get ProcessLifecycleOwner
ProcessLifecycleOwner.get().getLifecycle().addObserver(new MyLifecycleApplicationObserver(this)); }}Copy the code
5.8 View Lifecycle
class MyLifecycleView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : View(context, attrs, defStyle) {
init {
addOnAttachStateChangeListener(object : OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View?). {
Log.d("MyLifecycleView"."onViewAttachedToWindow") findViewTreeLifecycleOwner()? .lifecycle ? .addObserver(object : LifecycleEventObserver {
override fun onStateChanged(
source: LifecycleOwner,
event: Lifecycle.Event
) {
Log.d("MyLifecycleView"."OnStateChanged: source:$source, event: $event")}}}override fun onViewDetachedFromWindow(v: View?). {
Log.d("MyLifecycleView"."onViewDetachedFromWindow")}})}}Copy the code
5.9 Execution sequence of various types of observers
- DefaultLifecycleObserver All methods will be called before the lifecycle callback method for [LifecycleOwner] is called, and it is important to note the timing of the Fragment lifecycle callback.
- LifecycleEventObserver onStateChanged method is called when the state transition event occurs.
- If a class implements both DefaultLifecycleObserver and LifecycleEventObserver, the DefaultLifecycleObserver method is first called, Then call LifecycleEventObserver. OnStateChanged (LifecycleOwner, Lifecycle. The Event) method.
- If a class implements this interface and also uses the OnLifecycleEvent annotation, the annotation will be ignored.
D/Life_Owner: onCreate
D/Life_Observer: onCreate
D/Life_Observer: onStateChanged,event:ON_CREATE
D/Life_Owner: onStart
D/Life_Observer: onStart
D/Life_Observer: onStateChanged,event:ON_START
D/Life_Owner: onResume
D/Life_Observer: onResume
D/Life_Observer: onStateChanged,event:ON_RESUME
D/Life_Observer: onPause
D/Life_Observer: onStateChanged,event:ON_PAUSE
D/Life_Owner: onPause
D/Life_Observer: onStop
D/Life_Observer: onStateChanged,event:ON_STOP
D/Life_Owner: onStop
D/Life_Observer: onDestroy
D/Life_Observer: onStateChanged,event:ON_DESTROY
D/Life_Owner: onDestroy
Copy the code
An observer is registered with the Activity’s onPause method and when the host executes onPause the observer will start onCreate until the current state is aligned. Lifecycle does synchronization and alignment inside Lifecycle.
D/Life_Owner: onCreate
D/Life_Owner: onStart
D/Life_Owner: onResume
D/Life_Observer: onCreate
D/Life_Observer: onStateChanged,event:ON_CREATE
D/Life_Observer: onStart
D/Life_Observer: onStateChanged,event:ON_START
D/Life_Owner: onPause
D/Life_Observer: onStop
D/Life_Observer: onStateChanged,event:ON_STOP
D/Life_Owner: onStop
D/Life_Observer: onDestroy
D/Life_Observer: onStateChanged,event:ON_DESTROY
D/Life_Owner: onDestroy
Copy the code
Lifecycle minimal prototyping
6.1 Code to achieve the minimum prototype
Observed part
// Abstract the interface layer
abstract class Lifecycle {
abstract fun addObserver(observer: LifecycleObserver)
abstract fun removeObserver(observer: LifecycleObserver)
enum class State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
}
enum class Event { ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_ANY; }}/ / the entrusted party
class LifecycleRegistry(private val lifecycleOwner: LifecycleOwner) : Lifecycle() {
private var lifecycleObserver: LifecycleObserver? = null
private val lifecycleObservers = arrayListOf<LifecycleObserver>()
override fun addObserver(observer: LifecycleObserver) {
lifecycleObservers.add(observer)
lifecycleObserver = observer
}
override fun removeObserver(observer: LifecycleObserver) {
lifecycleObservers.remove(observer)
}
fun handleLifecycleEvent(event: Event) {
lifecycleObservers.forEach {
if (it is LifecycleEventObserver) {
it.onStateChanged(lifecycleOwner, event)
}
}
}
}
Copy the code
Observer part
interface LifecycleObserver {}
interface LifecycleEventObserver : LifecycleObserver {
fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event)
}
interface DefaultLifecycleObserver : FullLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {}
override fun onStart(owner: LifecycleOwner) = Unit
override fun onResume(owner: LifecycleOwner) {}
override fun onPause(owner: LifecycleOwner) {}
override fun onStop(owner: LifecycleOwner) {}
override fun onDestroy(owner: LifecycleOwner){}}Copy the code
Test the observed part
class Activity : LifecycleOwner {
private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
init {
lifecycleRegistry.addObserver(ActivityObserver())
}
override fun getLifecycle(a): Lifecycle = lifecycleRegistry
fun onStart(a) {
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
}
fun onStop(a) {
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
}
}
Copy the code
Test observer section
class ActivityObserver : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
println("source: $source, event: $event ")}}// Run the test
fun main(a) {
val app = Activity()
app.onStart()
app.onStop()
}
Copy the code
Lifecycle implementation principle
Implementation of 7.1 Fragment
The Fragment component in Jetpack has been observed as part of the interface LifecycleOwner
/ / androidx fragments. The app. Is implemented LifecycleOwner fragments
public class Fragment implements
ComponentCallbacks.OnCreateContextMenuListener.LifecycleOwner.ViewModelStoreOwner.HasDefaultViewModelProviderFactory.SavedStateRegistryOwner.ActivityResultCaller {... }LifecycleOwner exposes the host's lifecycle management class by overriding the getLifecycle method
@Override
@NonNull
public Lifecycle getLifecycle(a) {
return mLifecycleRegistry;
}
LifecycleRegistry mLifecycleRegistry;
The LifecycleRegistry trustee is initialized in the constructor
public Fragment(a) initLifecycle(a); }private void initLifecycle(a) {
mLifecycleRegistry = new LifecycleRegistry(this);
}
// When a lifecycle event occurs, the handler distributes the event to all observers through the delegate class
void performCreate(Bundle savedInstanceState) {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
Copy the code
The Fragment lifecycle awareness implementation is simple and delegated to mLifecycleRegistry
7.2 the Activity implementation
/ / androidx.core.app.Com ponentActivity, @ hide, not external use, only do the Lifecycle and KeyEvent encapsulation
public class ComponentActivity extends Activity implements
LifecycleOwner.KeyEventDispatcher.Component {... }Copy the code
/ / androidx.activity.Com ponentActivity, features more than + integrates Jitpack other components, such as Lifecycle, the ViewModel, etc
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware.LifecycleOwner.ViewModelStoreOwner.HasDefaultViewModelProviderFactory.SavedStateRegistryOwner.OnBackPressedDispatcherOwner.ActivityResultRegistryOwner.ActivityResultCaller {
LifecycleOwner exposes the host's lifecycle management class by overriding the getLifecycle method
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
public Lifecycle getLifecycle(a) {
return mLifecycleRegistry;
}
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ReportFragment is a Fragment inherited from the SDK, so it can be compatible with the SDK activities and declaration cycle awareness
ReportFragment.injectIfNeededIn(this);
if(mContentLayoutId ! =0) { setContentView(mContentLayoutId); }}}Copy the code
/ / androidx. Fragments. App. FragmentActivity, the use of the above features + simplified fragments, such as: FragmentManager
public class FragmentActivity extends ComponentActivity implements
ActivityCompat.OnRequestPermissionsResultCallback.ActivityCompat.RequestPermissionsRequestCodeValidator {... }Copy the code
/ / androidx appcompat. App. Simplify AppCompatActivity above features + Material design, such as theme, diablo, navigation, etc
public class AppCompatActivity extends FragmentActivity implements
AppCompatCallback.TaskStackBuilder.SupportParentable.ActionBarDrawerToggle.DelegateProvider {... }Copy the code
Androidx. Activity ComponentActivity is the top activity base class for AndroidX or Jetpack. As you can see, LifecycleOwner is already implemented in the ComponentActivity class, so as with fragments, you delegate the observer-specific logic to LifecycleRegistry.
But we don’t see the distribution operations performed by LifecycleRegistry in the callback method of the ComponentActivity lifecycle. We see in the onCreate method ReportFragment. InjectIfNeededIn (this); ReportFragment is an inherited Fragment from the SDK, so it can be compatible with the SDK for activities to realize the declaration period awareness.
ReportFragment
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
/ / on the 29 + API, to directly register registerActivityLifecycleCallbacks callback method in the Activity of acquiring the Activity's lifecycle callback.
LifecycleCallbacks.registerIn(activity);
}
Prior to API 29, both the process host ProcessLifecycleOwner and ProcessLifecycleOwner retrieve the Activity's lifecycle callback indirectly by inserting an empty Fragment.
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(newReportFragment(), REPORT_FRAGMENT_TAG).commit(); manager.executePendingTransactions(); }}//29 The mode of distribution above
@RequiresApi(29)
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
static void registerIn(Activity activity) {
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
}
@Override
public void onActivityPostCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
dispatch(activity, Lifecycle.Event.ON_CREATE);
}
@Override
public void onActivityPostStarted(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_START);
}
@Override
public void onActivityPreDestroyed(@NonNull Activity activity) {
dispatch(activity, Lifecycle.Event.ON_DESTROY);
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {}}//Fragment declares that the interval method is triggered
@Override
public void onStart(a) {
super.onStart();
dispatchStart(mProcessListener);// Process 29 the following is required
dispatch(Lifecycle.Event.ON_START);// Distribute Avtivity below 29
}
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) { dispatch(getActivity(), event); }}static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); // 29 The following final distribution method}}}Copy the code
In general, activities notify subscribers of lifecycle methods in a different way than fragments do, delegating responsibility directly to mLifecycleRegistry in lifecycle callbacks. The mode of Activity appears to be complex, and the main reason for the complexity is that it has to be done for compatibility with lower versions and portability.
According to the SDK version, there are two ways. Greater than or equal to 29 (10) Androi above is through the activity. The registerActivityLifecycleCallbacks (new Application. ActivityLifecycleCallbacks) The method registers the lifecycle callback method to get the Activity’s lifecycle callback, and then notifies subscribers in the callback via mLifecycleRegistry.
29(Androi 10) The following is a callback to an Activity’s lifecycle that is obtained indirectly by inserting an empty Fragment, and then notifies subscribers in the callback via mLifecycleRegistry.
7.3 LifecycleRegistry- The real being observed
LifecycleRegistry is commonly used by Fragments and Activity components. You can also use it directly if you have a need to customize LifecycleOwner.
LifecycleRegistry can be thought of as a life-cycle aware trustee for fragments and activities. All the observed logic is implemented here.
A constructor
private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
mLifecycleOwner = new WeakReference<>(provider); // The host class is wrapped by weak references
mState = INITIALIZED;
mEnforceMainThread = enforceMainThread;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
Copy the code
The host class is wrapped by weak references. When GC is used, the host class will be reclaimed to avoid memory leaks. Every time the host is fetched, it will be nulled first.
Add observer
// Add an observer to LifecycleRegistry from the host
lifecycle.addObserver(MyLifecycleActivityObserver())
Copy the code
// Cache the observer's data container
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
// Encapsulate the distribution event
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
// Get status based on events
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event); / / distribute
mState = newState; // advance one state}}@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// The initial state is: mState = INITIALIZED;
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// Wrap the observer
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
// It was cached before
if(previous ! =null) {
return;
}
// The host is GC
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
//
booleanisReentrance = mAddingObserverCounter ! =0 || mHandlingEvent;
State targetState = calculateTargetState(observer);// Calculate the current state of the host
mAddingObserverCounter++;
// Synchronize to the current state of the host, such as the observer registered in the onResume method. The previous lifecycle method is also called back
while ((statefulObserver.mState.compareTo(targetState) < 0 // Compare the state, whether it is less than the state of the host. Enumeration classes are compared according to ordinal ordinal
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
// Move one lifecycle method forward, on_create-on_start-on_resume knows to align the host
final Event event = Event.upFrom(statefulObserver.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + statefulObserver.mState);
}
// The backward lifecycle method is distributed each time the lifecycle method is moved forward
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if(! isReentrance) {// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
@Nullable
public static Event upFrom(@NonNull State state) {
switch (state) {
case INITIALIZED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
default:
return null; }}Copy the code
Forward synchronization: Events are first pushed according to the status. Distribution deduces the status according to the events, and then updates the status.
Suppose the host is an observer registered in the onResume method, what should his synchronization flow look like?
The observer will eventually be subjected to onCreate-onStart-onRsume three return methods.
The State and the Event
The correspondence between State and Event in Lifecycle will be analyzed using the flow diagram provided by Lifecycle.
Lifecycle interface provides two enumerations: State for host State and Event for host Lifecycle events.
enum class State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
}
enum class Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY;
}
Copy the code
Two processes: forward and back
Progress: the INITIALIZED – ON_CREATE – CREATED – ON_START – STARTED – ON_RESUME – RESUMED
Back: RESUMED – ON_PAUSE – STARTED – ON_STOP – CREATED – ON_DESTROY – DESTROYED
States are nodes in a graph, and events can be thought of as edges between these nodes.
Get state by event
public State getTargetState(a) {
switch (this) {
case ON_CREATE:
case ON_STOP:
return State.CREATED;
case ON_START:
case ON_PAUSE:
return State.STARTED;
case ON_RESUME:
return State.RESUMED;
case ON_DESTROY:
return State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
Copy the code
If the diagram above doesn’t make sense, look at the one below to clear up the correspondence.
Inform observer
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
// Deduce the state from the event, then perform the move
moveToState(event.getTargetState());
}
// Determine the condition
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if(mHandlingEvent || mAddingObserverCounter ! =0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
private void sync(a) {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while(! isSynced()) { mNewEventOccurred =false;
// mState represents the state of the host, smaller than that of the observer is the hind leg flow onpause-onstop
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
// Forward flow
if(! mNewEventOccurred && newest ! =null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
// the conditions of the while loop are synchronized
private boolean isSynced(a) {
if (mObserverMap.size() == 0) {
return true;
}
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
Copy the code
Forward and hind legs
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
while(descendingIterator.hasNext() && ! mNewEventOccurred) { Map.Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next(); ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = Event.downFrom(observer.mState); // loop back
if (event == null) {
throw new IllegalStateException("no event down from " + observer.mState);
}
pushParentState(event.getTargetState());
// Distribute lifecycle methodsobserver.dispatchEvent(lifecycleOwner, event); popParentState(); }}}public static Event downFrom(@NonNull State state) {
switch (state) {
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
default:
return null; }}private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while(ascendingIterator.hasNext() && ! mNewEventOccurred) { Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next(); ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
final Event event = Event.upFrom(observer.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + observer.mState);
}
// Distribute lifecycle methodsobserver.dispatchEvent(lifecycleOwner, event); popParentState(); }}}public static Event upFrom(@NonNull State state) {
switch (state) {
case INITIALIZED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
default:
return null; }}Copy the code
Distinguish between observer types -Lifecycling
Conclusion is that no matter which way the observer through the adapter pattern into LifecycleEventObserver type, when the distribution of events, as long as the executive mLifecycleObserver. OnStateChanged (the owner, the event); Various types of Lifecycling fit will be distributed accordingly.
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
Copy the code
The adapter pattern transformation Observer is wrapped as Life Cleevening Server
static LifecycleEventObserver lifecycleEventObserver(Object object) {
boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
// Implement this interface
if (isLifecycleEventObserver && isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
(LifecycleEventObserver) object);
}
if (isFullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
}
if (isLifecycleEventObserver) {
return (LifecycleEventObserver) object;
}
// Implementation of LifecycleObserver + annotations, the latest version has been deprecated, there are problems with slow compilation, low reflection efficiency
finalClass<? > klass = object.getClass();int type = getObserverConstructorType(klass); // Check whether APT is used by reflecting whether the generated Adapter class has ClassNotFoundException
if (type == GENERATED_CALLBACK) { // Use apt mode
//GeneratedAdapter is the interface that generates the class
List<Constructor<? extends GeneratedAdapter>> constructors =
sClassToAdapters.get(klass);
if (constructors.size() == 1) {
GeneratedAdapter generatedAdapter = createGeneratedAdapter(
constructors.get(0), object);
return new SingleGeneratedAdapterObserver(generatedAdapter);
}
GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
for (int i = 0; i < constructors.size(); i++) {
adapters[i] = createGeneratedAdapter(constructors.get(i), object);
}
return new CompositeGeneratedAdaptersObserver(adapters);
}
return new ReflectiveGenericLifecycleObserver(object); // Runtime reflection
}
Copy the code
The adapter is converted to lifeccleeventobServer type
class FullLifecycleObserverAdapter implements LifecycleEventObserver {
private final FullLifecycleObserver mFullLifecycleObserver;
private final LifecycleEventObserver mLifecycleEventObserver;
FullLifecycleObserverAdapter(FullLifecycleObserver fullLifecycleObserver,
LifecycleEventObserver lifecycleEventObserver) {
mFullLifecycleObserver = fullLifecycleObserver;
mLifecycleEventObserver = lifecycleEventObserver;
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
switch (event) {
case ON_CREATE:
mFullLifecycleObserver.onCreate(source);
break;
case ON_START:
mFullLifecycleObserver.onStart(source);
break;
case ON_RESUME:
mFullLifecycleObserver.onResume(source);
break;
case ON_PAUSE:
mFullLifecycleObserver.onPause(source);
break;
case ON_STOP:
mFullLifecycleObserver.onStop(source);
break;
case ON_DESTROY:
mFullLifecycleObserver.onDestroy(source);
break;
case ON_ANY:
throw new IllegalArgumentException("ON_ANY must not been send by anybody");
}
if(mLifecycleEventObserver ! =null) { mLifecycleEventObserver.onStateChanged(source, event); }}}Copy the code
The way APT is generated is converted to the Life Cleeve Server type
class SingleGeneratedAdapterObserver implements LifecycleEventObserver {
private final GeneratedAdapter mGeneratedAdapter;
SingleGeneratedAdapterObserver(GeneratedAdapter generatedAdapter) {
mGeneratedAdapter = generatedAdapter;
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
mGeneratedAdapter.callMethods(source, event, false.null);
mGeneratedAdapter.callMethods(source, event, true.null); }}class CompositeGeneratedAdaptersObserver implements LifecycleEventObserver {
private final GeneratedAdapter[] mGeneratedAdapters;
CompositeGeneratedAdaptersObserver(GeneratedAdapter[] generatedAdapters) {
mGeneratedAdapters = generatedAdapters;
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
MethodCallsLogger logger = new MethodCallsLogger();
for (GeneratedAdapter mGenerated: mGeneratedAdapters) {
mGenerated.callMethods(source, event, false, logger);
}
for (GeneratedAdapter mGenerated: mGeneratedAdapters) {
mGenerated.callMethods(source, event, true, logger); }}}Copy the code
7.4 Application implementation
registered
class MyLifecycleApplication : MultiDexApplication(a){
override fun onCreate(a) {
super.onCreate()
// Get ProcessLifecycleOwner
ProcessLifecycleOwner.get().lifecycle.addObserver(MyLifecycleApplicationObserver(this))}}Copy the code
Through the startup initialization ProcessLifecycleInitializer
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge" >
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />
</provider>
Copy the code
ProcessLifecycleInitializer
public final class ProcessLifecycleInitializer implements Initializer<LifecycleOwner> {
@NonNull
@Override
public LifecycleOwner create(@NonNull Context context) {
LifecycleDispatcher.init(context);
ProcessLifecycleOwner.init(context);
return ProcessLifecycleOwner.get();
}
@NonNull
@Override
publicList<Class<? extends Initializer<? >>> dependencies() {returnCollections.emptyList(); }}Copy the code
ProcessLifecycleOwner is used for changes in the life cycle of today’s Application
public class ProcessLifecycleOwner implements LifecycleOwner {
@VisibleForTesting
static final long TIMEOUT_MS = 700; //mls
// ground truth counters
private int mStartedCounter = 0;
private int mResumedCounter = 0;
private boolean mPauseSent = true;
private boolean mStopSent = true;
private Handler mHandler;
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
private Runnable mDelayedPauseRunnable = new Runnable() {
@Override
public void run(a) { dispatchPauseIfNeeded(); dispatchStopIfNeeded(); }}; ActivityInitializationListener mInitializationListener =new ActivityInitializationListener() {
@Override
public void onCreate(a) {}@Override
public void onStart(a) {
activityStarted();
}
@Override
public void onResume(a) { activityResumed(); }};private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();
/**
* The LifecycleOwner for the whole application process. Note that if your application
* has multiple processes, this provider does not know about other processes.
*
* @return {@link LifecycleOwner} for the whole application.
*/
@NonNull
public static LifecycleOwner get(a) {
return sInstance;
}
static void init(Context context) {
sInstance.attach(context);
}
void activityStarted(a) {
mStartedCounter++;
if (mStartedCounter == 1 && mStopSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
mStopSent = false; }}void activityResumed(a) {
mResumedCounter++;
if (mResumedCounter == 1) {
if (mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mPauseSent = false;
} else{ mHandler.removeCallbacks(mDelayedPauseRunnable); }}}void activityPaused(a) {
mResumedCounter--;
if (mResumedCounter == 0) { mHandler.postDelayed(mDelayedPauseRunnable, TIMEOUT_MS); }}void activityStopped(a) {
mStartedCounter--;
dispatchStopIfNeeded();
}
void dispatchPauseIfNeeded(a) {
if (mResumedCounter == 0) {
mPauseSent = true; mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE); }}void dispatchStopIfNeeded(a) {
if (mStartedCounter == 0 && mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
mStopSent = true; }}private ProcessLifecycleOwner(a) {}@SuppressWarnings("deprecation")
void attach(Context context) {
mHandler = new Handler();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
Application app = (Application) context.getApplicationContext();
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@RequiresApi(29)
@Override
public void onActivityPreCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
// We need the ProcessLifecycleOwner to get ON_START and ON_RESUME precisely
// before the first activity gets its LifecycleOwner started/resumed.
// The activity's LifecycleOwner gets started/resumed via an activity registered
// callback added in onCreate(). By adding our own activity registered callback in
// onActivityPreCreated(), we get our callbacks first while still having the
// right relative order compared to the Activity's onStart()/onResume() callbacks.
activity.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@Override
public void onActivityPostStarted(@NonNull Activity activity) {
activityStarted();
}
@Override
public void onActivityPostResumed(@NonNull Activity activity) { activityResumed(); }}); }@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
// Only use ReportFragment pre API 29 - after that, we can use the
// onActivityPostStarted and onActivityPostResumed callbacks registered in
// onActivityPreCreated()
if (Build.VERSION.SDK_INT < 29) { ReportFragment.get(activity).setProcessListener(mInitializationListener); }}@Override
public void onActivityPaused(Activity activity) {
activityPaused();
}
@Override
public void onActivityStopped(Activity activity) { activityStopped(); }}); }@NonNull
@Override
public Lifecycle getLifecycle(a) {
returnmRegistry; }}Copy the code
LifecycleDispatcher is used to inject ReportFragment for all activities, so that later activities in the SDK can achieve lifecycle observable capabilities simply by implementing LifecycleOwner.
class LifecycleDispatcher {
private static AtomicBoolean sInitialized = new AtomicBoolean(false);
static void init(Context context) {
if (sInitialized.getAndSet(true)) {
return;
}
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.injectIfNeededIn(activity);
}
@Override
public void onActivityStopped(Activity activity) {}@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}}private LifecycleDispatcher(a) {}}Copy the code
7.5 the Service implementation
class MyLifecycleService : LifecycleService(a){
init {
lifecycle.addObserver(MyLifecycleServiceObserver())
}
}
Copy the code
LifecycleService
public class LifecycleService extends Service implements LifecycleOwner {
private final ServiceLifecycleDispatcher mDispatcher = new ServiceLifecycleDispatcher(this);
@CallSuper
@Override
public void onCreate(a) {
mDispatcher.onServicePreSuperOnCreate();
super.onCreate();
}
@CallSuper
@Nullable
@Override
public IBinder onBind(@NonNull Intent intent) {
mDispatcher.onServicePreSuperOnBind();
return null;
}
@SuppressWarnings("deprecation")
@CallSuper
@Override
public void onStart(@Nullable Intent intent, int startId) {
mDispatcher.onServicePreSuperOnStart();
super.onStart(intent, startId);
}
// this method is added only to annotate it with @CallSuper.
// In usual service super.onStartCommand is no-op, but in LifecycleService
// it results in mDispatcher.onServicePreSuperOnStart() call, because
// super.onStartCommand calls onStart().
@CallSuper
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@CallSuper
@Override
public void onDestroy(a) {
mDispatcher.onServicePreSuperOnDestroy();
super.onDestroy();
}
@Override
@NonNull
public Lifecycle getLifecycle(a) {
returnmDispatcher.getLifecycle(); }}Copy the code
ServiceLifecycleDispatcher
public class ServiceLifecycleDispatcher {
private final LifecycleRegistry mRegistry;
private final Handler mHandler;
private DispatchRunnable mLastDispatchRunnable;
/ * * *@param provider {@link LifecycleOwner} for a service, usually it is a service itself
*/
@SuppressWarnings("deprecation")
public ServiceLifecycleDispatcher(@NonNull LifecycleOwner provider) {
mRegistry = new LifecycleRegistry(provider);
mHandler = new Handler();
}
private void postDispatchRunnable(Lifecycle.Event event) {
if(mLastDispatchRunnable ! =null) {
mLastDispatchRunnable.run();
}
mLastDispatchRunnable = new DispatchRunnable(mRegistry, event);
mHandler.postAtFrontOfQueue(mLastDispatchRunnable);
}
/**
* Must be a first call in {@link Service#onCreate()} method, even before super.onCreate call.
*/
public void onServicePreSuperOnCreate(a) {
postDispatchRunnable(Lifecycle.Event.ON_CREATE);
}
/**
* Must be a first call in {@link Service#onBind(Intent)} method, even before super.onBind
* call.
*/
public void onServicePreSuperOnBind(a) {
postDispatchRunnable(Lifecycle.Event.ON_START);
}
/**
* Must be a first call in {@link Service#onStart(Intent, int)} or
* {@link Service#onStartCommand(Intent, int, int)} methods, even before
* a corresponding super call.
*/
public void onServicePreSuperOnStart(a) {
postDispatchRunnable(Lifecycle.Event.ON_START);
}
/**
* Must be a first call in {@link Service#onDestroy()} method, even before super.OnDestroy
* call.
*/
public void onServicePreSuperOnDestroy(a) {
postDispatchRunnable(Lifecycle.Event.ON_STOP);
postDispatchRunnable(Lifecycle.Event.ON_DESTROY);
}
/ * * *@return {@link Lifecycle} for the given {@link LifecycleOwner}
*/
@NonNull
public Lifecycle getLifecycle(a) {
return mRegistry;
}
static class DispatchRunnable implements Runnable {
private final LifecycleRegistry mRegistry;
final Lifecycle.Event mEvent;
private boolean mWasExecuted = false;
DispatchRunnable(@NonNull LifecycleRegistry registry, Lifecycle.Event event) {
mRegistry = registry;
mEvent = event;
}
@Override
public void run(a) {
if(! mWasExecuted) { mRegistry.handleLifecycleEvent(mEvent); mWasExecuted =true; }}}}Copy the code
Links to 8.
-
Github | Lifecycle
-
Android developers | Lifecycle
-
The user guide
-
Code sample
-
Codelab
-
Lifecycle Release Description
-
googlecodelabs | android-lifecycles
-
What is lifecycle observer and how to use it correctly?