Activity-Hook填坑过程中温故而知新(2),腾讯+华为+阿里面试真题分享

文章可能过分详细,但是这是为了帮助到尽量多的人,毕竟工作5,6年,不能老吸血,也到了回馈开源的时候.
这个系列的文章:
1、用通俗易懂的讲解方式,讲解一门技术的实用价值
2、详细书写源码的追踪,源码截图,绘制类的结构图,尽量详细地解释原理的探索过程
3、提供Github 的 可运行的Demo工程,但是我所提供代码,更多是提供思路,抛砖引玉,请酌情cv
4、集合整理原理探索过程中的一些坑,或者demo的运行过程中的注意事项
5、用gif图,最直观地展示demo运行效果

如果觉得细节太细,直接跳过看结论即可。
本人能力有限,如若发现描述不当之处,欢迎留言批评指正。

学到老活到老,路漫漫其修远兮。与众君共勉 !


引子

HOOK系列是 今年年初大概3月份写的,其中《手把手讲解 Android Hook-实现无清单启动Activity》 这一篇的文章链接为:《请峰子在这里替换为享学公众号的这篇文章的链接
Demo地址为:https://github.com/18598925736/ActivityHookDemo/tree/startActivityWithoutRegiste

当时是基于最新的SDK 28 android 9 进行的hook,但是近期有一位朋友提出,在SDK 28的设备上,hook之后会导致作为LauncherActivity的生命周期完全失效。并且在SDK 29 android10的设备上,会崩溃。
这位朋友解决了崩溃的问题,在此对他(github名为:fangding)表示感谢!
崩溃的问题我大致看过,也验证过,没有问题,已经合并到 开发分支上,很简单,只是SDK 29改了一些类名,各位可以到 github上去自行查看。现在要解决的是生命周期失效的问题。

声明一个debug源码的坑

hook开发的初期,一般不要用真机。因为真机的系统都是经过了手机厂家深度定制的,如果你想要进行代码debug,使用真机做不到的,因为代码的行数根本对应不上。推荐使用谷歌原生的模拟器

本文采用的是 android 9 sdk 28 谷歌原生androidStudio自带AVD模拟器

适合阅读的人群

如果你对hook 有概念,并且对具体如何去hook有 兴趣深入了解,那么这篇文章可以帮到你很多。

正文

  • bug 表征
  • 源码探索
  • 解决方案
  • 完美效果
  • 可能隐患

bug 表征

Demo : https://github.com/18598925736/ActivityHookDemo/tree/startActivityWithoutRegiste
请切换到 git时间点: 945df9
git checkout 945df9
如果结果为:HEAD is now at 945df96 使用androidX 则切换成功。
这里是,已经出现问题的版本节点。

运行Demo,启动as自带模拟器 sdk28版本。进行跳转,

简单的跳转.gif
然后发现,生命周期函数并不执行。
image.png跳转过程中,只出现了onCreate onStart onResume, 照理说,跳转之后应该有 onPause onStop. 并且我回到这个Activity时,应该会有 onRestart onStart onResume, 但是也没有。

源码探索

为什么生命周期函数都不执行了?要找到这个原因,我必须先弄清楚一个问题: Activity的生命周期函数到底是由谁来调用的。

前期准备:

这里我不使用Demo工程,而是另外自己新建一个工程,写一个普通的startActivity跳转(这个我就不贴代码了). 因为我们要观察的是正常跳转

开工,进入源码(SDK 28 注意,app module的sdk也要28,必须用 androidStudio自带的AVD SDK 28模拟器才能 debug ):
(为了确保源码探索的完整流程,我们从 startActivity开始 . )

image.png
image.pngimage.png
这里产生2个分支,但是仔细观察之后,其实他们最终都走到了同一段逻辑:

Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}

来解析这一段逻辑:

两句代码,一个是 mInstrumentation.execStartActivity
image.png

看来这一段并没有涉及到Activity生命周期函数的逻辑。
那么,看下一段:

mMainThread.sendActivityResult ,从 mInstrumentation.execStartActivity 执行之后,得到了一个ar,现在把这个ar 交给mMainThread(ActivityThread类的对象),于是,进入 ActivityThread源码:
image.png
这里的 scheduleTransaction方法,在ActivityThread的父类ClientTransactionHandler中:image.png
看到sendMessage,就怀疑,这里可能和Handler扯上关系了。
还记不记得 ActivityThread的父类ClientTransactionHandler scheduleTransaction()方法中 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); 用到了 ActivityThread.H.EXECUTE_TRANSACTION. 我们在H extends Handler中找到这个switch case的分支:
image.png

一共就两句代码可能和Activity的生命周期函数调用有关,那么我有理由怀疑就是这一段代码在执行 生命周期函数. 那么 如何验证我的猜想是否成立? 答: debug源码(前面之所以要源码版本,AVD模拟器版本,项目版本gradle SDK版本都写成28,就是为了这里debug)
加上断点之后,开始debug,按下跳转按钮, 我们发现了惊人的现象:


一次跳转,我们debug发现了3个可能和生命周期函数有关的细节:
PauseActivityItem ,ResumeActivityItem,StopActivityItem,这3个是不是分别对应了 Activity的3个生命周期函数?
继续探索:
找到 TransactionExecutor类的execute()方法:
image.png

我们需要跟踪的是transaction参数 (因为这里只有一个参数…不跟踪它跟踪谁呢)
然而,这里,使用到这个参数的是两个方法,executeCallbacks()executeLifecycleState(),
而,在这两个方法中,我都找到了类似下面这样的代码:

final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);

推断出,生命周期函数一定和ActivityLifecycleItemexecute()postExecute()有关,还记不记得之前我们debug出来的PauseActivityItem ,ResumeActivityItem,StopActivityItem . 这3个类就是ActivityLifecycleItem的子类,进去看看:

image.png
debug 一下:

最后

文章所有资料全部已经打包整理好,免费分享给有需要的人,另外小编手头上整理了大量Android架构师全套学习资料,Android核心高级技术PDF文档+全套高级学习资料+视频+2021 BAT 大厂面试真题解析,都是免费分享给大家的,全部都已整理在GitHub上,有需要的朋友可以点击前往领取更多。

资料展示:

image

image

image

g-JfWmJgj7-1644025529704)]

[外链图片转存中…(img-fk6yHotg-1644025529704)]

[外链图片转存中…(img-rTam5Lqf-1644025529705)]

image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值