第3.2节 Android应用调用链路分析
3.2.1 Android调用链路简介
在Android应用程序中,调用链路涉及应用程序中不同组件(如Activity、Service、BroadcastReceiver、ContentProvider)之间的调用关系,以及应用程序与系统服务之间的交互。了解和分析这些调用链路对于调试、性能优化和安全性分析非常重要。以下是Android应用程序调用链路的主要组成部分及其分析方法:
1,Activity调用链
Activity是Android应用程序的基本组件之一,负责处理用户界面和用户交互。
典型的调用链包括Activity的生命周期方法(如onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy())之间的调用。
2,Service调用链
Service是用于在后台执行长时间运行操作的组件。
典型的调用链包括Service的生命周期方法(如onCreate()、onStartCommand()、onBind()、onUnbind()、onDestroy())之间的调用。
3,BroadcastReceiver调用链
BroadcastReceiver用于接收和处理广播消息。
典型的调用链包括onReceive()方法的调用。
4,ContentProvider调用链
ContentProvider用于在应用程序之间共享数据。
典型的调用链包括CRUD操作方法(如query()、insert()、update()、delete())的调用。
5,系统服务调用链
Android应用程序与系统服务(如LocationManager、NotificationManager、ConnectivityManager等)之间的调用。
分析Android应用程序的调用链路
1,使用Android Studio Profiler
Android Studio提供了强大的性能分析工具,可以帮助你分析应用程序的调用链。
打开Android Studio,运行你的应用程序,然后打开Profiler工具。在Profiler中,你可以查看CPU、内存、网络等性能数据,并分析方法调用链。
2,使用日志记录
在代码中添加日志记录,输出调用链信息。使用Log.d()、Log.i()、Log.w()、Log.e()等方法记录关键方法的调用。通过查看日志,可以了解应用程序的调用链。
3,使用Traceview
Traceview是Android SDK提供的一个工具,用于分析应用程序的性能。在代码中使用Debug.startMethodTracing()Debug.stopMethodTracing()方法生成trace文件。使用Traceview工具打开trace文件,查看方法调用链和性能数据。
4,使用第三方工具
- LeakCanary:用于检测内存泄漏,帮助分析调用链。
- Stetho:Facebook提供的调试工具,可以查看应用程序的数据库、网络请求等信息。
- Hugo:用于在方法调用时自动记录日志,帮助分析调用链。
3.2.2 Android App静态调用链路
第一节介绍了很多Android App的调用链路以及相关的分析方法,可以帮助程序员分析问题,定位Bug。作为测试同学,我们更加关注的时,开发修改的某些代码,添加了某些类或是函数,影响到什么功能?以方便界定测试范围,组织测试用例集进行测试。为了达到这个目的,主要关注App的两个调用链路,一个是静态调用链路,通过分析代码,解析出代码间的调用关系。另一个是动态调用链路,通过执行测试用例,记录用例的执行路径,分析相应的调用链路。
本节先介绍静态调用链路,Android App的静态调用链路借助于一个开源的工具java-callgraph2: https://github.com/Adrninistrator/java-callgraph2来进行分析。
1,java-callgrap2的使用
java-callgraph2项目用于对Java代码(编译后的class、jar、war文件)进行静态分析的开源工具。它能够帮助开发者直观地理解程序内部的调用逻辑,从而更好地进行代码审查、性能优化和重构。该工具支持按类、包或整个项目生成调用图,具有简单高效、灵活性和跨平台等特点。
(1)下载与安装
克隆项目仓库:
git clone https://github.com/Adrninistrator/java-callgraph2.git
进入项目目录:
cd java-callgraph2
构建项目(使用 Maven):
mvn clean install
(2)生成调用图
假设你有一个 Java 项目 my-java-project,你可以使用以下命令生成调用图:
java -jar target/java-callgraph2.jar -source my-java-project -output callgraph.dot
生成的 callgraph.dot 文件可以使用 Graphviz 工具进行可视化:
dot -Tpng callgraph.dot -o callgraph.png
如:

2,Android App调用链路分析
App调用链路分析可以使用java-graph2对项目文件进行直接分析,这是项目的源码文件,可能存在打包过程中动态生成的类的调用关系无法分析出来。经过调研,发现通过对App直接反编译,再进行分析会更加全面,具体流程如下:

