内容简介:为什么需要我们管理Activity和Fragment的生命周期?这些不是Framework自动帮我们搞定的么?(手动黑人问号)刚看到这样的标题我也是很懵逼,不就是onCreate->onSart()->onResume()->onPause()->onStop()->onDestory()么?难道还有什么高深的地方么?在讲Data Bing Library的文章中,大多数同学反馈在实际开发中没什么必要。因为没深爱过,没法名正言顺为其正名。恰好周末逛到如果你对Data Binding Library有独特的见
为什么需要我们管理Activity和Fragment的生命周期?这些不是Framework自动帮我们搞定的么?(手动黑人问号)刚看到这样的标题我也是很懵逼,不就是onCreate->onSart()->onResume()->onPause()->onStop()->onDestory()么?难道还有什么高深的地方么?
题外话
在讲Data Bing Library的文章中,大多数同学反馈在实际开发中没什么必要。因为没深爱过,没法名正言顺为其正名。恰好周末逛到 郭霖公众号 一篇讲Data Bing 在RecyclerView的实践,讲的挺好,大家有空移步前去阅读。引用《卖油翁的故事》道理->熟能生巧,爱得够深,就能擦出火花。
如果你对Data Binding Library有独特的见解或看法,可以前往 Data Binding Library(数据绑定库) 讨论
Abount Lifecycle-Aware Components
该组件能在像Activity、Fragment等等具有生命周期的组件发生状态改变时,以轻量级的和易维护的代码作出响应动作。
吃个栗子就懂意思了:
//为了考虑大多数同学学习过Java,就贴 Java 的代码 //定义个监听类,用来在Activity生命周期发生变化时,对定位服务资源作相关处理 class MyLocationListener { public MyLocationListener(Context context, Callback callback) { // ... } void start() { // connect to system location service } void stop() { // disconnect from system location service } } //在Activity中回调监听类相关方法 class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; @Override public void onCreate(...) { myLocationListener = new MyLocationListener(this, (location) -> { // update UI }); } @Override public void onStart() { super.onStart(); myLocationListener.start(); // manage other components that need to respond // to the activity lifecycle } @Override public void onStop() { super.onStop(); myLocationListener.stop(); // manage other components that need to respond // to the activity lifecycle } } 复制代码
毕竟拿人手短,吃人嘴软,吃了人家的栗子就得给人家分析。
这个栗子还是挺简单的,只是简单调用了MyLocationListener对象的两个回调方法,但是在实际开发中,大多数情况下会在Activity的onCreate()、onStart()等等生命周期中做大量的业务逻辑处理和UI更新,而且如果不止一个监听类需要被回调的话,就意味着要在Activity中管理多个其他组件的生命周期或者回调。那代码的维护性和可读性就非常差。(另外,在发生某种竞态条件的情况下,可能会导致Activity的onStop()方法在onStart()方法前就发生了)
为了解决这种痛点,在包 android.arch.lifecycle
中提供类和接口来独立的管理Activity和Fragment组件的生命周期。
Lifecycle
生命周期是一个类包含组件的生命周期状态的信息(例如Activity和Fragment),并允许其他对象观察到这个状态。 Lifecycle
对象以两种主要的枚举类型跟踪它关联组件的生命周期状态:
- Event Framework和Lifecycle类分发生命周期事件(Lifecycle Event),并映射到Activity或者Fragment的回调事件。
- State Lifecycle对象跟踪组件的当前状态。
INITALZIED
、
DESTROYED
等等表示组件的状态,而箭头上的
ON_CREATE
、
ON_START
等等则表示事件。假如Framework或者Lifecycle类分发
ON_CREATE
事件,表示关联的组件的状态从初始化到onCreate状态,对应调用组件的onCreate()方法。
通过在类的方法上添加注解来监听组件的生命周期。然后将该类以观察者形式添加到具有生命周期的类中。
//MyObserver作为一个观察者来监听有生命周期的类 public class MyObserver implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void connectListener() { ... } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void disconnectListener() { ... } } //myLifecycleOwner是一个实现了LifecycleOwner 接口的类,继续看下文 myLifecycleOwner.getLifecycle().addObserver(new MyObserver()); 复制代码
LifecycleOwner
LifecycleOwner,是只有一个 getLifecycle()
方法的接口,实现该接口的类表示具有生命周期。如果想管理整个应用的生命周期,用 ProcessLifecycleOwner
代替 LifecycleOwner
。LifecycleOwner接口将所有具有生命周期的类的生命周期所有权抽象出来,以方便可以在其生命周期进行读写。实现了LifecycleObserver接口的类可以注册到实现了 LifecycleOwner
的类,以观察对应组件的生命周期。例如上文的:
myLifecycleOwner.getLifecycle().addObserver(new MyObserver()); 复制代码
这样做带来的好处是什么? 通过这种观察者模式,可以将平常根据Activity或Fragment生命周期状态的逻辑分离到单独类中进行处理,以便更好的逻辑开发、功能迭代和后期维护。
class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, getLifecycle(), location -> { // update UI }); Util.checkUserStatus(result -> { if (result) { myLocationListener.enable(); } }); } } 复制代码
讲到这里基本就已经知道如何使用Lifecycle-Aware Components管理Activity或Fragment的生命周期了。如果LifecycleObserver需要监听其他Activity或Fragment的生命周期,只需要重新初始化并注册到新的Activity或Fragment即可。资源的设置和清除回收不需要我们担心。
Custom LifecycleOwner
在Support Library 26.1.0和更高版本,Activity和Fragment已经默认实现了LifecycleOwner。如果要实现定制的LifecycleOwner,需要新建 LifecycleRegistry
对象,并将相关事件传递给它。
public class MyActivity extends Activity implements LifecycleOwner { private LifecycleRegistry lifecycleRegistry; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); lifecycleRegistry = new LifecycleRegistry(this); lifecycleRegistry.markState(Lifecycle.State.CREATED); } @Override public void onStart() { super.onStart(); lifecycleRegistry.markState(Lifecycle.State.STARTED); } @NonNull @Override public Lifecycle getLifecycle() { return lifecycleRegistry; } } 复制代码
最好实践
- 保持UI(Activity或Fragment)精简。不要在Activity或Fragment中取获取应用数据,采用ViewModel或者Livedata。也就是为什么有MVP、MVVM模式。
- 尝试写数据驱动类型UI。在数据发生变化的时候通过UI控制器更新UI或者通知用户进行操作。
- 把数据的处理逻辑放到
ViewModel
类中。ViewModel
作为UI界面与数据的桥梁,处理数据与UI界面交互的逻辑。注意不是获取数据的逻辑,例如获取网络数据或者数据库数据。 - 使用数据绑定库(Data Binding Library)在UI界面和UI控制器之间进行维护。这样有利于减少在Activity或Fragment中更新UI的代码。在Java中可以使用
Butter Knife
库。 - 如果UI界面很复杂,可以建立一个主持(Presenter)类去处理视图。MVP模式?
- 使用Kotlin协同机制管理耗时任务。
使用lifecycle-aware components的场景
lifecycle-aware组件在不同情况能让我们更方便的管理Acitivity和Fragment的生命周期。那在什么情景下适合使用该组件呢?
- 粗细粒度的切换。例如在定位中,如果当前界面可见,那么定位精度应该更细,定位请求更频繁,以提高响应性。当切换到后台时,请求定位的频率就要放缓,以降低功耗
- 开始和停止视频缓冲。这个是高手,在应用加载的时候尽早缓冲视频,减少用户等待时间在应用退出是结束缓冲。
- 开始和停止网络连接。根据App状态自动切换连接的状态。
- 开始和停止绘制图片。应用在后台时不会绘制,返回前台继续绘制。
存在的一些问题
当Fragment或AppCompatActivity在调用onSaveInstanceState()方法保存状态后,它们的视图在 ON_START
事件被调用之前是不会改变的,在这期间UI被更改会引起不一致的问题,这就是为什么FragmentManager在状态保存后运行FragmentTransaction会抛出异常。
因此如果AppCompatActivity的onStop()方法在调用onSaveInstanceState()方法之后,就会造成一个缺口:UI状态改变是不允许,但生命周期还没有改为 CREATED
的状态。为此,Lifecycle类通过将状态标记为 CREATED
,但直到调用onStop()方法前,不分发该事件,此时去检测当前的状态也可获得真实的值。但是还存在以下两个问题:
- 在Android 6.0和更低版本,系统调用onSaveInstanceState()方法,但它不一定调用onStop()方法。这样就会造成事件无法分发,潜在的导致观察者以为lifecycle处于活动状态,尽管此时它处于停止状态。
- 任何想要在LiveData暴露类似行为的类必须实现Lifecycle 版本 beta 2 和更低版本提供的方法。
总结
本文是对官网知识的理解或翻译,建议再进一步阅读原文,毕竟原文才是原汁原味,知识点也多。
从第一次看官网懵懵懂懂,到开始了解,又掌握一个知识点。不仅光讲Lifecycle-Aware Components的知识点,还讲到平常开发应用的 最佳实践 ,这些对实际开发都有很强指导作用。
开文有益, 点赞 支持好文
本文是Jetpack系列文章第二篇
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。