Android Jetpack-Lifecycle

200 阅读7分钟

一、概述

很多时候我们需要在Activity或Fragment的生命周期发生变化时做一些事情,比如onStart时初始化视频、动画、定位等,而当onPause时需要暂停视频、动画、定位等,在onDestroy时让视频、动画、定位等资源释放并退出,在以前的开发中会把相关的生命周期操作臃肿的塞在Activity或Fragment的各个生命周期里,代码长不利于阅读和维护。比如如下伪代码:

伪代码一:全部写在类中塞在一起

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //初始化播放器
        initPlayer();
        //初始化定位
        initLocation();
    }

    override fun onStart() {
        super.onStart()
        //开始播放
        mediaPlayer.start();
        //开始定位
        location.start();
    }

    override fun onPause() {
        super.onPause()
        //暂停播放
        mediaPlayer.pause();
        //暂停定位
        location.start();
    }

    override fun onDestroy() {
        super.onDestroy()
        //释放资源
        mediaPlayer.release();
        //释放资源
        location.release();
    }
}

伪代码二:多个动作需要监听生命周期时写多个Listener回调

//定位的类
class ProjectLocationListener(context: Context, callback: LocationCallback) {

    fun statrt() {
        //初始化定位
        startLocation();
    }

    fun pause() {
        //暂停定位
        pauseLocation();
    }

    fun destroy() {
        //释放资源
        releaseLocation();
    }

}

//MainActivity中使用
class MainActivity : AppCompatActivity() {
    private lateinit var mProjectLocationListener:ProjectLocationListener

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //初始化定位的监听器
        mProjectLocationListener = ProjectLocationListener(this){
            //callback回调,比如把定位的位置返回:xx省xx市xx区
        }
    }

    override fun onStart() {
        super.onStart()
        //传递生命周期
        mProjectLocationListener.statrt()
    }

    override fun onPause() {
        super.onPause()
        //传递生命周期
        mProjectLocationListener.pause()
    }

    override fun onDestroy() {
        super.onDestroy()
        //传递生命周期
        mProjectLocationListener.destroy()
    }
}

看着没问题,但是会有太多管理界面和其他组件的调用,繁琐且不安全。Lifecycle可以更方便的解决这个问题。

二、Lifecycle

1、简介

Lifecycle 是一个类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。

Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态:事件和状态

  • 事件

    从框架和 Lifecycle 类分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件。

  • 状态

    由 Lifecycle 对象跟踪的组件的当前状态。

lifecycle-states.png

2、引入Lifecycle库

现在创建androidx项目时默认就会引入,就是这一行:

implementation 'androidx.appcompat:appcompat:1.4.1'

这行依赖除了引入Lifecycle以外还会引入很多其他依赖,看下Lifecycle引入了哪些:

image.png

3、DefaultLifecycleObserver

普通的类可以通过实现DefaultLifecycleObserver 并替换相应的方法onCreate 和 onStart 等)来监控组件的生命周期状态。如下代码:


class LocationLifecycleObserver(context: Context,
        lifecycle:Lifecycle,
        callback:LocationCallback
        ): DefaultLifecycleObserver {
    
    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        //初始化定位
        initLocation()
    }

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        //开始定位
        startLocation()
    }

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
    }

    override fun onPause(owner: LifecycleOwner) {
        super.onPause(owner)
        //暂停定位
        pauseLocation()
    }

    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        //释放资源
        releaseLocation()
    }
}

然后,可以通过调用 Lifecycle 类的 addObserver() 方法并传递观察器的实例来添加观察器,如下例所示:

//调用上面的Listener
xxLifecycleOwner.lifecycle.addObserver(LocationLifecycleObserver(this){
    //callback回调,比如把定位的位置返回:xx省xx市xx区
})

上面代码中的xxLifecycleOwner是啥?从LifecycleOwner字面理解是生命周期的持有者,常见的有生命周期的有Activity、Fragment等,LifecycleOwner是一个接口,xxLifecycleOwner是接口的实现类(这里的xxLifecycleOwner是伪代码)。

4、LifecycleOwner

LifecycleOwner 是单一方法接口,任何自定义类均可实现 LifecycleOwner接口,这个接口有一个方法getLifecycle()获取生命周期:

/**
 * 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.
 *
 * @see Lifecycle
 * @see ViewTreeLifecycleOwner
 */
