• The ambitious fight against heaven and earth, the unambitious people hate heaven and earth.

Lifecycle

Lifecycle applications can respond to changes in the Lifecycle state, such as activities and fragments. These components help you write more organized and often leaner code that is easier to maintain.

A, UML

LifecycleOwner interfaces are implemented for Fragments and activities in Support Library 26.1.0 and later

2. Related interfaces and classes

Familiarity with the interfaces and classes is essential. Let's do it step by stepCopy the code

1.LifecycleOwner

A class that has an Android lifecycle. These events can be used by custom components to handle lifecycle changes without implementing any code inside the Activity or the Fragment.

LifecycleOwner has classes for the Android life cycle. LifecycleOwner is a custom component that uses these events to handle lifecycle changes without having to implement any code in an Activity or Fragment (more on that later). Source:

public interface LifecycleOwner {
    Lifecycle getLifecycle(a);
}
Copy the code

Below we can trace all familiar components in the source codeandriodx.activity.ComponentActivity,androidx.core.app.ComponentActivity,androidx.fragment.app.FragmentImplement theLifecycleOwner, so there is no implementation when using activities and fragments.

2.Lifecycle<-LifecycleRegistry

Defines an object that has an Android Lifecycle. {@link androidx.fragment.app.Fragment Fragment}and {@link androidx.fragment.app.FragmentActivity FragmentActivity} classes implement{@link LifecycleOwner} interface which has the {@link LifecycleOwner#getLifecycle()getLifecycle} method to access the Lifecycle. You can also implement {@link LifecycleOwner}in your own classes.

Defines a lifecycle object with lifecycle events defined internallyEventAnd state enumerationStateAnd add and remove subscribersLifecycleObserverEvent to get the current life cycle stategetCurrentState, etc…

LifecycleRegistryInheritance implements Lifecycle and can handle multiple observers or subscribers.In LifecycleRegistry we see the following code:

// Used to store subscribers and status
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> 
mObserverMap =new FastSafeIterableMap<>();
Copy the code

3.LifecycleEventObserver

As you can see in the UML diagram,LifecycleEventObserver implements the LifecycleObserver interface and internally provides the onStateChanged function as a notification call. While Lifecycleevening Server stores notifications with mObserverMap collections waiting to be sent, according toThe current stateandSubscription listening statusConduct status distribution to notify subscribers:In LifecycleRegistry, the injected subscribers and current state are stored into the collection via addObserver(@nonnull LifecycleObserver Observer)mObserverMapWhen the wait state changes, it is distributed to the registrant as a bridge:

    @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);
Copy the code

4.State&Event

Lifecycle State:Lifecycle indicates an enumeration of State identifiers for the Lifecycle of an Activity. INITIALIZED, DESTROYED, CREATED, STARTED, and RESUMED states are defined in sequence, and each state corresponds to a different lifecycle of the Activity.

    /** 
     * Lifecycle states. You can consider the states as the nodes in a graph and
     * {@link Event}s as the edges between these nodes.
     */
    @SuppressWarnings("WeakerAccess")
    public enum State {
        /** *LifecycleOwner has been destroyed. After this event, the lifecycle state distribution does not dispatch any more events, and the lifecycle will dispatch no more events. For example, this state arrives before Activityon's Destroy call. * Destroyed state for a LifecycleOwner. After this event, this Lifecycle will not dispatch * any more events. For instance, for an {@link android.app.Activity}, this state is reached
         * <b>right before</b> Activity's {@link android.app.Activity#onDestroy() onDestroy} call.
         */
        DESTROYED,

        /** * the lifecycle of INITIALIZED->CREATED represents the Activity before CREATED. * Initialized state for a LifecycleOwner. For an {@link android.app.Activity}, this is
         * the state when it is constructed but has not received
         * {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} yet.
         */
        INITIALIZED,

        /** * Create state for a LifecycleOwner. For an {create state for a LifecycleOwner.@link android.app.Activity}, this state
         * is reached in two cases:
         * <ul>
         *     <li>after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call;
         *     <li><b>right before</b> {@link android.app.Activity#onStop() onStop} call.
         * </ul>
         */
        CREATED,

        /** * Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state
         * is reached in two cases:
         * <ul>
         *     <li>after {@link android.app.Activity#onStart() onStart} call;
         *     <li><b>right before</b> {@link android.app.Activity#onPause() onPause} call.
         * </ul>
         */
        STARTED,

        /**
         * Resumed state for a LifecycleOwner. For an {@link android.app.Activity}, this state
         * is reached after {@link android.app.Activity#onResume() onResume} is called.
         */
        RESUMED;

        /** * Compares if this State is greater or equal to the given {** * Compares if this State is greater or equal to the given {@code state}.
         *
         * @param state State to compare with
         * @return true if this State is greater or equal to the given {@code state}
         */
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0; }}Copy the code

