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

高效获知Activity的生命周期

Activity生命周期监听

使用 Instrumentation 对 Activity 生命周期进行监听。
优点:

  • 全局仅一次反射,性能影响极小
  • 所有Activity的生命周期都能够被监听到
  • 由于Java的单继承,为了拓展性,可以使用装饰器模式对Instrumentation进行功能加强,但个人觉得这样做不推荐

缺点:

  • 只使用于Activity的生命周期监听
  • FragmentManger实例的应用关系复杂,不容易反射替代(应该可以实现,或者用其他方式Hook)

1. 实现原理:

回顾到 Activity 的启动流程,AMS 向 APP 进程发来 Activity 启动请求,ApplicaitonThread 作为binder线程的维护者收到消息,将消息回调到 ActivityThread 的Handler.handleMessage(),启动Activity。核心为:performLaunchActivity()->Instrumentation.callActivityOnCreate()->activity.performCreate()
类似的,还有:

//Instrumentation.java
pubilc void callActivityOnCreate(Activity activity,Bundle budle,PsersistableBundle p){
//...
}
public void callActivityOnCreate(Activity activity,Bundle 
bundle){
//...
}
public void callActivityOnStart(Activity activity){
//...
}
//...OnPause、OnStop、OnDestroy也都类似

这些方法都是开放的,所有Activity的生命周期都会经过它,而且这些方法都明确了要调用哪个Activity的生命周期。这就给了我们一个机会来监听 Activity。同时这个设计也表现了 Android 的事件驱动设计。

2. 实现方法

我们可以通过继承一个 Instrumentation 来给这些方法加个钩子,注意一定要回调父类的本方法,否则就破坏程序了:


public class FyInstrumentation extends Instrumentation {public static final String TAG = "FyInstrumentation";//------------   onCreate   ------------@Overridepublic void callActivityOnCreate(Activity activity, Bundle bundle) {Log.e(TAG, "begin onCreate: " + activity);super.callActivityOnCreate(activity, bundle);Log.e(TAG, "end onCreate" + activity);}@Overridepublic void callActivityOnCreate(Activity activity, Bundle bundle, PersistableBundle persistentState) {Log.e(TAG, "begin onCreate: " + activity);super.callActivityOnCreate(activity, bundle,persistentState);Log.e(TAG, "end onCreate" + activity);}//--------------  onStart ---------------@Overridepublic void callActivityOnStart(Activity activity){Log.e(TAG, "begin onStart: " + activity);super.callActivityOnStart(activity);Log.e(TAG, "end onStart" + activity);}//--------------  onResume ---------------@Overridepublic void callActivityOnResume(Activity activity){Log.e(TAG, "begin onResume: " + activity);super.callActivityOnResume(activity);Log.e(TAG, "end onResume" + activity);}//--------------  onPause ---------------@Overridepublic void callActivityOnPause(Activity activity){Log.e(TAG, "begin onPause: " + activity);super.callActivityOnPause(activity);Log.e(TAG, "end onPause" + activity);}//--------------  onStop ---------------@Overridepublic void callActivityOnStop(Activity activity){Log.e(TAG, "begin onStop: " + activity);super.callActivityOnStop(activity);Log.e(TAG, "end onStop" + activity);}//--------------  onDestroy ---------------@Overridepublic void callActivityOnDestroy(Activity activity){Log.e(TAG, "begin onDestroy: " + activity);super.callActivityOnResume(activity);Log.e(TAG, "end onDestroy" + activity);}}

把我们的 FyInstrumentation 替换掉原有的 Instrumentation。
何时替换都可以,只需要在我们目标监听的 Activity 开始之前就替换好即可。所以我这里就把它放在 MyApplication 中,在所有 Activity 开始之前就替换好。
先写一个工具类,由于单例设计,ActivityThread实例的获取,我们可以通过静态方法currentActivityThread()来获取。再对它的成员变量 mInstrumentation 进行反射替换成我们的 Instrumentation。

public class HookHelper {public static final String TAG= "HookHelper";public static void attachContext() throws Exception{//获取到当前的activityThreadClass<?> atClazz = Class.forName("android.app.ActivityThread");Method method = atClazz.getMethod("currentActivityThread");Object at = method.invoke(null);Log.e(TAG,at.getClass().getName()+"  ");Field f = at.getClass().getDeclaredField("mInstrumentation");f.setAccessible(true);f.set(at,new FyInstrumentation());}
}

最后,我们在MyApplication中进行替换:


public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();try {HookHelper.attachContext();} catch (Exception e) {e.printStackTrace();}}
}

3.测试监听:

