最新公告
  • 欢迎您光临AA分享网,一个高级程序员的学习、分享的分享平台!立即加入我们
  • 使用Lifecycle处理生命周期

    大多数Android Framework中的app组件都有自己的生命周期。这些生命周期由操作系统或者运行在你的进程中的框架代码所管理。它们是Android系统工作原理的核心,你必须遵守。否则就由可能会导致内存泄漏甚至崩溃。

    假设我们有一个显示设备所处位置的activity。常见的实现方式大致如下:

    class MyLocationListener {
        public MyLocationListener(Context context, Callback callback) {
            // ...
        }
        void start() {
            // connect to system location service
        }
        void stop() {
            // disconnect from system location service
        }
    }
    class MyActivity extends AppCompatActivity {
        private MyLocationListener myLocationListener;
        public void onCreate(...) {
            myLocationListener = new MyLocationListener(this, (location) -> {
                // update UI
            });
      }
        public void onStart() {
            super.onStart();
            myLocationListener.start();
        }
        public void onStop() {
            super.onStop();
            myLocationListener.stop();
        }
    }

    虽然这个例子看起来是正确的,但在真实的app中,最终可能会出现超多类似这样的调用,而且 onStart() 和 onStop()也会变得非常大。

    此外,有些控件不能直接在onStart()中启动。要是在开始定位监听之前需要检查一些配置怎么办?完全有可能在某些情况下activity停止之后检查才完成,也就是说myLocationListener.start() 可能会在myLocationListener.stop() 之后才被调用,基本上就是永远保持着连接了。

    class MyActivity extends AppCompatActivity {
        private MyLocationListener myLocationListener;
        public void onCreate(...) {
            myLocationListener = new MyLocationListener(this, location -> {
                // update UI
            });
        }
        public void onStart() {
            super.onStart();
            Util.checkUserStatus(result -> {
                // what if this callback is invoked AFTER activity is stopped?
                if (result) {
                    myLocationListener.start();
                }
            });
        }
        public void onStop() {
            super.onStop();
            myLocationListener.stop();
        }
    }

    Lifecycle提供了一套帮助你以一种灵活独立的方式处理这些问题的类。

    Lifecycle

    Lifecycle 是一个持有组件(比如 activity 或者 fragment)生命周期状态信息的类,并且允许其它对象观察这个状态。

    Lifecycle 主要使用两个枚举来跟踪相关组件的生命周期状态。

    Event

    framework和Lifecycle类发出的生命周期事件。这些事件对应Activity和Fragment中的回调事件。

    译注:

    Lifecycle.Event  ON_ANY

    An Event constant that can be used to match all events. 

    Lifecycle.Event  ON_CREATE

    Constant for onCreate event of the LifecycleOwner. 

    Lifecycle.Event  ON_DESTROY

    Constant for onDestroy event of the LifecycleOwner. 

    Lifecycle.Event  ON_PAUSE

    Constant for onPause event of the LifecycleOwner. 

    Lifecycle.Event  ON_RESUME

    Constant for onResume event of the LifecycleOwner. 

    Lifecycle.Event  ON_START

    Constant for onStart event of the LifecycleOwner. 

    Lifecycle.Event  ON_STOP

    Constant for onStop event of the LifecycleOwner. 

    State

     Lifecycle对象获取到的组件当前的状态。

    一个类可以通过在它的方法中添加注解来管理组件的lifecycle。

    public class MyObserver implements LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        public void onResume() {
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        public void onPause() {
        }
    }
    aLifecycleOwner.getLifecycle().addObserver(new MyObserver());

    LifecycleOwner

    LifecycleOwner 是一个只有单个方法的接口,代表类具有生命周期。这个唯一的方法是getLifecycle(),必须实现。

    这个类把 Lifecycle从各个生命周期组件(比如Activity和Fragmennt)中抽象出来,从而写一个两者都适用的组件。任何一个自定义的application类都可以实现 LifecycleOwner 接口。

    注:因为Lifecycle项目还处于alpha阶段,Fragment 和 AppCompatActivity 类还不能实现它(因为我们不能让一个稳定的控件依赖于一个不稳定的API)。在Lifecycle 稳定之前,我们提供 LifecycleActivity 和 LifecycleFragment 方便大家使用。当Lifecycle项目正式发布之后,支持库中的fragment和Activity将实现 LifecycleOwner ;届时LifecycleActivity 和 LifecycleFragment 将被视作过时的类。 可以参考 自定义Activity或者Fragment实现LifecycleOwner。

    对于前面的例子,我们可以把MyLocationListener类写成 LifecycleObserver,在onCreate中使用我们的Lifecycle初始化之,然后就不用再管他了。这让MyLocationListener类可以自给自足,在必要的时候自己做清理。

    class MyActivity extends LifecycleActivity {
        private MyLocationListener myLocationListener;
        public void onCreate(...) {
            myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
                // update UI
            });
            Util.checkUserStatus(result -> {
                if (result) {
                    myLocationListener.enable();
                }
            });
      }
    }

    常见的用例就是在 Lifecycle 不合适的时候不触发某个回调。比如,如果回调在activity回收状态之后运行fragment transaction的话,会出现崩溃,因此我们绝对不会想触发那个回调。

    为了让这种用例处理起来简单, Lifecycle 允许其它的对象查询当前的状态。

    class MyLocationListener implements LifecycleObserver {
        private boolean enabled = false;
        public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
           ...
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        void start() {
            if (enabled) {
               // connect
            }
        }
        public void enable() {
            enabled = true;
            if (lifecycle.getState().isAtLeast(STARTED)) {
                // connect if not connected
            }
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        void stop() {
            // disconnect if connected
        }
    }

    这样实现之后,我们的LocationListener类就完全有了生命周期意识;它可以无需activity管理,自己做初始化和清理的工作。如果我们需要在其它的activity或者fragment中使用这个LocationListener,我们只需要初始化它酒醒了。所有的清理工作都由它自己完成。

    可以和Lifecycle一起工作的类我们称之为有生命周期意识的控件。我们建议那些提供了需要和Android生命周期打交道的类的库最好提供有生命周期意识的控件,这样它们的用户就能轻松的集成这些类,而不是在客户端手动管理生命周期。

    LiveData 就是一个有生命周期意识的控件的例子。使用LiveData 和 ViewModel 可以让数据部署到UI更简单。

    Lifecycle最佳实践

    • 尽可能保持UI控制器(Activity和Fragment)的简洁。它们不应该去获取数据,而是使用ViewModel 来做这个工作,然后观察LiveData 把变化反应给view。

    • 尝试写数据驱动的UI,UI controller的职责是在数据改变的时候更新view,或者把用户的操作通知给ViewModel。

    • 把数据逻辑放在ViewModel 类中。ViewModel的角色是UI控制器与app其余部分的桥梁。不过要注意,ViewModel的职责并不是获取数据(比如,从网络)。相反 ViewModel应该调用合适的控件去做这件事情,然后把结果提供给UI控制器。

    • 使用 Data Binding来让view和UI控制器之间的接口保持干净。这可以让你的view更加声明式同时最小化Activity和Fragment中的代码。如果你更喜欢用Java代码做这件事情,使用 Butter Knife来避免繁琐的代码。

    • 如果你的UI非常复杂,考虑创建一个Presenter类来处理UI的变动。通常这会有点多余,但可能会让UI的测试更加简单。

    • 绝对不要在 ViewModel中引用View 或者 Activity 的context。如果ViewModel活的比Activity更长,Activity可能会泄漏,无法正常回收。

    自定义Activity或者Fragment实现LifecycleOwner

    任何自定义的fragment或者activity都可以通过实现LifecycleRegistryOwner 接口变成一个 LifecycleOwner(而不是继承LifecycleFragment 或者 LifecycleActivity)。

    public class MyFragment extends Fragment implements LifecycleRegistryOwner {
        LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
        @Override
        public LifecycleRegistry getLifecycle() {
            return lifecycleRegistry;
        }
    }

    如果你有一个自定义的类想成为 LifecycleOwner, 你可以使用 LifecycleRegistry 类,但是你需要向那个类传递事件。这个传递在实现了LifecycleRegistryOwner接口的fragment或者activity中是自动完成的。

    AA分享网一个高级程序员的学习、分享的IT资源分享平台
    AA分享网-企业网站源码-PHP源码-网站模板-视频教程-IT技术教程 » 使用Lifecycle处理生命周期
    • 263会员总数(位)
    • 5946资源总数(个)
    • 2本周发布(个)
    • 0 今日发布(个)
    • 575稳定运行(天)

    提供最优质的资源集合

    立即查看 了解详情