Android Jetpack 组件是库的集合,这些库是为了协同工作而构建的,不过也可以单独采用,接下来会一一详细地学习这些库, 下面源码版本是com.android.support:appcompat-v7:28.0.0, 以及库android.arch.lifecycle:extensions:1.1.1

Lifecycles库是拿来干什么的

这个库从系统框架层去管理具有生命周期的组件,例如activity, fragment。让开发更方便地去管理自己应用里需要和activity或者fragment绑定的组件,让代码更容易维护。

也许有点抽象,举个例子说明一下,比如有个需求,需要在一个界面比较频繁更新地理位置信息。当Activity走了onstop之后,你应该也要暂停更新地理位置,或者当Activity走destroy后,你要释放一些资源。下面用一些代码实例解析一下,你的代码也许是这样的:

class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
} void start() {
// 开始连接位置服务
} void stop() {
// 停止连接位置服务
} void destroy(){
//释放资源
}
} class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener; @Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, new Callback(){
//回调更新UI
});
} @Override
public void onStart() {
super.onStart();
myLocationListener.start();
//绑定actiivty的onStart周期函数
} @Override
public void onStop() {
super.onStop();
myLocationListener.stop();
//绑定actiivty的onStop周期函数
} @Override
public void onDestroy() {
super.onDestroy();
myLocationListener.destroy();
//绑定actiivty的onDestroy周期函数
}
}
复制代码

上面的代码在简单app看起来也许还好,但是当你activity业务逻辑比较多,可能包含很多和生命周期绑定的自定义组件,代码长期积累就很难维护啦。

下面在看看使用Lifecycles库的代码做对比:

class MyLocationListener implements LifecycleObserver{
public MyLocationListener(Context context, Callback callback) {
// ...
} @OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
// 开始连接位置服务
} @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void stop() {
// 停止连接位置服务
} @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void destroy(){
//释放资源
}
} class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener; @Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, new Callback(){
//回调更新UI
});
getLifecycle().addObserver(myLocationListener);
}
}
复制代码

MyLocationListener实现LifecycleObserver, 在相应的方法添加OnLifecycleEvent注解就可以收到相应的回调,在Activity的onCreate方法里调用 getLifecycle().addObserver(myLocationListener)即可。下面结合源码分析Lifecycles库, 去更好地学习这个库。

Lifecycles库核心类与结构

Support Library 26.1.0 版本以及之后的版本,AppCompatActivity和Fragment实现了LifecycleOwner。类图如下所示:

Lifecycles库核心就是订阅者模式。

LifecycleOberver类:只是个空接口, 安卓生命周期观察者,

Lifecycle类: 是个抽象类,定义了安卓生命周期对象,有3个方法,添加观察者,移除观察者,获取当前状态。

LifecycleOwner类: 是个接口, 安卓生命周期的拥有者

LifecycleRegistry: Lifecycle的实现类,实现了添加、移除观察者,分派观察者状态等

自定义类实现LifecycleOberver接口,在方法中添加OnLifecycleEvent注解就可以收到相应生命周期的状态

public @interface OnLifecycleEvent {
Lifecycle.Event value();
} public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
//Event是Lifecycle内部类一个枚举类, 分别定义了onCreate, onStart, onResume, onPause,onStop,onDestroy, onAny这几个Event public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED; public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}//State也是Lifecycle内部类一个枚举类, 定义了INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED几种状态
复制代码

Lifecycle的各个状态以及事件分发过程如下图所示: (该图来自google官网文档)

矩形代表状态,一共有5个状态,记录在枚举State中, 依次是DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED;

箭头上面代表分发的Event:

  • 当分发ON_CREATE事件时,State由INITIALIZED -> CREATED;
  • 当分发ON_START事件时, State由CREATED -> STARTED
  • 当分发ON_RESUME事件时, State由STARTED -> RESUMED
  • 当分发ON_PAUSE事件时, State由RESUMED -> STARTED
  • 当分发ON_STOP事件时, State由STARTED -> CREATED
  • 当分发ON_DESTROY事件时, State由CREATED -> DESTROYED

你会发现State没STOPED和PAUSED的状态, 当State=CREATED时, Activity大概是在onCreate调用后或者onStop调用后;当State=STARTED时, Activity大概是在onStart调用后或者onPause调用后

ComponentActivity分发Event的过程

下面截取部分ComponentActivity的关键代码

public class ComponentActivity extends Activity implements LifecycleOwner{
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this); //利用Fragment来分发
} @CallSuper
@Override
protected void onSaveInstanceState(Bundle outState) {
mLifecycleRegistry.markState(Lifecycle.State.CREATED); //onSaveInstanceState是用来恢复Activity状态的, 这里记录的状态是CREATED
super.onSaveInstanceState(outState);
} @Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry; //返回LifecycleRegistry
}
}
复制代码

下面再看ReportFragment类关键代码:

    public static void injectIfNeededIn(Activity activity) {
// 为当前activity add 一个ReportFragment,用于分发event
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
} @Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatch(Lifecycle.Event.ON_CREATE); //分发ON_CREATE Event
} @Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);//分发ON_START Event
} @Override
public void onResume() {
super.onResume();
dispatch(Lifecycle.Event.ON_RESUME);//分发ON_RESUME Event
} @Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);//分发ON_PAUSE Event
} @Override
public void onStop() {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);//分发ON_STOP Event
} @Override
public void onDestroy() {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);//分发ON_DESTROY Event
} private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
// Activity是实现LifecycleOwner接口,这里可以跳过
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
} if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
//最终调用LifecycleRegistry.handleLifecycleEvent(event)处理event分发
}
}
}
复制代码

ComponentActivity的是Event分发是通过添加一个ReportFragment, 通过重写ReportFragment的onActivityCreated, onStart, onResume, onStop, onPause, onDestroy方法,最终交给LifecycleRegistry.handleLifecycleEvent(event)处理。

Fragment分发Event的过程

下面也是截去相关v4里Fragment的相关源码

    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
} void performCreate(Bundle savedInstanceState) {
...
onCreate(savedInstanceState);
...
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
} void performStart() {
...
onStart();
...
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
} void performResume() {
...
onResume();
...
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
} void performPause() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
...
onPause();
...
} void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
...
onStop();
...
} void performDestroy() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
...
onDestroy();
...
}
复制代码

LifecycleRegistry.handleLifecycleEvent(event)处理。 至于LifecycleRegistry这个类更多的细节就不展开啦

自定义LifecycleOwner

前面提到Support Library 26.1.0 版本以及之后的版本,AppCompatActivity和Fragment实现了LifecycleOwner, 如果你还用旧的版本或者继承Activity, 你可以通过自定义Activity或者Fragment实现。自定义实现代码如下:

//可以单独引入androidx.lifecycle:lifecycle-runtime:$lifecycle_version库
public class MyActivity extends Activity implements LifecycleOwner {
private LifecycleRegistry mLifecycleRegistry; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLifecycleRegistry = new LifecycleRegistry(this);
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
} @Override
public void onStart() {
super.onStart();
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
} .... @NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
复制代码

使用ProcessLifecycleOwner监听整个App进程的前后台

要注意ON_CREATE的Event之后分发一次,ON_DESTROY不会分发

public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleObserver() { private static final String TAG = "ProcessLifecycleOwner"; @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate(){
Log.d(TAG, "onCreate: "); //应用启动只被调用一次
} @OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart(){
Log.d(TAG, "onStart: "); //应用启动会调用一次, 从后台回来也会调用
} @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume(){
Log.d(TAG, "onResume: "); //应用启动会调用一次, 从后台回来也会调用
} @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause(){
Log.d(TAG, "onPause: "); //按home键或者切换应用会调用
} @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop(){
Log.d(TAG, "onStop: "); //按home键或者切换应用会调用
} });
}
复制代码

要注意ON_PAUSE, ON_STOP的回调会有700毫秒的延迟, 官方的解析是保证不要由于配置更改而销毁和重新Activity时不会分发任何事件。还有一点,如果你的app是多进程应用,ProcessLifecycleOwner只能用来监听主进程。