Events define LifecycleOwner’s own lifecycle Event constants. Event distribution occurs when the lifecycle state changes or handleLifecycleEvent is actively executed. For example, ON_CREATE is triggered during event distribution from INITIALIZED — >CREATED in the state event diagram.

public enum Event {
        /**
         * Constant for onCreate event of the {@link LifecycleOwner}.
         */
        ON_CREATE,
        /**
         * Constant for onStart event of the {@link LifecycleOwner}.
         */
        ON_START,
        /**
         * Constant for onResume event of the {@link LifecycleOwner}.
         */
        ON_RESUME,
        /**
         * Constant for onPause event of the {@link LifecycleOwner}.
         */
        ON_PAUSE,
        /**
         * Constant for onStop event of the {@link LifecycleOwner}.
         */
        ON_STOP,
        /**
         * Constant for onDestroy event of the {@link LifecycleOwner}.
         */
        ON_DESTROY,
        /**
         * An {@link Event Event} constant that can be used to match all events.
         */
        ON_ANY
    }

Copy the code

When the event distribution down call LifecycleRegistry handleLifecycleEvent () calls eventually call mLifecycleObserver. In turn onStateChanged (the owner, the event); Send notifications to subscribers, who receive lifecycle status notifications.

//1.Activity or lifeRegister lifecycle events are sent down the entry
  public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }
//2. Update current status
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;
    }
