Android官方架构组件介绍之LifeCycle(一)
Android官方架构组件介绍之LifeCycle
下面是官方提供的Android App开发的架构图:

从上图可以看到一些关键字:ViewModel,LiveData,Room等。其实看了上面视频的会发现Google官方Android架构组件一共包括以下几个:
- LifeCycle : 与Activity和Fragment的生命周期有关
 - LiveData :异步可订阅数据,也是生命周期感知
 - ViewModel :视图数据持有模型,也是生命周期感知
 - Room :SQLite抽象层,用于简化SQLite数据存储
 
这篇文章主要讲解LifeCycle在项目的简单用法
AS中添加依赖
首先在工程根目录的build.gradle中添加一下内容:
allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }  //添加此行
    }
}
然后在应用目录下的build.gradle中添加以下依赖:
//For Lifecycles, LiveData, and ViewModel
compile "android.arch.lifecycle:runtime:1.0.0-alpha1"
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1" //For Room
compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
LifeCycle相关使用
在我们平时的项目中经常会遇到很多需要依赖生命周期的逻辑处理,比如有这么一个需求。
在某个Activity我们需要在屏幕上展现用户的地理位置。简单的实现方法如下:
lass 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();
    }
}
虽然以上代码看起来很简洁,但在实际项目中的onStart,onStop方法可能会变得相当庞大。
此外,实际情况可能并不像上面这么简单,例如我们需要在start位置监听前做用户状态检测,检测是一个耗时的任务,那么很有可能在检测结束前用户提前退出了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
LifeCyle类持有Activity或者Fragment的生命周期相关信息,并且支持其他对象监听这些状态。
LifeCyle有两个枚举用于追踪生命周期中的状态。
Event
这是生命周期的事件类,会在Framework和LifeCycle间传递,这些事件映射到Activity和Fragment的回调事件中。
State
LifeCycle所持有Activity或Fragment的当前状态。
一个类想要监听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是一个只有一个方法的接口用于表明其有一个LifeCycle对象。这个方法为getLifecycle()。
这个对象给Acitivity,Fragment和LifeCycle提供了一个很好的抽象关系,Activity和Fragment只要实现这个接口就能配合LifeCycle实现生命周期监听。
注意:由于目前LifeCycle处于alpha阶段,所以Fragment和AppCompatActivity并不会实现这些方法,在此之前,可以使用
LifecycleActivity和LifecycleFragment。等LifeCycle趋于稳定后,Fragment和AppCompatActivity会默认实现这些。
对于之前的位置监听的例子,我们可以让MyLocationListener继承LifecycleObserver,在onCreate中使用LifeCycle进行初始化,剩下的问题则不必担心了。因为MyLocationListener有能力进行生命周期的判断。
class MyActivity extends LifecycleActivity {
    private MyLocationListener myLocationListener;
    public void onCreate(...) {
        //此处进行初始化getLifecycle()传入LifeCycle对象
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {
            // update UI
        });
        //检测用户状态并启用监听
        Util.checkUserStatus(result -> {
            if (result) {
                myLocationListener.enable();
            }
        });
  }
}
下面看一下MyLocationListener
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
    }
}
LifeCycle最重要的特性就是在⓵处,他可以提供主动查询生命周期状态的方法。这样就避免了上面遇到的myLocationListener.start()在myLocationListener.stop()后面调用的问题。
通过以上的实现,我们的LocationListener是完全的生命周期感知了,它可以进行自己的初始化和资源清理而不必受Activity或者Fragment的管理。这时候如果我们在其他Activity或者Fragment中使用LocationListener,我们只需要初始化它就行了,不必再担心生命周期对它的影响,因为它内部会做好这一切。
通过LefeCycle工作的类我们称之为生命周期感知。鼓励需要使用Android生命周期的类的库提供生命周期感知组件,以便客户端可以轻松地在客户端上集成这些类,而无需手动生命周期管理。
LiveData就是生命周期感知组件的示例,将LiveData和ViewModel一起使用,可以在遵循Android生命周期的情况下,更容易的使用数据来填充UI。
生命周期的最佳实践
- 保持你的UI(Activity和Fragment)尽可能简洁。它们不应该试图获取它们的数据而是使用ViewModel来执行此操作,并通过LiveData的回调将数据更新到UI中。
 - 尝试编写数据驱动的UI,你的UI的责任是在数据更改时更新视图,或将用户操作通知给ViewModel。
 - 将你的数据逻辑放在ViewModel类中。 ViewModel应该作为UI和其他数据操作的连接器。值得注意的是,ViewModel并不负责提取数据(例如,从网络)。相反,ViewModel应该调用其他接口来执行此工作,然后将结果提供给UI。
 - 使用
Data Binding可以让你的的UI代码变得相当干净利落。这将使你的UI更具声明性,并最大限度地减少书写UI更新的代码。如果您更喜欢在Java中执行此操作,请使用像Butter Knife这样的库来避免使用样板代码并进行更好的抽象。 - 如果你有一个复杂的UI,请考虑创建一个Presenter类来处理UI修改。这通常是过度架构的,但可能有助于使你的UI更容易测试。
 - 不要在ViewModel中引用View或Activity上下文。如果ViewModel在Activity或View销毁的情况下依旧存活,这时将导致内存泄漏。
 
