Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Jetpack Lifecycle-Aware Components #3

Open
xxm-sz opened this issue Jun 27, 2019 · 0 comments
Open

Android Jetpack Lifecycle-Aware Components #3

xxm-sz opened this issue Jun 27, 2019 · 0 comments

Comments

@xxm-sz
Copy link
Owner

xxm-sz commented Jun 27, 2019

为什么需要我们管理Activity和Fragment的生命周期?这些不是Framework自动帮我们搞定的么?(手动黑人问号)刚看到这样的标题我也是很懵逼,不就是onCreate->onSart()->onResume()->onPause()->onStop()->onDestory()么?难道还有什么高深的地方么?

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对象跟踪组件的当前状态。

生命周期状态
方框中的INITALZIEDDESTROYED等等表示组件的状态,而箭头上的ON_CREATEON_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 和更低版本提供的方法。

总结

本文是对官网知识的理解或翻译,建议再进一步阅读原文,毕竟原文才是原汁原味,知识点也多。

Google Android Developer 官网

从第一次看官网懵懵懂懂,到开始了解,又掌握一个知识点。不仅光讲Lifecycle-Aware Components的知识点,还讲到平常开发应用的最佳实践,这些对实际开发都有很强指导作用。

坚持初心,写优质好文章

开文有益,Star支持好文

@xxm-sz xxm-sz changed the title Android Jetpack Lifecycle-Aware Components 生命周期管理组件入门 Android Jetpack Lifecycle-Aware Components Jun 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant