Android Jetpack - Lifecycle

简介

Lifecycle 是一个类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。说白了以前通过各种方式在Activity和Fragment的生命周期里处理的其他类的回调,现在可以通过Lifecycle放到那个类的里面,在Activity和Fragment只要设置一下观察对象即可。
举个例子:播放器需要在stop里面暂停,start或restart里面开始播放,这些原本需要在Activity中手动调用的,现在都可以封装到播放器那个类的里面让他自动去调用(这里暂停不在pause里面,恢复不在resume里面,因为Android有分屏功能,在这种多屏状态下,Activity的生命周期是从resume到pause再从pause到resume,如果把播放器的暂停写在pause里面,用户一个屏在播放视频,这时点击到另一个屏,视频就会暂停)。

使用方式

  1. 想要观察的类实现LifecycleObserver接口,使用注解@OnLifecycleEvent(Lifecycle.Event.ON_START)来声明当相应生命周期到来时需要执行的方法。
    Lifecycle有两个枚举Events和State
    Events种类有:ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、ON_STOP、ON_DESTORY
    State种类有:INITIALIZED、CREATED、STARTED、RESUMED、DESTROYED
internalclass Player (
	private var url:String
	private val lifecycle: Lifecycle
	) : LifecycleObserver {

	@OnLifecycleEvent(Lifecycle.Event.ON_START)
	fun start(){
		Log.d("KtMainActivity", "player start play url = $url")
	}

	@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
	fun pause(){
		Log.d("KtMainActivity", "player pause play url = $url")
	}

	@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
	fun release(){
		Log.d("KtMainActivity", "player release play url = $url")
	}
	
	fun showErrorView(){
		//其他状态不显示错误标识
		if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
               // connect if not connected
           }
	}
}

如果想要观察的类需要对所有生命周期都执行操作则可以继承FullLifecycleObserver,并且效率也比LifecycleObserver高一点,因为在源码中,继承自FullLifecycleObserver在状态改变时是直接调用方法

//FullLifecycleObserverAdapter
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
   switch (event) {
       case ON_CREATE:
           mObserver.onCreate(source);
           break;
       case ON_START:
           mObserver.onStart(source);
           break;
       case ON_RESUME:
           mObserver.onResume(source);
           break;
       case ON_PAUSE:
           mObserver.onPause(source);
           break;
       case ON_STOP:
           mObserver.onStop(source);
           break;
       case ON_DESTROY:
           mObserver.onDestroy(source);
           break;
       case ON_ANY:
           throw new IllegalArgumentException("ON_ANY must not been send by anybody");
   }
}

而继承自LifecycleObserver是通过反射在状态改变时调用相应的方法

class ClassesInfoCache{
	private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
        ...
        //使用反射将相应生命周期需要执行的方法保存下来
        Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
        boolean hasLifecycleMethods = false;
        for (Method method : methods) {
            OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
            if (annotation == null) {
                continue;
            }
            ...
        }
        ....
    }
	...
	static class CallbackInfo {
		...
		//使用map来保存,key就是event value就是方法
		final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers;
		...
	}
	
	static class MethodReference {
		...
		final Method mMethod;
		MethodReference(int callType, Method method) {
			mCallType = callType;
			mMethod = method;
			//外部可调用该方法,这说明@OnLifecycleEvent注解标识的方法可见修饰符对于观察者本身没有影响
			mMethod.setAccessible(true);
		}
		...
		
		//在界面控制器生命周期发生变化时会调用该方法
		void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
			....
			switch (mCallType) {
				case CALL_TYPE_NO_ARG:
					mMethod.invoke(target);
					break;
				case CALL_TYPE_PROVIDER:
					mMethod.invoke(target, source);
					break;
				case CALL_TYPE_PROVIDER_WITH_EVENT:
					mMethod.invoke(target, source, event);
					break;
			}
			...
		}
	|
	...
}
  1. 被观察对象需要通过lifecycle.addObserver(Player)来将自己生命周期让Player可视
class MainActivity : AppCompatActivity(){
	private lateinit var player: Player
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)
		player = Player("https://127.0.0.1:8080/video/vr.mp4", lifecycle)
		lifecycle.addObserver(player)
	}
}

这边AppCompatActivity里,默认会有lifecycle,当不是继承该类时需要自己实现继承LifecycleOwner接口,标识自己是生命周期拥有者,它只有一个getLifecycle需要实现,