@SuppressWarnings({"WeakerAccess", "unused"})
public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}

实现 DefaultLifecycleObserver 的组件可与实现 LifecycleOwner 的组件完美配合,因为所有者可以提供生命周期,而观察者可以注册以观察生命周期。这句话就是Lifecycle的核心。支持库 26.1.0 及更高版本中的 Fragment 和 Activity 已实现 LifecycleOwner 接口。如下:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        ContextAware,
        LifecycleOwner,    //Activity已经实现了LifecycleOwner
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner,
        ActivityResultRegistryOwner,
        ActivityResultCaller {
        ...
        }
public class Fragment implements ComponentCallbacks, 
        OnCreateContextMenuListener,
        LifecycleOwner,     //Fragment已经实现了LifecycleOwner
        ViewModelStoreOwner,
        HasDefaultViewModelProviderFactory, 
        SavedStateRegistryOwner,
        ActivityResultCaller {

现在结合上面的第三点看,定义了一个位置信息的观察者LocationLifecycleObserver,只需要将LocationLifecycleObserver注入到实现了LifecycleOwner的组件中即可,假如这个组件是Activity代码如下:

this.lifecycle.addObserver(LocationLifecycleObserver(this,lifecycle){
    //callback回调,比如把定位的位置返回:xx省xx市xx区
})

于是我们就可以用这种注入的形式把定位、播放视频、动画等需要跟生命周期关联的需求分拆开,使代码简洁方便维护。

5、实现自定义LifecycleOwner

支持库 26.1.0 及更高版本中的 Fragment 和 Activity 已实现 LifecycleOwner 接口。

如果您有一个自定义类并希望使其成为 LifecycleOwner,您可以使用 LifecycleRegistry 类,但需要将事件转发到该类,如以下代码示例中所示:

class MyActivity : Activity(), LifecycleOwner {

    private lateinit var lifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleRegistry = LifecycleRegistry(this)
        //转发事件
        lifecycleRegistry.markState(Lifecycle.State.CREATED)
    }

    public override fun onStart() {
        super.onStart()
         //转发事件
        lifecycleRegistry.markState(Lifecycle.State.STARTED)
    }

    //重写getLifecycle方法
    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}

6、获取生命周期的事件

有时候需要判断已经到达了某个生命周期事件才能触发动作,代码如下:

 if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED))  {
            // connect if not connected
        }

三、Service中的Lifecycle

为了方便对Service生命周期的监听,Android提供了一个名为LifecycleService的类,让该类继承自Service,并实现LifecycleOwner接口,不过先要引入依赖:

implementation "android.arch.lifecycle:extensions:1.4.1"

LifecycleService类的源码:

public class LifecycleService extends Service implements LifecycleOwner {

    private final ServiceLifecycleDispatcher mDispatcher = new ServiceLifecycleDispatcher(this);

    @CallSuper
    @Override
    public void onCreate() {
        //lifecycle事件create
        mDispatcher.onServicePreSuperOnCreate();
        super.onCreate();
    }

    @CallSuper
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //lifecycle事件bind
        mDispatcher.onServicePreSuperOnBind();
        return null;
    }

    @SuppressWarnings("deprecation")
    @CallSuper
    @Override
    public void onStart(Intent intent, int startId) {
        //lifecycle事件start
        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(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @CallSuper
    @Override
    public void onDestroy() {
        //lifecycle事件destroy
        mDispatcher.onServicePreSuperOnDestroy();
        super.onDestroy();
    }

    @Override
    public Lifecycle getLifecycle() {
        return mDispatcher.getLifecycle();
    }
}

那么LifecycleService该如何使用? 其实跟上面的思路一样,创建类实现DefaultLifecycleObserverLifecycleObserver,伪代码如下:

class LocationLifecycleObserver(
    var context: Context,
    var lifecycle: Lifecycle,
    var callback: LocationCallback
) : DefaultLifecycleObserver {

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        //开始定位
        startLocation()
    }

    private fun startLocation() {
        Log.d("LOCATION","startLocation")
        callback.getLocation("XX省,XX市,XX区")
    }


    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        //停止定位
        stopLocation()
    }

    private fun stopLocation() {
        Log.d("LOCATION","stopLocation")
    }
}

在Service中注入生命周期

