文档章节

Android Architecture Components之处理生命周期

dj_归去来兮
 dj_归去来兮
发布于 2017/08/14 15:49
字数 1560
阅读 13
收藏 0

包  android.arch.lifecycle 提供了类和接口让你构建拥有生命周期的组件--可以根据activity或者fragment的生命周期做出调整的组件。

大部分的APP组件都是在Android框架中定义的,都会有生命周期。这些生命周期过程被操作系统或者框架代码管理着。它们是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()方法中就已经处于started状态了。如果我们需要在开始观察位置之前检查一些配置将会发生什么呢?有些情况是这样的:在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();
    }
}

包 android.arch.lifecycle 提供了类和接口帮助你通过富有弹性和独立的方式解决这些问题。

Lifecycle

Lifecycle 类持有关于activity或者fragment等组件的生命周期状态,允许其他对象观察这些状态。

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

Event:这些生命周期事件由框架和 Lifecycle发送。这些事件与activities和fragments回调事件一 一对应。

State: Lifecycle 对象追踪的组件的当前状态。

设想state是图表中的节点,event是两个节点之间的边框线。

通过在方法上加上注解,可以让一个类监控组件的生命周期。

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(),需要被子类实现。

这个类从个体类(activity,fragment)中抽象了生命周期的所有权,允许编写可以与它们一起工作的组件。任何一个自定义的应用类都可以实现这个接口。

针对上面的示例,我们可以使我们的MyLocationListener 类称为一个 LifecycleObserver ,然后通过 Lifecycle 的方法onCreate初始化它。

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的onSaveInstance方法调用之后,调用了运行fragment事物的回调方法,将会导致奔溃,所以,我们不要去调用那个回调方法。

为了让这个方案易于使用,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一起使用,更易于在遵循Android生命周期的情况下使用数据填充UI层。

Best practices for Lifecycles

    1 保持你的UI控制层(activities,fragments)越轻越好。它们不应该自己去取数据,相反,使用一个 ViewModel去做,并且观察 LiveData 反应到UI层上。

    2 尝试编写数据驱动UI,当数据变化时,你的UI层控制器负责更新控件,或者通知用户操作到ViewModel

    3 把数据操作逻辑放在ViewModel 类中,ViewModel 应该像UI层与其他APP组件之间的连接器。不过,要小心,获取数据(例如,从网路获取数据)并不是ViewModel 的责任。ViewModel 应该调用适当的组件去做这个工作,然后提供结果给UI层控制器。

    4 使用Data Binding在控件和控制器之间保持干净的接口。这允许在activity和fragment中,你把你的控件更声明化(声明性编程),并且更新最少的代码。

    5 如果你的UI很复杂,考虑创建一个presenter类持有UI的变化。这通常过度封装了,但是可以让UI层的测试更加容易。

    6 决不要在 ViewModel 层引用 View 或者Activity 上下文。如果ViewModel比activity的生命周期长的话,activity将会内存泄漏,不能正确的GC。

 

Addendum

Implementing LifecycleOwner in custom activities and fragments

任何一个自定义的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 接口,这个事件转发对fragments,activities会自动的进行。

来自 https://developer.android.google.cn/topic/libraries/architecture/lifecycle.html

© 著作权归作者所有

共有 人打赏支持
dj_归去来兮
粉丝 15
博文 113
码字总数 31739
作品 0
合肥
Android工程师
私信 提问
如何绑定页面生命周期(二)-基于Android Architecture Components的Lifecycle实现

上篇文章如何绑定页面生命周期(一)-Glide实现介绍了Glide实现生命周期感知的原理,这里我们再介绍基于Android Architecture Components的Lifecycle实现页面生命周期感知。 Lifecycle是And...

宇是我
07/29
0
0
Architecture Components MVVM架构演进

在对MVP的架构实践中,发现写单元测试不是那么方便,因为Presenter持有了View的引用,而Mock View的 行为和方法特别的卡慢,因此只能把具体的业务逻辑再抽成一个个独立于Presenter的Logic,进...

Mr云台
2017/11/27
0
0
MVP模式, 开源库mosby的使用及代码分析

Android中的构架模式一直是一个很hot的topic, 近年来Architecture components推出之后, MVVM异军突起, 风头正在逐渐盖过之前的MVP. 其实我觉得MVP还是有好处的, 比如灵活多变(其实只是我用起...

圣骑士wind
09/25
0
0
《Android构建MVVM》系列(一) 之 MVVM架构快速入门

前言   本文属于《Android构建MVVM》系列开篇,共六个篇章,详见目录树。   该系列文章旨在为Android的开发者入门MVVM架构,掌握其基本开发模式。   辅以讲解Android Architecture Co...

昕无旁骛
08/18
0
0
Architecture Components(1) - Lifecycles

一、概述 听说这一套已经有很长一段时间了,一直没有系统的学习过,前几天有同事在项目中通过解决了监听生命周期的问题,不得不说,真的是一套强大的框架,除此之外,前段时间还更新了、和用...

泽毛
07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

崛起于Springboot2.X之集成工作流Activiti5.22(42)

声明:该博客主要是Springboot1.X和Springboot2.X集成Activiti5.22版本,并说一下两个版本的搭建不同的地方 技术:Springboot2.0.3+mysql+jpa(自动生成25张表)+Activiti5.22 /然后Springboo...

木九天
16分钟前
2
1
windows环境下搭建rabbitMQ开发环境

windows环境下搭建rabbitMQ开发环境 下载与安装 erlang rabbitmq 是使用erlang语言开发的,所以需要erlang环境; 下载地址 rabbitmq 下载地址 rabbitmq与erlang版本关系 下载之后直接安装即可...

晨猫
27分钟前
1
0
JVM 中的守护线程

特点 通常由JVM启动 运行在后台处理任务,比如垃圾回收等 用户启动线程执行结束或者JVM结束时,会等待所有的非守护线程执行结束,但是不会因为守护线程的存在而影响关闭。 判断线程是否为守护...

小刀爱编程
31分钟前
1
0

参考 极客时间《数据结构与算法之美》

grace_233
44分钟前
2
0
谈谈KMP算法

KMP算法的资料网上已经一大把了,主要用来解决某个文本片段是否包含另一个子串问题。这里假设文本片段的长度n大于子串长度m,如: 文本串为ABCDABGHIJK 子串为 ABCDABE 在传统的暴力解法中当...

FAT_mt
45分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部