更多细节参考:developer.android.google.cn/reference/a…

下面简单说一下ProcessLifecycleOwner的工作原理:

// ProcessLifecycleOwner 关键代码
public class ProcessLifecycleOwner implements LifecycleOwner{ private int mStartedCounter = 0; // 计数器
private int mResumedCounter = 0; // 计数器 void activityResumed() {
mResumedCounter++;
if (mResumedCounter == 1) {
if (mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mPauseSent = false;
} else {
mHandler.removeCallbacks(mDelayedPauseRunnable);
}
}
} void activityPaused() {
mResumedCounter--;
if (mResumedCounter == 0) {
mHandler.postDelayed(mDelayedPauseRunnable, TIMEOUT_MS);
}
} void attach(Context context) {
mHandler = new Handler();
//mRegistry是LifecycleRegistry对象,依靠LifecycleRegistry分发Event,不多说
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
Application app = (Application) context.getApplicationContext();
//利用registerActivityLifecycleCallbacks注册callback监听activity生命周期
//细看activityResumed和activityPaused方法,通过Activity计数法来实现应用前后台的监听
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.get(activity).setProcessListener(mInitializationListener);
} @Override
public void onActivityPaused(Activity activity) {
activityPaused();
} @Override
public void onActivityStopped(Activity activity) {
activityStopped();
}
});
} static void init(Context context) { // 初始化
sInstance.attach(context);
}
} public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
//这是个ContentProvider,在onCreate方法初始化ProcessLifecycleOwner
//主进程的第一个ContentProvider.onCreate是比Application.onCreate先调用的
//这个ContentProvider会注册在Androidmenifest中,从而不用再Application中进行ProcessLifecycleOwner初始化
ProcessLifecycleOwner.init(getContext());
return true;
}
}
复制代码

LifecycleService的使用

LifecycleService 继承Service, 并实现LifecycleOwner, 可以自定义一个服务继承LifecycleService来使用,下面是代码实例:

public class MyService extends LifecycleService {

    public MyService() {
} @Override
public void onCreate() {
super.onCreate();
getLifecycle().addObserver(new LifecycleObserver() { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate(){
Log.d(TAG, "onCreate: ");
} @OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart(){
Log.d(TAG, "onStart: ");
} @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop(){
Log.d(TAG, "onStop: ");
} @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy(){
Log.d(TAG, "onDestroy: ");
} });
}
}
复制代码

总结以及其他的Tips

Lifecycles库为Jetpack其他组件打下了基础,通过LifecycleObserver观察者减少对Activity, Fragment, 和Service这些具有生命周期类的依赖。

  • 是使用LifecycleService和ProcessLifecycleOwner需要引入android.arch.lifecycle:extensions:1.1.1库,它并没有包含在com.android.support:appcompat-v7:version中
  • 在使用到Lifecycles库时最好在gradle引入apt编译器库annotationProcessor "android.arch.lifecycle:compiler:1.1.1", 没引入这库,对应注解@OnLifecycleEvent的方法就是使用反射来实现的,当引入这库后,会在编译时期自动生成YourObserverName_LifecycleAdapter类实现0反射提高性能。