class TestService : LifecycleService() {

    private lateinit var mLocationLifecycleObserver: LocationLifecycleObserver

    override fun onCreate() {
        super.onCreate()
        mLocationLifecycleObserver =
            LocationLifecycleObserver(this, lifecycle, object : LocationCallback {
                override fun getLocation(location: String) {
                    Log.d("LOCATION", "回调位置:${location}")
                }

            })
        //注入生命周期的事件
        lifecycle.addObserver(mLocationLifecycleObserver)
    }
 }

四、Application的Lifecycle

1、ProcessLifecycleOwner

创建Application生命周期事件的观察者


class ApplicationObserver(
    var context: Context,
    var lifecycle: Lifecycle
) : DefaultLifecycleObserver {
    companion object{
        const val TAG = "ApplicationObserver"
    }

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        Log.d(TAG,"onCreate")
    }

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        Log.d(TAG,"onStart")
    }

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
        Log.d(TAG,"onResume")
    }

    override fun onPause(owner: LifecycleOwner) {
        super.onPause(owner)
        Log.d(TAG,"onPause")
    }

    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
        Log.d(TAG,"onStop")
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        Log.d(TAG,"onDestroy")
    }
}

注入观察者

class App : Application() {

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(
            ApplicationObserver(
                this,
                ProcessLifecycleOwner.get().lifecycle
            )
        )
    }
}

需要注意的是App被杀死时一般不会回调onDestroy方法,而onStop方法在切换前后台时也会被回调,所以要慎重使用。

跟踪ProcessLifecycleOwner源码会发现关联的是Activity的生命周期:

@SuppressWarnings("WeakerAccess")
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;
    //lifecycle的生命周期事件的注册
    private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
    //底层是handler传递runnable事件
    private Runnable mDelayedPauseRunnable = new Runnable() {
        @Override
        public void run() {
            dispatchPauseIfNeeded();
            dispatchStopIfNeeded();
        }
    };

    ActivityInitializationListener mInitializationListener =
            new ActivityInitializationListener() {
                @Override
                public void onCreate() {
                }

                @Override
                public void onStart() {
                    activityStarted();
                }

                @Override
                public void onResume() {
                    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() {
        return sInstance;   //单例
    }

    static void init(Context context) {
        sInstance.attach(context);
    }

    //Activity的start事件
    void activityStarted() {
        mStartedCounter++;
        if (mStartedCounter == 1 && mStopSent) {
            //注册了Activity的start事件
            mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
            mStopSent = false;
        }
    }

    //Activity的resume事件
    void activityResumed() {
        mResumedCounter++;
        if (mResumedCounter == 1) {
            if (mPauseSent) {
                 //注册了Activity的resume事件
                 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
                mPauseSent = false;
            } else {
                mHandler.removeCallbacks(mDelayedPauseRunnable);
            }
        }
    }

    void activityPaused() {
        mResumedCounter--;
        if (mResumedCounter == 0) {
            //回调dispatchPauseIfNeeded,会注册pause事件
            mHandler.postDelayed(mDelayedPauseRunnable, TIMEOUT_MS);
        }
    }

    void activityStopped() {
        mStartedCounter--;
         //回调dispatchStopIfNeeded,会注册stop事件
        dispatchStopIfNeeded();
    }

    void dispatchPauseIfNeeded() {
        if (mResumedCounter == 0) {
            mPauseSent = true;
            //注册Activity的pause事件
            mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        }
    }

    void dispatchStopIfNeeded() {
        if (mStartedCounter == 0 && mPauseSent) {
            //注册Activity的stop事件
            mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
            mStopSent = true;
        }
    }

    private ProcessLifecycleOwner() {
    }

    @SuppressWarnings("deprecation")
    void attach(Context context) {
        mHandler = new Handler();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        //关键的代码,注册了registerActivityLifecycleCallbacks拿到Activity的生命周期回调
        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() {   //获取Lifecycle对象
        return mRegistry;
    }
}

registerActivityLifecycleCallbacks注册了Activity生命周期的回调,可以拿到当前前台的Activity的生命周期事件。

2、ActivityLifecycleCallbacks

Application提供了Acitivty生命周期回调的方法,就是registerActivityLifecycleCallbacks,看下如何自定义使用。

创建类实现Application.ActivityLifecycleCallbacks接口:

class AppLifeCallback : Application.ActivityLifecycleCallbacks {

    companion object {
        const val TAG = "AppHelper"
    }

    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        //打印调用此方法的Activity的类的名称
        Log.d(TAG, "onActivityCreated:${activity.localClassName}")
    }

    override fun onActivityDestroyed(activity: Activity) {
        //打印调用此方法的Activity的类的名称
        Log.d(TAG, "onActivityDestroyed:${activity.localClassName}")
    }

    override fun onActivityStarted(activity: Activity) {
        //打印调用此方法的Activity的类的名称
        Log.d(TAG, "onActivityStarted:${activity.localClassName}")
    }

    override fun onActivityResumed(activity: Activity) {
        //打印调用此方法的Activity的类的名称
        Log.d(TAG, "onActivityResumed:${activity.localClassName}")
    }

    override fun onActivityPaused(activity: Activity) {
        //打印调用此方法的Activity的类的名称
        Log.d(TAG, "onActivityPaused:${activity.localClassName}")
    }

    override fun onActivityStopped(activity: Activity) {
        //打印调用此方法的Activity的类的名称
        Log.d(TAG, "onActivityStopped:${activity.localClassName}")
    }

    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}

}