//3. Decide whether to traverse the distribution forward or backward based on the sequential sequence of the current target 'lifecycle state' and 'Observer state'
private void sync(a)./** 4. If the current target state value is mState < Observer state value. * * /
        if (mState.compareTo(mObserverMap.eldest().getValue(a).mState) < 0) {
               4.1 The Observer is required to decrease the state value until it equals the current target state value, mState
                backwardPass(lifecycleOwner);
            }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if(! mNewEventOccurred && newest ! = nul && mState.compareTo(newest.getValue().mState) >0) {
               4.1 The Observer is required to increment the state value until it equals the current target state value, mStateforwardPass(lifecycleOwner); }... }Pass the event forward, corresponding to DESTROYED->RESUMED in the state diagram in the figure
   private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();
        while(ascendingIterator.hasNext() && ! mNewEventOccurred) { Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next(); ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0&&! mNewEventOccurred && mObserverMap.contains(entry.getKey()))) { pushParentState(observer.mState); observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); popParentState(); }}}//4. Pass events backwards, as shown in the RESUMED -> DESTROYED figureReduce the Observer state value until the state value equals the current state valueprivate void backwardPass(LifecycleOwner lifecycleOwner) {
          Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
                mObserverMap.descendingIterator();
        4.1.1 The Observer needs to be notified to decrease the state value until it equals the current target state value, mState
        while(descendingIterator.hasNext() && ! mNewEventOccurred) { Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next(); ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                Event event = downEvent(observer.mState);
                pushParentState(getStateAfter(event));
                ObserverWithState dispatchEvent()observer.dispatchEvent(lifecycleOwner, event); popParentState(); }}}//6. Notify subscribers of life status via mLifecycleObserver
 static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
            mState = initialState;
        }

        void dispatchEvent(LifecycleOwner owner, Event event) {
            State newState = getStateAfter(event);
            mState = min(mState, newState);
            //7. Notify subscribersmLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code

3.MainActivity registers and adds subscriber events

We add a Lifecycleevening Server lifecycle event subscriber to the Activity to receive after event distribution. Then run the code.Copy the code
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.ComponentActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.blankj.utilcode.util.ToastUtils
import com.example.module_map.R
import com.example.module_map.databinding.MapActivityBaseMapBinding

class BaseOberAbleMapActivity : ComponentActivity() {
    lateinit var binding:MapActivityBaseMapBinding
    lateinit var registLifecycle:LifecycleRegistry
    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        binding  = DataBindingUtil.setContentView(this, R.layout.map_activity_base_map)
        Log.e("activity"."envent=ON_CREATE")
        lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                ToastUtils.showLong("lifecycle=" + event.name)
                Log.e("lifecycle"."envent=" + event.name)
            }
        })
    }
    override fun onStart(a) {
        super.onStart()
        Log.e("activity"."envent=ON_START")}override fun onPause(a) {
        super.onPause()
        Log.e("activity"."envent=ON_PAUSE")}override fun onResume(a) {
        super.onResume()
        Log.e("activity"."envent=ON_RESUME")}override fun onRestart(a) {
        super.onRestart()
        Log.e("activity"."envent=ON_RESTART")}override fun onStop(a) {
        super.onStop()
        Log.e("activity"."envent=ON_STOP")}override fun onDestroy(a) {
        super.onDestroy()
        Log.e("activity"."envent=ON_DESTROY")}}// Result:
/** E/activity: envent=ON_CREATE E/lifecycle: envent=ON_CREATE E/activity: envent=ON_START E/lifecycle: envent=ON_START E/activity: envent=ON_RESUME E/lifecycle: envent=ON_RESUME **/
Copy the code

In the Activity above, although handleLifecycleEvent is not actively called for event distribution, print can see that notifications are automatically received in the subscription listener. Let’s continue to analyze why notifications are automatically sent for life cycle changes. The above analysis we ponentActivity ponentActivity, androidx.core.app.Com, andriodx.activity.Com androidx. Fragments. App. Realized the Lifecycl fragments EOwner, we can see that LifecycleRegistry is initialized internally and provides the public accessible method getLifecycle().

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner.ViewModelStoreOwner.SavedStateRegistryOwner.OnBackPressedDispatcherOwner {
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    @NonNull
    @Override
    public Lifecycle getLifecycle(a) {
        returnmLifecycleRegistry; }}Copy the code

4. How are subscribers automatically notified of changes to the Activity lifecycle

We do not actively call LifeRegister’s handleLifecycleEvent or setCurrentState() in MainActivity to notify subscribers of events. MainActivity: ComponentActivity (); MainActivity: ComponentActivity (); MainActivity: ComponentActivity (); MainActivity: ComponentActivity (); MainActivity: ComponentActivity () Distribute. But to see in the onCreate ReportFragment. InjectIfNeededIn (this) that:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner.ViewModelStoreOwner.SavedStateRegistryOwner.OnBackPressedDispatcherOwner {

    static final class NonConfigurationInstances {
        Object custom;
        ViewModelStore viewModelStore;
    }
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSavedStateRegistryController.performRestore(savedInstanceState);
        / / ReportFragment here
        ReportFragment.injectIfNeededIn(this);
        if(mContentLayoutId ! =0) { setContentView(mContentLayoutId); }}}Copy the code

Let’s keep lookingReportFragmentWe can see that dispatch is called for each lifecycle, and the AndroidStudio compiler debug is called for each lifecycle event of the ReportFragment every time it enters the application.

public class ReportFragment extends Fragment {
    private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";

    public static void injectIfNeededIn(Activity activity) {
        // ProcessLifecycleOwner should always correctly work and some activities may not extend
        // FragmentActivity from support lib, so we use framework fragments for activities
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
    }

    static ReportFragment get(Activity activity) {
        return (ReportFragment) activity.getFragmentManager().findFragmentByTag(
                REPORT_FRAGMENT_TAG);
    }

    private ActivityInitializationListener mProcessListener;

    private void dispatchCreate(ActivityInitializationListener listener) {
        if(listener ! =null) { listener.onCreate(); }}private void dispatchStart(ActivityInitializationListener listener) {
        if(listener ! =null) { listener.onStart(); }}private void dispatchResume(ActivityInitializationListener listener) {
        if(listener ! =null) { listener.onResume(); }}@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onStop() {
        super.onStop();
        dispatch(Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
        // just want to be sure that we won't leak reference to an activity
        mProcessListener = null;
    }

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        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);
            }
        }
    }

    void setProcessListener(ActivityInitializationListener processListener) {
        mProcessListener = processListener;
    }

    interface ActivityInitializationListener { void onCreate(); void onStart(); void onResume(); }}Copy the code

Who notifys the ReportFragment here? Let’s look at the places where the ReportFragment is used besides CompoentActivity and LifecycleDispatcher. In LifecycleDispatcher we can see:

/** * When initialized, it hooks into the Activity callback of the Application and observes * Activities. It is responsible to hook in child-fragments to activities and fragments to report * their lifecycle events. Another responsibility of this class is to mark as stopped all lifecycle * providers related to an activity as soon it is not safe to run a fragment transaction  in this * activity. */
class LifecycleDispatcher {

    private static AtomicBoolean sInitialized = new AtomicBoolean(false);

    static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        / / 1. By registering the Activity lifecycle callback function in the listening to distribute in DispatcherActivityCallback receiving
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

    @SuppressWarnings("WeakerAccess")
    @VisibleForTesting
    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {

        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            // Give the activity to ReportFragment for dispatching and distribution to lifeRegister for further distribution
            ReportFragment.injectIfNeededIn(activity);
        }

        @Override
        public void onActivityStopped(Activity activity) {}@Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}}private LifecycleDispatcher(a) {}}Copy the code

Also we found in ReportFragment setProcessListener (ActivityInitializationListener processListener) seem monitor let’s take a look at the caller:

/** provides the entire application lifecycle * Class that provides lifecycle for the whole application process. * so It will only issue ON_CREATE events once *It is useful for use cases where you would like to react on your app coming *to the foreground or *going to the background and you Don't need a milliseconds accuracy in *receiving lifecycle events. And ProcessLifecycleOwner */ when no millisecond precision is required to receive lifecycle events
public class ProcessLifecycleOwner implements LifecycleOwner {

  

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

    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) {}void attach(Context context) {
        mHandler = new Handler();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
             // Pass the Activity to ReportFragment for distribution
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

Also, we can see in the section that the Activity is handed to the ReportFragment for distribution in attah. Like LifecycleDispatcher through App. RegisterActivityLifecycleCallbacks to monitor the activity of the life cycle of change, and then delivered to the ReportFragment distributed.

Through the above tracking we know:

  • ProcessLifecycleOwner

    By registering the Activity lifecycle callback function to receive DispatcherActivityCallback distributed notice. Distribute it to ReportFragment in onActivityCreated, allocate it to LifecycleRegister and distribute it down through ReportFragment.

  • LifecycleDispatcher through the same App. RegisterActivityLifecycleCallbacks to monitor the activity of the life cycle of change, and then delivered to the ReportFragment distributed.

The initialization of ProcessLifecycleOwner and LifecycleDispatcher go further and we’ll find:

ProcessLifecycleOwnerInitializer inheritance ContentProvider here we are not in the Application for registration, it certainly Lifecyle automatically injected in the manifest file

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
    @Override
    public boolean onCreate() {
        LifecycleDispatcher.init(getContext());
        ProcessLifecycleOwner.init(getContext());
        return true;
    }
Copy the code

Look at the manifest file under Build after we run the app

Lifecycle now that we understand how Lifecycle works, let’s manage the Lifecycle of the tool separately to avoid having a node associated with each Lifecycle event in the activity that is bloated under the code.

package com.example.module_map.baseoberservable

import android.content.Context
import android.location.Location
import android.location.LocationListener
import android.util.Log
import androidx.lifecycle.*
import com.blankj.utilcode.util.ToastUtils

/ * * * * ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ * │ ┌ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┬ ─ ─ ─ ┐ │ x │ │ Esc │! 1 2 │ │ @ # % 3 $4 │ │ │ 5 6 7 │ │ & * ^ 8 │ │ │ (9) 0 _ + = │ │ - | \ │ ` ~ │ │ * │ ├ ─ ─ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ─ ─ ┤ │ x │ │ Tab │ │ │ │ │ Q W E R T I │ │ │ Y U │ │ │ P O {[│}] │ BS │ │ x │ ├ ─ ─ ─ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ─ ─ ─ ─ ─ ┤ │ x │ │ Ctrl │ │ │ │ │ │ F G D S A H │ │ │ K J L │ :; │ │ "' Enter │ │ X │ ├ ─ ─ ─ ─ ─ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ┬ ─ ┴ ─ ─ ─ ─ ┬ ─ ─ ─ ┤ │ X │ │ Shift │ │ X │ │ Z C V │ │ │ N M B , │ │ < >. │? / │ Shift │ Fn │ │ x │ └ ─ ─ ─ ─ ─ ┬ ─ ─ ┴ ┬ ─ ─ ┴ ─ ─ ┬ ┴ ─ ─ ─ ┴ ─ ─ ─ ┴ ─ ─ ─ ┴ ─ ─ ─ ┴ ─ ─ ─ ┴ ─ ─ ┬ ┴ ─ ─ ─ ┴ ┬ ─ ─ ┴ ┬ ─ ─ ─ ─ ─ ┴ ─ ─ ─ ┘ │ x │ │ Fn Alt │ │ Space Alt │ │ Win │ HHKB │ x │ └ ─ ─ ─ ┴ ─ ─ ─ ─ ─ ┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┴ ─ ─ ─ ─ ─ ┴ ─ ─ ─ ┘ │ * └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ Copyright (c) 2015 Bohai Xinneng All Rights Reserved@authorFeiWang * Version: 1.5 * Creation Date: 1/13/21 * Description: BHNE_OSM * E-mail: 1276998208@qq.com
 * CSDN:https://blog.csdn.net/m0_37667770/article
 * GitHub:https://github.com/luhenchang
 */
class MyLifeCycleOwer(var locationClient:LocationClient) : LifecycleObserver{
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun  connectListener(a) {
        // For example, restart the location operation
        locationClient.resumConnnected()
        ToastUtils.showLong("lifecycle=ON_RESUME")}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun  disconnectListener(a) {
        // Stop location of other life-cycle related events
        locationClient.stopConnnected()
        ToastUtils.showLong("lifecycle=ON_PAUSE")}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun  removeLocation(a) {
        locationClient.removeConnnected()
        ToastUtils.showLong("lifecycle=ON_PAUSE")
        Log.e("lifecycle"."envent=ON_PAUSE")}}Copy the code

We injected our LifecycleObserver implementation class into the activity for what cycle and location tool event management, code implementation of parity, separation, looks much more streamlined.

class BaseOberAbleMapActivity : ComponentActivity(a){
    var locationClient: MyLifeCycleOwer.LocationClient = MyLifeCycleOwer.LocationClient()
    override fun onCreate(savedInstanceState: Bundle?) {
    lifecycle.addObserver(MyLifeCycleOwer(locationClient))
 }
}
Copy the code

That’s it. I would like to point out what is unclear or problematic…