zoukankan      html  css  js  c++  java
  • Android Architecture Components 系列(二) LifeCycle

    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。否则会造成内存泄露。
  • 相关阅读:
    uniapp,获取用户地理位置信息授权,如果拒绝的话需要引导用户重新请求授权操作
    sql group by 之别扭
    echart.js 遇到的问题及解决
    sql 时间截取 分组 获得小时数据常用的方法
    使用JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength属性
    C#中Math.Round()实现中国式四舍五入
    layui js出现一个form内和外的button 事件怪事
    Sql Server 查询指定范围(一周,一月,本周,本月等)内的数据
    java jdk1.6低版本ssm 源码的的在idea的搭建
    一个 jQuery循环获取点击事件,显示tab 子页
  • 原文地址:https://www.cnblogs.com/cold-ice/p/9115810.html
Copyright © 2011-2022 走看看