在Application中注册

class App : Application() {

    override fun onCreate() {
        super.onCreate()
        //注册
       registerActivityLifecycleCallbacks(AppLifeCallback())
    }
}

打印会发现所有的Activity的生命周期事件都会在这里回调

image.png

所以这里可以做一些Activity的统一管理,比如杀死所有Activity并退出应用等。

3、FragmentLifecycleCallbacks

相应的Fragment也有生命周期回调FragmentLifecycleCallbacks,自定义它的实现类并实现它的所有方法:


class CustomFragmentLifecycleCallback: FragmentManager.FragmentLifecycleCallbacks() {


    override fun onFragmentPreAttached(fm: FragmentManager, f: Fragment, context: Context) {
        super.onFragmentPreAttached(fm, f, context)
    }

    override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) {
        super.onFragmentAttached(fm, f, context)
    }

    override fun onFragmentPreCreated(
        fm: FragmentManager,
        f: Fragment,
        savedInstanceState: Bundle?
    ) {
        super.onFragmentPreCreated(fm, f, savedInstanceState)
    }

    override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
        super.onFragmentCreated(fm, f, savedInstanceState)
    }

    override fun onFragmentActivityCreated(
        fm: FragmentManager,
        f: Fragment,
        savedInstanceState: Bundle?
    ) {
        super.onFragmentActivityCreated(fm, f, savedInstanceState)
    }

    override fun onFragmentViewCreated(
        fm: FragmentManager,
        f: Fragment,
        v: View,
        savedInstanceState: Bundle?
    ) {
        super.onFragmentViewCreated(fm, f, v, savedInstanceState)
    }

    override fun onFragmentStarted(fm: FragmentManager, f: Fragment) {
        super.onFragmentStarted(fm, f)
    }

    override fun onFragmentResumed(fm: FragmentManager, f: Fragment) {
        super.onFragmentResumed(fm, f)
    }

    override fun onFragmentPaused(fm: FragmentManager, f: Fragment) {
        super.onFragmentPaused(fm, f)
    }

    override fun onFragmentStopped(fm: FragmentManager, f: Fragment) {
        super.onFragmentStopped(fm, f)
    }

    override fun onFragmentSaveInstanceState(fm: FragmentManager, f: Fragment, outState: Bundle) {
        super.onFragmentSaveInstanceState(fm, f, outState)
    }

    override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) {
        super.onFragmentViewDestroyed(fm, f)
    }

    override fun onFragmentDestroyed(fm: FragmentManager, f: Fragment) {
        super.onFragmentDestroyed(fm, f)
    }

    override fun onFragmentDetached(fm: FragmentManager, f: Fragment) {
        super.onFragmentDetached(fm, f)
    }
}

在Activity中注册

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //第二参数是是否自动注册Fragment的子Fragment
        supportFragmentManager.registerFragmentLifecycleCallbacks(
            CustomFragmentLifecycleCallback(), true)
    }
}

参考了如下博客,表示感谢:

使用生命周期感知型组件处理生命周期

监听Service的生命周期-LifecycleService

--个人学习笔记