(1)App链路分析
- App链路分析,先从指定的地方下载到要测试的Apk文件,这个文件是要进行链路分析的,不能是其他的版本,否则可能存在代码不一致的情况。
- 将apk文件重新命名为zip文件,并进行解压或是通过解压软件,直接对apk进行解压,拿到包中的文件。不过这些文件不能直接进行分析,要通过反编译手段进行处理,dexjar:https://github.com/pxb1988/dex2jar,将文件夹里的dex文件反编译成jar文件。当然也可以通过以下命令,将apk包直接反编译成jar包:
sh d2j-dex2jar.sh -f ~/path/to/apk_to_decompile.apk
如果apk文件较大,建议解压后再进行反编译。
- 通过java-callgraph2工具,将反编译后的jar包进行链路分析,将分析后的结果保存到txt文件中。
java -jar path/java-callgraph2.jar -Doutput.file=calllink.txt path/source.jar
调用关系数据如下所示:
J:1 /Users/sxf/Downloads/Kim/classes-dex2jar.jar
C:K.S K.S
C:K.S java.lang.Object
M:1 K.S:<init>() (O)java.lang.Object:<init>() 0 1
C:aegon.chrome.base.ActivityState aegon.chrome.base.ActivityState
C:aegon.chrome.base.ActivityState java.lang.Object
C:aegon.chrome.base.ActivityState java.lang.annotation.Annotation
C:aegon.chrome.base.ApiCompatibilityUtils$ApisLmr1 aegon.chrome.base.ApiCompatibilityUtils$ApisLmr1
C:aegon.chrome.base.ApiCompatibilityUtils$ApisLmr1 java.lang.Object
C:aegon.chrome.base.ApiCompatibilityUtils$ApisLmr1 aegon.chrome.base.ApiCompatibilityUtils
C:aegon.chrome.base.ApiCompatibilityUtils$ApisLmr1 android.view.View
M:2 aegon.chrome.base.ApiCompatibilityUtils$ApisLmr1:<init>() (O)java.lang.Object:<init>() 0 1
M:3 aegon.chrome.base.ApiCompatibilityUtils$ApisLmr1:setAccessibilityTraversalBefore(android.view.View,int) (M)android.view.View:setAccessibilityTraversalBefore(int) 0 1
C:aegon.chrome.base.ApiCompatibilityUtils$ApisM aegon.chrome.base.ApiCompatibilityUtils$ApisM
C:aegon.chrome.base.ApiCompatibilityUtils$ApisM java.lang.Object
C:aegon.chrome.base.ApiCompatibilityUtils$ApisM aegon.chrome.base.ApiCompatibilityUtils
C:aegon.chrome.base.ApiCompatibilityUtils$ApisM android.view.View
M:4 aegon.chrome.base.ApiCompatibilityUtils$ApisM:<init>() (O)java.lang.Object:<init>() 0 1
M:5 aegon.chrome.base.ApiCompatibilityUtils$ApisM:setStatusBarIconColor(android.view.View,boolean) (M)android.view.View:getSystemUiVisibility() 0 1
M:6 aegon.chrome.base.ApiCompatibilityUtils$ApisM:setStatusBarIconColor(android.view.View,boolean) (M)android.view.View:setSystemUiVisibility(int) 0 1
- 处理app下所有的调用关系数据,将数据保存成如下数据结构:
{"class1:method1":{"methodin":[调用方函数列表],"methodout":[调用函数列表]}}}
将数据序列化保存到pickle文件中,注意通过路径来区分一下app的版本号,分支信息等。
(2)查询影响范围
当对一个App创建的调用链路数据后,就可以根据提测版本,通过git diff获取修改的文件,再通过修改的行号,获取出修改的函数名参数等信息,拼接出如:包名.类名:函数名,存到相应的文件中,如diffdetail.txt中。
读取diffdetail.txt文件,按行去查询调用关系,再拿调用关系的methodin中的函数列表进行查询,直到没有调用关系,或是到页面为止, 从而形成一个调用链路,以此来评估需求改动的影响范围。或是在精准测试平台后面的功能中,会以影响范围来进行用例推荐,推荐测试同学执行相关的测试用例集,以达到对需求改动的全面覆盖。
