#鸣谢
翻了很多关于
hook Activity
启动流程的博客,这位大佬的文章给我的启发最大
https://blog.csdn.net/gdutxiaoxu/article/details/81459910
但是,可能大佬的博文对于有些基础不足的初中级
安卓工程师或者并不熟悉hook
的某些大佬 还不够友好,所以我把大佬的思想用更通俗,更具象化的方式再展示一遍,并且提供可运行的github
demo.并且,阅读源码的时候一些坑,我都会详细给出解决方案。
#正文大纲
一. 两种启动Activity的方式源码追踪
二. 第一种启动方式的hook方案
三. 第二种启动方式的hook方案
四. 目前方案弊端分析
五. 最终解决方案
六. HOOK开发可能的坑
Demo地址
https://github.com/18598925736/ActivityHookDemo
#正文
##一. 两种启动Activity的方式源码追踪
(源码基于
SDK 28 ~ android-9.0
)
方式1:使用Activity
自带的startActivity
示例代码
private void startActivityByActivity() {
Intent i = new Intent(MainActivity.this, Main2Activity.class);
startActivity(i);
}
程序执行走向图.
代码追踪:
这里有个if(mParent==null)
判定,先看true
分支:
发现一个坑,mInstrumentation.execStartActivity
这里居然不能继续往下索引了?很奇怪,不过不重要,我们直接进入Instrumentation.java
去找这个方法:
在这个execStartActivity中,可以找到关键代码
:
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
通过这种方式启动Activity,最终的执行权被交给了
ActivityManager.getService()
(即AMS
),它的作用是 启动一个Activity并且返回result
,然后checkStartActivityResult(result, intent);
这句话,对当前的跳转意图intent
进行检测;
have you declared this activity in your AndroidManifest.xml
这句异常应该很熟悉了吧?启动一个没有注册的Activity的报错.
再看个if(mParent==null)
的false
分支: