Handling LifeCycle
android.arch.lifecycle 提供的类和接口,让使用者构建能够感知生命周期。
Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.
根据Activity or fragment的生命周期自行调整类的行为通过观察其状态
Lifecycle uses two main enumerations to track the lifecycle status for its associated component:
AAC 中提供了LifeCycle 使用枚举类来解决生命周期管理问题。
- 持有Activity/Fragment 生命周期类
- 通过接口LifecycleRegistryOwner /LifecycleObserver 注解事件@OnLifecycleEvent(),以及外部调用观察者模式addObserver(mTx),来完成将(Activity/Fragment)”生命周期”共享给其他组件这么一件事
- 事件
生命周期事件由系统来分发,这些事件对应与Activity和Fragment的生命周期函数
(ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY)
- 状态
LifeCycle的状态,用于追踪lifecycle对象: (INITIALIZED,DESTROYED,CREATED,STARTED,RESUMED)
ps:在STARTED和RESUMED 状态是处于活跃状态,只有在这两个状态下LivaData是会通知数据变化的。
ps 考虑一个问题:
LifeCycle 是如何感知到Activity或是Fragment的生命周期的呢?
因为AAC是基于MVVM架构的所以首先开一下 MVP和MVVM的感知生命周期操作。
(1)MVP感知生命周期的方法
最开始的attach和detach ,通过Activity或是Fragment中生命周期函数去关联Presenter,之后判断View是否是Active的来决定是否更新Ui。因为Retrofit和RxJava的兴起,可以将Presenter中的动作变成一个流事件。通过RxJava特效通过解除订阅的方式来控制Presenter中的更新Ui的动作。后面有出了RxLifecycle,通过细微控制到每一个生命周期函数,更进一步的感知处理每个生命周期函数。
(2)MVVM感知生命周期的方法
创造一个MVVM ViewModel接口 ,里面包含所有的生命周期回掉的方法,然后在Aor f中的各个生命周期函数中调用。
(3)官方的MVVM感知生命周期的方法
在《使用ContentProvider初始化你的Library》 一文中,作者提到使用了ContentProvider进行library的初始化,并通过其控制生命周期函数
LifeCycle 源码分析:
<provider
android:name = “android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
android:exported = “fasle”
android:multiporcess = “true”
android:authoritites = "com.example.hbl.mbbm.lifecycle-trojan"
/>
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class LifecycleRuntimeTrojanProviderextends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher .init ( getContext() ); //初始化生命周期控制的方法
ProcessLifecycleOwner.init( getContext() );
return true;
}
}
在LifecycleDispatcher()方法中 又是如何操作的呢?
Class LifecycleDispatcher{
private static final String REPORT_FRAGMENT_TAG = “android.arch.lifecycle"
+ “.LifecycleDispatcher.report_fragment_tag” ;
private static AtomicBooleansInitialized= new AtomicBoolean ( false);
static void init (Context context) {
if(sInitialized .getAndSet (true) ){
return ;
}else {
( (Application)context .getApplicationContext() ). registerActivityLifecycleCallbacks
(new DispatcherActivityCallback());
}
}
解析:通过AtomicBoolean来控制初始化一次,之后获取ApplicationContext并设置ActivityLifecycleCallback回调。
ps:AtomicBoolean 函数在退出app的时候可以用到
在DispatcherActivityCallback中:
在DispatcherActivityCallback()构造函数中
1、创建了一个FragmentCallback对象,用于设置Fragment的生命周期。
2、在onActivityCreated()函数中 instanceof 一个FragmentActivity,注入一股ReportFragment到当前Activity
3、在ReportFragment中,将这个Fragment 添加到当前Activity中,让当前的fragment绑定到Activity的生命周期中
4、之后通过onActivityCreate()函数中的dispatch()方法把当前生命周期分发到对应的LifecycleOwner中
5、通过这种方法,给Activity or Fragment添加其他额外的fragment,来获取当前的Activity 或是Fragment的生命周期。然后判断当前的Activity 或是Fragment是否是LifeCycleRegistryOwner的。如果是,那么就分发当前的生命周期事件到当前的Owner中,以达到生命周期的传递操作
- 官方LifeCycle的使用案例:
(一)创建监听器
classMyLocationListener{
publicMyLocationListener(Contextcontext,Callbackcallback){
// ...
}
voidstart(){
// connect to system location service
}
voidstop(){
// disconnect from system location service
}
}
在需要的Activity中绑定监听器
privateMyLocationListenermyLocationListener;
@Override
publicvoidonCreate(...){
myLocationListener =newMyLocationListener(this,(location)->{
// update UI
});
}
@Override
publicvoidonStart(){
super.onStart();
myLocationListener.start();
// manage other components that need to respond
// to the activity lifecycle
}
@Override
publicvoidonStop(){
super.onStop();
myLocationListener.stop();
// manage other components that need to respond
// to the activity lifecycle
}
(二)创建观察者对象
publicclassMyObserverimplementsLifecycleObserver{
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
publicvoidconnectListener(){
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
publicvoiddisconnectListener(){
...
}
}
myLifecycleOwner.getLifecycle().addObserver(newMyObserver());
(三)实现LifeCycleOwner 绑定Activity或是Fragment生命周期
publicclassMyActivityextendsActivityimplementsLifecycleOwner{
privateLifecycleRegistrymLifecycleRegistry;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
mLifecycleRegistry =newLifecycleRegistry(this);
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
publicvoidonStart(){
super.onStart();
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
publicLifecyclegetLifecycle(){
returnmLifecycleRegistry;
}
}
- 一个有关LifeCycle 的小Ex:
1、定义一个类实现LifeCycleObserver方法
2、定义2个状态变量
3、自定义类实现LifecycleObserver接口,并添加Lifecycle的生命周期绑定注解
class MyView extends TextView implements LifecycleObserver{
private boolean lifeCycleEnable;
private Lifecycle lifecycle;
//添加构造方法
public boolean isLifeCycleEnable() {
return lifeCycleEnable;
}
public void setLifeCycleEnable(boolean lifeCycleEnable) {
this.lifeCycleEnable = lifeCycleEnable;
}
public Lifecycle getLifecycle() {
return lifecycle;
}
// ****************** lifeCycle 生命周期函数事件******************
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void create() {
if (lifeCycleEnable) {
String text = System.currentTimeMillis() + "-create/n";
Log.i(TAG, text);
this.setText(text);
}
}
//同理Lifecycle.Event.ON_其他事件 ON_START 、ON_PAUSE、ON_STOP、ON_RESUME、ON_DESTROY、ON_ANY
}
在Activity中的使用:
publicclass XActivity extends AppCompatActivity implements LifecycleRegistryOwner {
privateLifecycleRegistry lifecycleRegistry =newLifecycleRegistry(this);
//在onCreate()函数中初始化控件 mtx
mtx .setLifecycle(getLifecycle());
//lifecycle观察者 LifecycleObserver:自定义的类 MyView
//lifecycle注册拥有者 LifecycleRegistryOwner:XActivity
getLifecycle().addObserver(mtx); //添加观察者角色
mtx .setLifeCycleEnable(true);
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
}
按home键进行观察日志:
creat -> start -> resume -> pause -> stop -> start -> resume
02-24 16:18:31.188 4694-4694/proxy.lifecycledemo E/MyView: Hello World!-creat
02-24 16:18:31.198 4694-4694/proxy.lifecycledemo E/MyView:-start
02-24 16:18:31.198 4694-4694/proxy.lifecycledemo E/MyView:-resume
02-24 16:32:46.058 4694-4694/proxy.lifecycledemo E/MyView:-pause
02-24 16:32:46.798 4694-4694/proxy.lifecycledemo E/MyView:-stop
02-24 16:32:47.988 4694-4694/proxy.lifecycledemo E/MyView:-start
02-24 16:32:47.988 4694-4694/proxy.lifecycledemo E/MyView:-resume
解析:LifecycleOwner是一个只有一个方法的接口getLifecycle(),需要由子类来实现。
在Lib中已经有实现好的子类,我们可以直接拿来使用。比如LifecycleActivity和LifecycleFragment,我们只需要继承此类就行了。
当然实际开发的时候我们会自己定义BaseActivity,Java是单继承模式,那么需要自己实现LifecycleRegistryOwner接口。
如下所示即可,代码很近简单
public class BaseFragment extends Fragment implements LifecycleRegistryOwner {
LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
}
Lifecycle的最佳建议
- 保持UI Controllers(Activity/Fragment)中代码足够简洁。一定不能包含如何获取数据的代码,要通过ViewModel获取LiveData形式的数据。
- 用数据驱动UI,UI的职责就是根据数据改变显示的内容,并且把用户操作UI的行为传递给ViewModel。
- 把业务逻辑相关的代码放到ViewModel中,把ViewModel看成是链接UI和App其他部分的胶水。但ViewModel不能直接获取数据,要通过调用其他类来获取数据。
- 使用DataBinding来简化View(布局文件)和UI Controllers(Activity/Fragment)之间的代码
- 如果布局本身太过复杂,可以考虑创建一个Presenter类来处理UI相关的改变。虽然这么做会多写很多代码,但是对于保持UI的简介和可测试性是有帮助的。
- 不要在ViewModel中持有任何View/Activity的context。否则会造成内存泄露。
系列文章列表: