当前位置: 首页 > news >正文

JetPack01- LifeCycle 监听Activity或Fragment的生命周期

前提

阅读本文的前提是要了解观察者模式。本文没有讲述反射相关的内容,功能中有使用反射。

简介

监听Activity/Fragment的生命周期,使用观察者模式,Activity/Fragment是被观察者。

监听的生命周期有onCreate、onStart、onResume、onPause、onStop和onDestroy。

androidx的特有功能。

使用

创建观察者

实现LifecycleObserver接口,使用注解监听对应的生命周期。

或者实现DefaultLifecycleObserver接口,同Activity/Fragment对应的函数监听对应的生命周期,且持有LifecycleOwner对象,AppCompatActivity是LifecycleOwner的子类。

注解方式在新版本已被弃用,项目中一般使用该方法。

注册观察者

AppCompatActivity中的成员变量mLifecycleRegistry,通过getLifecycle()获取。

LifecycleRegistry类实现Lifecycle接口,使用Lifecycle接口的addObserver()函数注册观察者。

综上可知:

实现AppCompatActivity类的Activity,可以使用lifecycle.addObserver(观察者)来注册观察者。

Tips:

一般在Activity的onCreate中注册观察者。

如果在onResume中注册观察者,会执行onCreate、onStart和onResume。(具体原因在源码分析)

PS:被观察者通知观察者由LifeCycle库实现。

源码分析

注册观察者时做了什么?

存储观察者对象,以及观察者类的class信息,回调生命周期对应函数时使用反射调用对应函数。

Lifecycle的实现类是LifecycleRegistry。

来分析下LifecycleRegistry的addObserver函数。

如何在Activity的生命周期被触发时调用观察者的对应函数?

如何获取Activity的生命周期?

核心实现在ReportFragment类的injectIfNeededIn方法中。

具体怎么做的?

ReportFragment是一个Fragment。

API=29的实现方式不同。

API版本

ReportFragment监听到Activity生命周期后,会调用ReportFragment的dispatch来调用观察者的对应函数。

API>=29时,是给Activity类添加回调,然后在Activity分发生命周期方法onCreate、onResume等时同时触发回调对应的方法。

向Activity类的成员变量mActivityLifecycleCallbacks添加一个LifecycleCallbacks对象,本质就是回调。

那么Activity是怎么将生命周期回调至LifecycleCallbacks对象呢?(以分析下onCreate为例)。

是在AMS分发Activty生命周期的时候处理的。AMS调用Activity的onCreate的函数是在performCreate中分发的。

不同版本分发的具体实现,都是通过ReportFragment的dispath函数来实现的。

dispath函数如何分发给观察者?

在分发的过程中没有直接使用对应的事件分发,在中间进行了事件和状态的转变处理,目的是为了灵活,在其他库使用Lifecycle时可以根据状态进行相应的处理。

例如:LiveData库会根据状态判断是否通知UI刷新。

事件有:

状态有:

事件与状态的关系如下图:

通过状态决定要执行什么事件(状态驱动事件)。

Lifecycle和观察者的状态是分别存储的,通过对比新旧状态,决定要执行什么事件。

状态的对比是通过枚举类型的数据进行大小对比来进行的。

为什么在onResume中注册,会执行onCreate、onStart和onResume?

onCreate、onStart和onResume01都是在回调onResume时触发的。

原因是在同步观察者状态时,是根据状态一步一步触发的。

循环过程如下图:

http://www.lryc.cn/news/444970.html

相关文章:

  • OpenCSG推出StarShip SecScan:AI驱动的软件安全革新
  • 占道经营检测-目标检测数据集(包括VOC格式、YOLO格式)
  • 828华为云征文 | 云服务器Flexus X实例:RAG 开源项目 FastGPT 部署,玩转大模型
  • MySQL之基本查询(一)(insert || select)
  • 基于深度学习的多智能体协作
  • Nmap网络扫描器基础功能介绍
  • idea 编辑器常用插件集合
  • 如何优化Java商城系统的代码结构
  • 两数之和、三数之和、四数之和
  • 这几个方法轻松压缩ppt文件大小,操作起来很简单的压缩PPT方法
  • 【nvm管理多版本node】下载安装以及常见问题和解决方案
  • C++(学习)2024.9.23
  • 大数据处理从零开始————3.Hadoop伪分布式和分布式搭建
  • 跟着问题学12——GRU详解
  • 内核是如何接收网络包的
  • 计算机毕业设计之:基于微信小程序的电费缴费系统(源码+文档+讲解)
  • 【leetcode】环形链表、最长公共前缀
  • C#开发记录如何建立虚拟串口,进行串口通信,以及通信模板
  • 电源设计的艺术:从底层逻辑到工程实践
  • 软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章
  • 【Kubernetes】常见面试题汇总(二十七)
  • 基于单片机巡迹避障智能小车系统
  • Python163邮箱发送:提升发送效率的技巧?
  • springboot中的异步任务
  • Linux学习笔记8 理解Ubuntu网络管理,做自己网络的主人
  • 理解线程的三大特性:原子性、可见性和有序性
  • 英特尔®以太网网络适配器E810-CQDA1 / E810-CQDA2 网卡 规格书 e810 网卡 规格书 Intel100G E810 网卡 白皮书
  • 好用的idea方法分隔符插件
  • 通过 Xshell 无法连接到 Ubuntu
  • Java面试篇基础部分-Synchronized关键字详解