进入到 MainActivity,然后点击按钮跳转到TestFragmentActivity:

2023-02-20 15:48:37.280 3737-3737/com.company.rxjavastudy E/FyInstrumentation: begin onCreate: com.company.lifecycle2.MainActivity@d3e13d
2023-02-20 15:48:37.700 3737-3737/com.company.rxjavastudy E/FyInstrumentation: end onCreatecom.company.lifecycle2.MainActivity@d3e13d
2023-02-20 15:48:37.703 3737-3737/com.company.rxjavastudy E/FyInstrumentation: begin onStart: 
...
2023-02-20 15:52:39.380 3737-3737/com.company.rxjavastudy E/FyInstrumentation: end onStopcom.company.lifecycle2.MainActivity@d3e13d

内容太多了,我把顺序梳理如下:APP开启后进入到活动A,点击按钮跳转到活动B:

A-onCreate
A-onStart
A-onResume
A-onPause
B-onCreate
B-onStart
B-onResume
A-onStop

测试完成,监听成功。
对生命周期的细节,大家可以复习关于:Activity的四大启动模式与Activity跳转的生命周期的关系,也注意一下 onNewIntent(),这是在复用Activity的时候调用的。

相关文章:

高效获知Activity的生命周期

Activity生命周期监听 使用 Instrumentation 对 Activity 生命周期进行监听。 优点&#xff1a; 全局仅一次反射&#xff0c;性能影响极小所有Activity的生命周期都能够被监听到由于Java的单继承&#xff0c;为了拓展性&#xff0c;可以使用装饰器模式对Instrumentation进行功…...

分析现货黄金价格一般有什么方法

分析现货黄金价格一般有什么方法呢&#xff1f;我相信很多投资者都会说&#xff0c;是技术分析。很多人并不知道技术分析是什么&#xff0c;并且技术分析是如何去分析现货黄金价格的&#xff0c;那么本文就介绍一下技术分析的主要分类。可以说&#xff0c;小编的其他文章都是以…...

Spring中的拦截器

这里写目录标题基本概念HandlerInterceptor拦截器HandlerInterceptor讲解MethodInterceptor拦截器二者的区别基本概念 在web开发中&#xff0c;拦截器是经常用到的功能。它可以帮我们预先设置数据以及统计方法的执行效率等等。 Spring中拦截器主要分两种&#xff0c;一个是Han…...

【Linux操作系统】【综合实验四 Linux的编译环境及线程编程】

文章目录一、实验目的二、实验要求三、实验内容四、实验报告要求一、实验目的 要求熟悉Linux环境中的程序编译、调试与项目管理过程并能实现具体操作&#xff1b;熟练使用基础函数库中与线程库中的管理函数&#xff0c;实现用户线程编程过程&#xff0c;并深入了解Linux的线程…...

Switch 如何使用NSCB 转换XCI NSP NSZ教程

很多小白经常碰到Switch游戏文件格式和预期不符的情况&#xff0c;比如碰到nsz自己不会安装&#xff08;安装NSZ格式文件教程&#xff09;&#xff1b;或者是碰到xci格式的&#xff0c;想转换为nsp&#xff1b;抑或想将nsz格式文件还原回nsp格式。本文对此提供了解决方案。 文中…...

JVM12 字节码指令集

1. 概述 2. 加载与存储指令 2.1. 局部变量压栈指令 iload 从局部变量中装载int类型值 lload 从局部变量中装载long类型值 fload 从局部变量中装载float类型值 dload 从局部变量中装载double类型值 aload 从局部变量中装载引用类型值&#xff08;refernce&#xff09; iload_0 从…...

centos之python安装与多版本python之间的共存

一、背景 随着python版本迭代加快&#xff0c;有写python模块再低版本无法运行&#xff0c;此时需要我们在进行安装一个python版本 例如&#xff1a;uvloop 在python3.7上运行&#xff1b;python 3.6官方不再维护与更新 有些模块或不支持较低版本、有些模块支持较高版本python…...

SpringBoot学习笔记(一)

Idea中隐藏指定文件或指定类型文件 setting->File Types->Ignored Files and Folders输入要隐藏的文件名&#xff0c;支持*号通配符回车确认添加 SpringBoot概述 parent 小结&#xff1a; 开发SpringBoot程序要继承spring-boot-starter-parentspring-boot-starter-pa…...

美国原装KEYSIGHT E4981A(安捷伦) E4981A电容计