Android Jetpack组件之Lifecycles库详解的更多相关文章

  1. 入职小白随笔之Android四大组件——内容提供器详解(Content Provider)

    Content Provider 内容提供器简介 内容提供器(Content Provider)主要用于在不同的应用程序之间 实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的 ...

  2. 详解Android中的四大组件之一:Activity详解

    activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...

  3. Android Jetpack组件

    带你领略Android Jetpack组件的魅力 Android新框架jetpack的内容讲解:Room.WorkManager.LifeCycles.LiveData.ViewModel.DataB ...

  4. Android开发:文本控件详解——TextView(一)基本属性

    一.简单实例: 新建的Android项目初始自带的Hello World!其实就是一个TextView. 在activity_main.xml中可以新建TextView,从左侧组件里拖拽到右侧预览界面 ...

  5. Android 广播大全 Intent Action 事件详解

    Android 广播大全 Intent Action 事件详解 投稿:mrr 字体:[增加 减小] 类型:转载 时间:2015-10-20我要评论 这篇文章主要给大家介绍Android 广播大全 In ...

  6. Flutter学习笔记(15)--MaterialApp应用组件及routes路由详解

    如需转载,请注明出处:Flutter学习笔记(15)--MaterialApp应用组件及routes路由详解 最近一段时间生病了,整天往医院跑,也没状态学东西了,现在是好了不少了,也该继续学习啦!!! ...

  7. 最强常用开发库总结 - JSON库详解

    最强常用开发库总结 - JSON库详解 JSON应用非常广泛,对于Java常用的JSON库要完全掌握.@pdai JSON简介 JSON是什么 JSON 指的是 JavaScript 对象表示法(Ja ...

  8. Lua的协程和协程库详解

    我们首先介绍一下什么是协程.然后详细介绍一下coroutine库,然后介绍一下协程的简单用法,最后介绍一下协程的复杂用法. 一.协程是什么? (1)线程 首先复习一下多线程.我们都知道线程——Thre ...

  9. Android EventBus 3.0 实例使用详解

    EventBus的使用和原理在网上有很多的博客了,其中泓洋大哥和启舰写的非常非常棒,我也是跟着他们的博客学会的EventBus,因为是第一次接触并使用EventBus,所以我写的更多是如何使用,源码解 ...

随机推荐

  1. Nacos学习

    Nacos是阿里开源的一个新框架,在分布式的架构中,Nacos同时扮演着服务注册中心和配置中心的角色.今天主要讲的是Nacos作为服务注册中心. 分布式中著名的CAP理论,任何一种服务注册中心都只能实 ...

  2. SpringMVC 给请求路径加上统一前缀

    最开始想到的是通过硬编码的方式手动在每个路径上加上前缀, 后面发现这种方式太不智能了,万一要修改那还不得改死, Spring既然支持EL表达式, 那能不能通过EL表达式的方式去读取配置文件里面的属性来 ...

  3. centos安装redis 5.0版本的集群

    我在本地VM-Centos里安装5.0.5时安装遇到了些问题,参考了Blog:https://www.cnblogs.com/shawhe/p/9548620.html 顺利安装完成. 安装redis ...

  4. springcloud添加自定义的endpoint来实现平滑发布

    在我之前的文章  springcloud如何实现服务的平滑发布 里介绍了基于pause的发布方案. 平滑发布的核心思想就是:所有服务的调用者不再调用该服务了就表示安全的将服务kill掉. 另外actu ...

  5. openresty开发系列34--openresty执行流程之4访问阶段

    openresty开发系列34--openresty执行流程之4访问阶段 访问阶段 用途:访问权限限制 返回403 nginx:allow 允许,deny 禁止 allow ip:deny ip: 涉 ...

  6. piecewise_construct存在的意义

    C++11中大部分的容器对于添加元素除了传统的 insert 或者 pusb_back/push_front 之外都提供一个新的函数叫做 emplace. 比如如果你想要向 std::vector 的 ...

  7. PL/SQL无法显示字段可以为NULL还是不能为NULL

    今天用mybatis操作oracle,用PL/SQL看到数据表的字段,明明都是可以为NULL的字段,各个字段都报错,ORA-01400 字段不能为NULL. 后面请教了同事和朋友,才知道这是PL/SQ ...

  8. [LeetCode] 80. Remove Duplicates from Sorted Array II 有序数组中去除重复项 II

    Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...

  9. [LeetCode] 857. Minimum Cost to Hire K Workers 雇K个工人的最小花费

    There are N workers.  The i-th worker has a quality[i] and a minimum wage expectation wage[i]. Now w ...

  10. Altera PLL Locked 失锁的原因

    Altera PLL 有时可能会出现失锁的情况,查找了官网资料,有总结到有几个情况下会出现失锁. 官网中的网页如下,是英文的: https://www.altera.com.cn/support/su ...