class MyLifeCycle: LifecycleOwner{
	//注册
	private val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
	
	//在需要的方法里调用lifecycleRegistry.markState来通知外界自己当前处于哪个生命周期状态
	fun loadData(){
		lifecycleRegistry.markState(Lifecycle.State.STARTED)
	}
	
	//LifecycleOwner接口实现的方法,需要返回一个lifecycleRegistry
	override fun getLifecycle(): Lifecycle {
		return lifecycleRegistry
	}
}

其实在AppCompatActivity的默认实现里面也是这样写的,最终代码是在ComponentActivity中

public class ComponentActivity extends Activity implements LifecycleOwner, KeyEventDispatcher.Component {
	protected void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//将ReportFragment加进去,然后利用Fragment自带的生命周期,在每个生命周期方法里面调用事件分发
		ReportFragment.injectIfNeededIn(this);
	}
}

public class ReportFragment extends Fragment {
	@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        //发送Create事件给观察者
        dispatch(Lifecycle.Event.ON_CREATE);
    }
}

注:

  • 调用时机问题:Activity的onCreate、onStart、onResume先执行,Player的相应的ON_CREATE、ON_START、ON_RESUME才会被执行,
    Player的相应的ON_PAUSE、ON_STOP、ON_DESTORY先被执行,Activity的onPuase、onStop、onDestory才会被执行
  • 关于state:LifeCycle的Event和State对应关系源码
//LifecycleRegistry
static State getStateAfter(Event event) {
        switch (event) {
        //Event是ON_CREATE和ON_STOP时State是CREATED
        case ON_CREATE:
        case ON_STOP:
            return CREATED;
        //Event是ON_START和ON_PAUSE时State是STARTED
        case ON_START:
        case ON_PAUSE:
            return STARTED;
        //Event是ON_RESUME时State是RESUMED
        case ON_RESUME:
            return RESUMED;
        //Event是ON_DESTROY时State是DESTROYED
        case ON_DESTROY:
            return DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException("Unexpected event value " + event);
}

或者直接看图
Lifecycle的Events和States

  • LifecycleOwner只是个接口,只有一个方法需要实现即getLifecycle(),而这个方法一般返回继承自Lifecycle的LifecycleRegistry。
    LifecycleRegistry是直接new出来的
public class ComponentActivity extends Activity implements LifecycleOwner{
	...
	private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
	...
}
public class LifecycleRegistry extends Lifecycle {
	//通过map来存储,需要调用的时候再来取,key是自定义的那个LifecycleObserver,value是对该LifecycleObserver的一些信息存储和状态
	//如:自定义的观察者是继承LifecycleObserver,通过给方法加注解方式使用,ObserverWithState在存的时候就会将所有方法和它们对应生效的周期存起来在ClassesInfoCache的一个在map中,方便后续调用
	private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();

	public LifecycleRegistry(@NonNull LifecycleOwner provider) {
		//这边使用了弱引用,避免在洁面控制器销毁时造成内存泄漏
		mLifecycleOwner = new WeakReference<>(provider);
		//初始状态是INITIALIZED
		mState = INITIALIZED;
	}
	
	//后面使用LiveData的时候也会调用该方法
	@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);
		...
	}
}

观察应用的生命周期

前面说的是监听某个类的生命周期,还可以通过ProcessLifecycleOwner来监听进程的生命周期
使用方式很简单,一般在Application的oncreate方法里(在其他地方也可):

	ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationObserver())
	class ApplicationObserver: LifecycleObserver{
	//应用程序创建时调用,只会被调用一次
	@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
	fun onAppCreate()
	{
		Log.d("KtMainActivity", "app create")
	}

	//应用程序出现到前台时调用
	@OnLifecycleEvent(Lifecycle.Event.ON_START)
	fun onAppStart()
	{
		Log.d("KtMainActivity", "app start")
	}

	//应用程序出现到前台时调用
	@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
	fun onAppResume()
	{
		Log.d("KtMainActivity", "app resume")
	}

	//应用程序退出到后台时调用
	@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
	fun onAppPause()
	{
		Log.d("KtMainActivity", "app pause")
	}

	//应用程序退出到后台时调用
	@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
	fun onAppStop()
	{
		Log.d("KtMainActivity", "app stop")
	}

	//永远不会被调用到,系统不会分发调用ON_DESTROY事件
	@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
	fun onAppDestroy()
	{
		Log.d("KtMainActivity", "app destroy")
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值