Android-Jetpack笔记-Lifecycles
Lifecycle
即生命周期,一些业务场景如三方地图、播放器等,依赖于activity的生命周期,会有类似下面的用法:
class MyAct extends Activity{
VideoPlayer player;
void onCreate(){
player.init();//初始化
}
void onResume(){
player.play();//播放
}
void onPause(){
player.stop();//暂停
}
void onDestroy(){
player.release();//释放资源
}
}
这样使得act代码耦合臃肿,业务代码无法移植,通常需要用接口回调的形式抽离业务代码进行解耦,不过,从SDK 26.1.0
开始,Activity和Fragment已经默认实现了LifecycleOwner
接口,成为可观察对象,开发者只需为其添加观察者即可监听生命周期,LiveData
与ViewModel
也是依赖于Lifecycle
实现的。
Jetpack笔记代码
本文源码基于SDK 29
使用
引入依赖:
def lifecycle_version = "2.2.0"
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
//可选,如果开启了java8的话可以加上
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
定义一个观察者,他可以是任何关心act生命周期的业务类,
class MyObserver implements LifecycleObserver {
private static final String TAG = "Lifecycle";
//以注解的形式标注其关心的生命周期
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume() {
//方法名随便写,内部根据注解存储方法,然后反射调用
Log.e(TAG, "Lifecycle call onResume");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void onPause() {
Log.e(TAG, "Lifecycle call onPause");
}
}
如果引入了java8,可以不用注解的形式,直接实现DefaultLifecycleObserver
接口,这样做的好处是可以避免反射,
//app/build.gradle
android {
compileOptions {
//使用java8
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
//DefaultLifecycleObserver接口里有默认实现,所以需要java8支持
class MyObserver2 implements DefaultLifecycleObserver {
private static final String TAG = "Lifecycle";
@Override
public void onResume(@NonNull LifecycleOwner owner) {
Log.e(TAG, "Lifecycle2 call onResume");
}
@Override
public void onPause(@NonNull LifecycleOwner owner) {
Log.e(TAG, "Lifecycle2 call onPause");
}
}
在act中添加观察者:
class LifecycleActivity extends AppCompatActivity {
void onCreate(Bundle savedInstanceState) {
getLifecycle().addObserver(new MyObserver());
getLifecycle().addObserver(new MyObserver2());
}
}
然后就可以直接运行看日志了。
原理
注解方式多了些反射逻辑,由于主要分析生命周期,所以以DefaultLifecycleObserver
的实现方式来分析即可。
getLifecycle得到LifecycleRegistry
对象,以addObserver作为入口,
//LifecycleRegistry.java
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =new FastSafeIterableMap<>();
void addObserver(LifecycleObserver observer) {
//把观察者存储起来
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
}
然后debug一下,看看调用链,
这里出现了一个ReportFragment
,可以猜测下是不是添加了一个空fragment来管理生命周期,这个先放一放,然后看看LifecycleRegistry
,
//LifecycleRegistry.java
void handleLifecycleEvent(Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
//省略调用链:moveToState -> sync -> forwardPass
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
//遍历观察者,逐个分发事件
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
}
}
}
然后看到内部类LifecycleRegistry.ObserverWithState
,
//LifecycleRegistry.ObserverWithState
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
//回调
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
来到FullLifecycleObserverAdapter
,
//FullLifecycleObserverAdapter.java
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
switch (event) {
case ON_RESUME:
//回调完成
mFullLifecycleObserver.onResume(source);
break;
case ON_ANY:
throw new IllegalArgumentException("ON_ANY must not been send by anybody");
}
}
最后,前边提到的ReportFragment
,也进去看看,
class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
//从Android 10开始,使用Application.ActivityLifecycleCallbacks实现Lifecycle
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks());
}
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
//给act添加一个空的fragment
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
@Override
public void onResume() {
super.onResume();
dispatch(Lifecycle.Event.ON_RESUME);
}
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
//Android 10之前,使用ReportFragment实现Lifecycle
dispatch(getActivity(), event);
}
}
}
可以看到,即便都会添加一个空fragment,但从Android 10
开始,使用Application.ActivityLifecycleCallbacks
来分发事件,之前的版本才会使用ReportFragment
来分发,看注释大概是为了处理一些兼容问题?
优缺点
- 优点:
- 解耦,避免act臃肿
- 模块化和可移植
- 缺点:
- 观察者操作比较耗时的话,会阻塞住其他观察者甚至生命周期。
参考文章
- 简书-Android官方架构组件Lifecycle:生命周期组件详解&原理分析
- demo1 动态显示view或弹框 动态隐藏view或弹框
- ios 继承UITableViewController,更改tableview样式
- demo1 动态显示view或弹框 动态隐藏view或弹框
- 从零开始的Spring Security Oauth2(一)
- 细说Android事件传递
- swift基础_ set get方法 理解
- 高仿今日头条(2)
- ios tableview 上加 textfiled
- Spring Cloud实战小贴士:Feign的继承特性(伪RPC模式)
- 仿淘宝购买详情页购买缩小动画
- 高仿今日头条(1)
- android Native堆
- Spring Boot中Web应用的统一异常处理
- android bitmap的内存分配和优化
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- PHP实现二维数组(或多维数组)转换成一维数组的常见方法总结
- Laravel框架Eloquent ORM简介、模型建立及查询数据操作详解
- Laravel框架下载,安装及路由操作图文详解
- PHP实用小技巧之调用录像的方法
- Laravel重定向,a链接跳转,控制器跳转示例
- Laravel 错误提示本地化的实现
- Laravel框架DB facade数据库操作详解
- laravel 解决强制跳转 https的问题
- 在laravel中实现将查询的对象转换为多维数组的函数
- 在Laravel 中实现是否关注的示例
- Laravel框架查询构造器常见用法总结
- laravel 解决多库下的DB::transaction()事务失效问题
- laravel 实现上传图片到本地和前台访问示例
- laravel框架模型中非静态方法也能静态调用的原理分析
- Laravel 5.2 文档 数据库 —— 起步介绍