KEYSIGHT E4981A&#xff08;安捷伦&#xff09; Keysight E4981A&#xff08;安捷伦&#xff09;电容计为生产线中的陶瓷电容器测试提供了高速、可靠的测量。E4981A 实现了电容从小到大的测量能力&#xff0c;测量准确。Agilent E4981A 电容计有助于提高测试吞吐量&#xff0…...

K8S的基础概念

目录 一、k8s概述 1、k8s简介 1.1 k8s的作用 1.2 k8s的由来 1.3 k8s的含义 1.4 k8s的官网 1.5 GitHub 2、为什么要用 K8S? 2.1 K8s的目标 2.2 K8s解决了裸跑Docker 的若干痛点: 2.3 K8s的主要功能 3、K8s的特性 二、Kubernetes 集群架构与组件 1、工作流程 2、…...

【数据结构】——环形队列

文章目录一.环形队列的定义及其特点二.使用数组来实现环形队列1.创建一个队列2.初始化队列3. 判断环形队列是否为空4.判断环形队列是否已满5. 向循环队列插入元素&#xff0c;插入成功返回真6.删除环形链表的数据7. 取队头元素8.取队尾元素8.释放空间总结一.环形队列的定义及其…...

windows 安装Qt

下载 下载地址https://download.qt.io/&#xff0c;此文已5.7.0为例子。 根据图片依次选择即可。 安装 安装过程参考另一篇文章Ubuntu 安装 Qt5.7.0即可 配置环境变量 ps&#xff1a;我就是之前没配置环境变量&#xff0c;直接使用创建项目&#xff0c;项目源码直接运行是…...

spring cloud gateway集成sentinel并扩展支持restful api进行url粒度的流量治理

sentinel集成网关支持restful接口进行url粒度的流量治理前言使用网关进行总体流量治理&#xff08;sentinel版本&#xff1a;1.8.6&#xff09;1、cloud gateway添加依赖:2、sentinel配置3、网关类型项目配置4、通过zk事件监听刷新上报api分组信息1、非网关项目上报api分组信息…...

wafw00f工具

wafw00f Web应用程序防火墙指纹识别工具 github地址&#xff1a;https://github.com/EnableSecurity/wafw00f 安装环境&#xff1a;python3环境 —>使用 pip install wafw00f 进行安装 安装成功后目录&#xff1a;python安装目录中的Lib\site-packages\wafw00f 本机为&a…...

论文阅读笔记-DiffusionInst: Diffusion Model for Instance Segmentation

文章目录DiffusionInst: Diffusion Model for Instance Segmentation摘要介绍任务介绍实例分割的几种方法想法来源贡献方法整体结构Mask RepresentationDiffusionInst组成TrainingInference不足之处感悟DiffusionInst: Diffusion Model for Instance Segmentation 代码&#x…...

解决CondaUpgradeError网上的方法都不奏效(回退版本、upgrade/update都不行)的问题和CondaValueError

问题描述 Executing transaction: failed ERROR conda.core.link:_execute(502): An error occurred while installing package ‘conda-forge::certifi-2022.9.24-pyhd8ed1ab_0’. CondaUpgradeError: This environment has previously been operated on by a conda version…...

基于某业务单登陆场景并发测试实战

文章目录1 测试目的2 测试目标和测试对象3 名词解释4 测试说明5 测试环境和工具5.1 测试工具5.2 测试环境5.3 人力计划6 测试用例6.1 方案设计6.2 接口地址6.3 接口参数6.3.1 header参数6.3.2 请求参数7 脚本设计8 监控数据8.1 虚拟用户并发情况8.2 事务响应时间8.3 每秒点击次…...

JVM内存模型

程序计数器 多线程时&#xff0c;当线程数超过CPU数量或CPU内核数量&#xff0c;线程之间就要根据时间片轮询抢夺CPU时间资源。因此每个线程有要有一个独立的程序计数器&#xff0c;记录下一条要运行的指令。线程私有的内存区域。如果执行的是JAVA方法&#xff0c;计数器记录正…...

三、NetworkX工具包实战3——特征工程【CS224W】(Datawhale组队学习)

开源内容&#xff1a;https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频&#xff1a;https://space.bilibili.com/1900783/channel/collectiondetail?sid915098 斯坦福官方课程主页&#xff1a;https://web.stanford.edu/class/cs224w NetworkX…...

分布式之Raft共识算法分析

写在前面 在分布式之Paxos共识算法分析 一文中我们分析了paxos算法&#xff0c;知道了其包括basic paxos和multi paxos&#xff0c;并了解了multi paxos只是一种分布式共识算法的思想&#xff0c;而非具体算法&#xff0c;但可根据其设计具体的算法&#xff0c;本文就一起来看…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...