补充
在自定义的Activity或Fragment中实现LifeCycleOwner,可以实现LifecycleRegistryOwner这个接口。而不是继承(LifeCycleFragment和LifeCycleActivity)
public class MyFragment extends Fragment implements LifecycleRegistryOwner {
    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }
}
如果你要在自定义的类中实现LifeCycleOwner,可以使用LifecycleRegistry,但是你需要主动向其转发生命周期的事件。但如果你自定义类是Fragment和Activity的话并且它们实现的是LifecycleRegistryOwner,那么事件转发都是自动完成的。
Android官方架构组件介绍之LifeCycle(一)的更多相关文章
- Android官方架构组件介绍之LifeCycle
		
Google 2017 I/O开发者大会于近日召开,在开发者大会上谷歌除了发布了Android O等一些新产品之外,也对Android代码的架构做出了一个官方的回应. Google 2017 I/O开 ...
 - Android官方架构组件介绍之ViewModel
		
ViewModel 像Activity,Fragment这类应用组件都有自己的生命周期并且是被Android的Framework所管理的.Framework可能会根据用户的一些操作和设备的状态对Act ...
 - Android官方架构组件介绍之LiveData
		
LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...
 - Android官方架构组件介绍之ViewModel(三)
		
ViewModel 像Activity,Fragment这类应用组件都有自己的生命周期并且是被Android的Framework所管理的.Framework可能会根据用户的一些操作和设备的状态对Act ...
 - Android官方架构组件介绍之LiveData(二)
		
LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...
 - Android官方架构组件介绍之应用(四)
		
讲一个项目常见的功能,友盟统计功能 例如一个项目有很多多modlue,每个里面modlue都有Activity,Activity需要友盟统一,Fragment也需要友盟统计.一般做法就是继承一个Bas ...
 - 改造 Android 官方架构组件 ViewModel
		
前言 Android 官方架构组件在今年 5 月份 Google I/O 大会上被公布, 直到 11 月份一直都是测试版, 由于工作比较繁忙, 期间我只是看过类似的文章, 但没有在实际项目中使用过, ...
 - Android官方架构组件指南
		
此指南适用于那些曾经或现在进行Android应用的基础开发,并希望了解和学习编写Android程序的最佳实践和架构.通过学习来构建强大的生产级别的应用. 注意:此指南默认你对Android开发有比较深 ...
 - Jetpack架构组件学习(1)——LifeCycle的使用
		
原文地址:Jetpack架构组件学习(1)--LifeCycle的使用 | Stars-One的杂货小窝 要看本系列其他文章,可访问此链接Jetpack架构学习 | Stars-One的杂货小窝 最近 ...
 
随机推荐
- 95E Lucky Country
			
传送门 题目大意 如果一个数中不包含除4和7之外的数字则是幸运数.有n个岛屿,通过双向道路连接.这些岛屿被分为几个地区.每个岛属于恰好一个区域,同一区域中的任何两个岛之间存在道路,不同区域的任何两个岛 ...
 - CF 1029E Tree with Small Distances
			
昨晚随便玩玩搞个div3结果浪翻了…… 强烈谴责D题hack数据卡常 考虑到本题中所要求的最短距离不会大于2,所以我们可以把所有结点到$1$的距离通过对$3$取模分类,考虑到直接自顶向下贪心不满足局部 ...
 - mysql双机热备份的实现步骤
			
MySQL 提供了数据库的同步功能,这对我们实现数据库的冗灾.备份.恢复.负载均衡等都是有极大帮助的.本文描述了常见的同步设置方法.<?xml:namespace prefix = o /> ...
 - asp.net core tags 扩展之 id 和 name
			
asp.net core 页面 TagHelper 的 Id 和 Name 属性扩展 . [HtmlTargetElement(Attributes = "asp-name")] ...
 - Join方法把阵列转为字符串
			
string有一个方法,就是Join,可以把阵列转换为字符串: 下面是Join方法重载,可以指定那个元素开始,连续取几个元素: 可以传入一个IEnumerable<T>参数:
 - Docker基本使用(二) Hello World
			
Docker 允许你在容器内运行应用程序, 使用 docker run 命令来在容器内运行一个应用程序. 输出Hello world runoob@runoob:~$ docker run ubunt ...
 - ubuntu - 14.10,安装uget和aria2(下载工具)
			
Windows下的下载工具--迅雷,之所以下载速度快,乃是它能搜索资源.为己所用,而不是仅仅从原始地址这单一资源处下载. Ubuntu下也有类似的工具,那就是aira2. aira2是一个命令行下载工 ...
 - 我的iphone不能被虚拟机识别怎么办
			
我的iphone不能被虚拟机识别怎么办 听语音 | 浏览:3890 | 更新:2015-11-04 15:28 | 标签:iphone vmware ios 1 2 3 4 5 6 分步阅读 特大喜讯 ...
 - CI框架源码学习笔记7——Utf8.php
			
愉快的清明节假期结束了,继续回到CI框架学习.这一节我们来看看Utf8.php文件,它主要是用来做utf8编码,废话不多说,上代码. class CI_Utf8 { /** * Class const ...
 - UVA10173 Smallest Bounding Rectangle 最小面积矩形覆盖
			
\(\color{#0066ff}{题目描述}\) 给定n(>0)二维点的笛卡尔坐标,编写一个程序,计算其最小边界矩形的面积(包含所有给定点的最小矩形). 输入文件可以包含多个测试样例.每个测试 ...