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. ‘Skimming-Perusal’ Tracking: A Framework for Real-Time and Robust Long-term Tracking

    ‘Skimming-Perusal’ Tracking: A Framework for Real-Time and Robust Long-term Tracking 2019-09-05 21:1 ...

  2. linux系统备份恢复到本机或是别的机器上

    ubuntu系统备份还原到相同电脑.另一台电脑.(tar方式) 原创 laukal 发布于2018-07-28 15:35:14 阅读数 2205 收藏 展开 最近一直搞Xtion2,openni2, ...

  3. redis的相关原理

    一.AOF 二.RDB 三.哨兵

  4. **80. Remove Duplicates from Sorted Array II 删除排序数组中的重复项 II

    1. 原始题目 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件 ...

  5. PAT 甲级 1077 Kuchiguse (20 分)(简单,找最大相同后缀)

    1077 Kuchiguse (20 分)   The Japanese language is notorious for its sentence ending particles. Person ...

  6. netty-websocket-spring-boot-starter关闭报错 io/netty/channel/AbstractChannel$AbstractUnsafe io/netty/util/concurrent/GlobalEventExecutor

    报错 java.lang.NoClassDefFoundError: io/netty/channel/AbstractChannel$AbstractUnsafe$ at io.netty.chan ...

  7. Python 内置函数--super()

    描述 super() 函数是用于调用父类(超类)的一个方法. super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重复 ...

  8. Linux安装卸载JDK完整步骤

    1.检查一下系统中的jdk版本 [root@localhost software]# java -version 显示: openjdk version "1.8.0_102" O ...

  9. springboot实战日记(一)数据库基本信息

    摘要:基于spring boot的后端实现,开发一个微信小程序点餐系统,主要是写写思路和遇到的问题以及分享读到的好文章. 项目分析: 1.角色划分,就是开有什么人使用这个系统,买家(手机端),卖家(p ...

  10. 《十天学会 PHP》的重难点

    记录一下我在学习<十天学会 PHP>(第六版)的过程中的遇到的重难点,该课程是学习制作一个简单的留言板. 准备工作 XAMPP(Apache + MySQL + PHP + PERL) 是 ...