Android 12 源码分析 —— 应用层 一(SystemUI准备篇)
Android 12 源码分析 —— 应用层一(SystemUI准备篇)
在接下来的时间中,将会使用Pixel 3(blueline)作为研究对象,选用AOSP的android-12.0.0_r34分支作源代码。
先从android的应用层进行探析,然后慢慢深入android的framework,接着进入android的hal层,最后以android的linux内核结束,期间可能会穿插一些其他文章如android的art虚拟机分析等。
本文是整个系列的第一篇,但是在此之前,请务必阅读以下的文章,他们将在以后的源码分析中时不时出场
- android 如何分析应用的内存(二)——xdd,gdb命令行(http://t.csdn.cn/RENbG)
- android 如何分析应用的内存(三)——LLDB命令行(http://t.csdn.cn/Vpw8e)
- android 如何分析应用的内存(四)——Visual studio code的LLDB(http://t.csdn.cn/8ZM8A)
- android 如何分析应用的内存(十四)——jdb命令行(http://t.csdn.cn/99r2G)
- android 如何分析应用的内存(十五)——Visual Studio Code 调试Android应用(http://t.csdn.cn/dWeF5)
上面列出的文章,是关于如何使用gdb,lldb,jdb进行android源码级别的调试。它在没有IDE的情况下非常有用。
本文作为应用层的开篇之作,选取SystemUI作为研究对象。
为什么选取SystemUI?
在Android的应用层有很多应用可以进行源码分析,如Launcher,Camera,Gallery,Bluetooth,SIM,telephony,Settings等等应用,综合考虑到SystemUI可能是定制比较多的一个模块,因此,对其进行仔细的分析。
本文的首要目标是——搭建分析SystemUI的环境——如何使用Android Studio进行AOSP的开发和调试
注意:在使用Android studio时,对pc的性能有一定的要求,如果pc性能确实不够,可以参考前面列出的5篇文章,使用VS code进行替代。在前面5篇文章中,未提及如何搭建java工程,只提及了如何调试。读者可参考其他关于:Extension Pack for Java插件的使用。搭配前面的5篇调试文章,也可以进行AOSP的开发。
如何使用Android Studio进行AOSP的开发和调试
要使用Android Studio进行SystemUI的编辑工作,需要进行如下的配置:
- 使用AOSP源码中aidegen工具,构建依赖模块
- 使用AOSP源码中的JDK
- 使用AOSP源码中的SDK
- 如何让AndroidManifest.xml和各种资源xml能相互引用
- 如何修改静态代码分析工具lint,以解决IDE中各种标红的错误(实际非错误)
- 如何使用Android studio单步调试SystemUI
接下来我们依次解决上面的步骤。
使用aidegen工具,构建依赖模块
在aosp源码中,加载完编译环境之后,即运行下面的命令之后:
. build/envsetup.shlunch
aidegen即可使用。
接下来使用aidegen工具,产生能在as中打开SystemUI的工程配置文件。如下:
aidegen SystemUI -i s -p /media/wanbiao/disk1t/root/IDE/android-studio/bin# SystemUI:表示要生成工程文件的模块# -i s:表示生成的工程文件对应的IDE为Android studio。# j=IntelliJ s=Android Studio e=Eclipse c=CLion v=VS Code# -p <路径>:表示对应的IDE的安装路径,在生成工程文件完成之后,会自动打开IDE# 其他常见选项如下:# -n:表示不用打开IDE# -s:表示跳过编译各种依赖,如果以前运行过make等命令,可以添加-s# -e:表示排除一些目录,这个非常有用,尤其是大型模块# -d:源码引用的模块的深度# -r:重置所有的aidegen保存的配置# -v:显示debug级别的log# -a:生成整个Android 源码树的工程文件# -l:用指定的语言打开IDE,j=java,c=c/c++,r=Rust# -h:打开帮助
成功运行之后,会得到如下的图片
在frameworks/base/package/SystemUI目录下,会出现一下几个文件:
- .idea文件夹,Android studio使用的工程文件夹,里面可以配置有多少个模块,从上图可以看到,有三个模块分别为:R,SystemUI,dependencies
- SystemUI.iml:配置SystemUI模块的配置文件
- dependencies.iml:配置dependencies模块的配置文件
接下来我们将要对上面的模块进行JDK和SDK的配置。这样as才能正确地在java类之间跳转。
使用AOSP源码中的JDK
可以使用which javac命令,查看具体的jdk路径如下:
然后打开Android studio,将这个jdk加入配置中,
- File->Project Structure
- 按照下图进行配置
如上图,我们选择了aosp目录中的jdk,并将这个jdk配置命名为:aosp-jdk11
接下来配置sdk
使用AOSP源码中的SDK
在android-12.0.0_r34分支中,默认并不会编译SDK,因此,运行下面的命令进行源码的编译。
. build/envsetup.shlunchmake sdk -j8
在Android的编译过程中,可能会报错,例如:module can not be located。又或者xxx文件不存在。
解决办法:只需要找到对应的报错文件,然后打开查看对应的module是否存在,如果不存在,就修改成正确的路径。当然也可简单粗暴的注释掉报错行,前提是:能够确定该行不会影响SDK的功能。
编译成功之后,将会在如下路径中出现:
./out/host/本机平台/sdk/aosp_blueline/android-sdk_eng.wanbiao_linux-x86
然后按照如下所示,添加SDK。
注意:在上图中,要保证SDK内部使用的JDK为我们前面配置的JDK即,aosp-jdk11.同时build target请确保为Android API 31.
将SDK和JDK与SystemUI项目相关联
上面两个步骤只是添加了对应的SDK配置和JDK配置,但是还未与SystemUI相关联起来,参照如下步骤,进行关联
接下来将项目下的各个模块,也配置好SDK,如下图
在点击完,apply之后,会出现一段时间的indexing…请等待片刻。
至此,as已经具备,编辑和跳转java代码的功能。在进行xml资源配置之前,我们需要先解决几个问题
如下:
- 如何正确跳转到源码中,而不是跳转到SDK中
- 源码中的重复文件该怎么操作
如何正确跳转到源码中
在上面的配置中,如果我们跳转源码,将会首先跳转到SDK中。为了能够成功跳转到我们的源码中而不是SDK中
可以有如下两种办法:
- 修改依赖的优先级
- 去掉sdk中的android.jar
两种办法都需要修改,project structure.我们用如下的图片来讲解两种办法
第一种办法:
第一种办法通常需要经常修改,因为as经常会将sdk移动到高优先级
第二种办法:
经过上面的配置,就可以正确的跳转到源码中的位置了
如何处理重复文件
我们处理重复文件,通过将其文件夹标记为exclude 目录即可,如下图
上图将Stub模块下的重复的SystemProperties.java排除在了source file之外。
注意:添加exclude 文件夹,除了上面的右键以外,还可通过对应的.iml文件添加如下的格式:
<content url="file://$MODULE_DIR$/../../../../system/tools/sysprop/stub"> <sourceFolder url="file://$MODULE_DIR$/../../../../system/tools/sysprop/stub" isTestSource="false" /> <excludeFolder url="file://$MODULE_DIR$/../../../../system/tools/sysprop/stub/android/os" />content>
再次注意:除了上面两种方法,还可以通过打开project structure进行修改,如下图
配置Android
上面的处理,只能进行java代码之间的跳转和配置,我们还需要进行AndroidManifest.xml和资源文件的处理。进行如下配置。
-
添加Android
-
选择清单文件和资源文件夹。其中清单文件和资源文件夹是必须
注意:在Android中,一次只能添加一个资源文件夹,如果有多个资源文件夹需要编辑,可以修改此处的配置。例如,我想在res-product中编辑资源的时候,IDE能给我正确的提示,那么可以将此处的Resource directory改为对应的文件夹。
至此,IDE中已经基本可以使用Android的资源了。但是在使用之前,依然还需要处理两个问题:
- 引用系统资源时,跳转到源码而不是sdk
- 处理IDE中报错,但是是正确的使用
如何调整到系统资源
在我的例子中,为了能够正确的关联到系统资源,我将编译出来的sdk中的资源文件夹,删掉,然后通过链接文件夹指向framworks/base/core/res/res目录。使用ln命令即可,不再赘述
处理xml中的非法使用
在AndroidManifest.xml中,如果使用了系统权限如:
<uses-permission android:name="android.permission.BIND_CONTROLS" />
再如,使用了不属于应用的useid
android:sharedUserId="android.uid.systemui"
这些会在IDE中,用红线标识其错误,
再如资源文件夹中使用
@*android:integer/config_mediumAnimTime
访问非public的资源,也会报错
这些都属于静态代码检查工具的功能,我们将对其进行一些修改。
针对上述错误,可做如下修改:
方法一:
- 打开AndroidManifest.xml文件之后,右键单击
- 选中Analyze->Configure Current File Analysis
- 最后选择Syntax
上面的步骤,是告诉IDE,对于当前这个文件,只做语法检查,不做其他检查
方法二:
上面仅仅是非常粗暴的关掉了提示。同样还可以通过File->Settings->Editor->Inspections 在打开的面板中,进行精细的条件。这个涉及到inspect功能的详细解读,不在此赘述。
方法三:
除了通过图形界面操作以外,还可以在当前目录下的lint.xml文件中进行配置。
lint.xml支持的选项,可以通过如下命令得到:
./prebuilts/devtools/tools/lint --list
至此,你可以畅快的在Android Studio中进行,java代码以及xml代码中的编辑工作了。
当然,你也可以对IDE编辑器上面的报错,视而不见,这对于我们的编辑工作并没有什么实质性影响。
在Android studio中调试
关于Android studio怎么调试Android 应用,此处不再介绍,请参考:
android 如何分析应用的内存(五)——Android studio的LLDB:http://t.csdn.cn/jSurw和android 如何分析应用的内存(十五)——Visual Studio Code 调试Android应用:http://t.csdn.cn/wHOgd
本文只介绍,如何能让SystemUI能够正确的调试起来。
事实上,在进行SystemUI的调试中,你将会发现local变量无法debug的场景。为了解决这个问题。需要处理如下几个步骤:
- 确定编译的时候,添加了javac -g选项
- 关掉AOSP中的优化配置
确定编译出来的class文件包含调试信息
在android 如何分析应用的内存(十四)——jdb命令行http://t.csdn.cn/GtbBH文章中,讲解了使用javap进行查看的命令。
接下来我们直接查看SystemUIApplication.class是否含有调试信息。
如果没有上面的输出,则尝试如下修改:
1. Android.mk中增加:LOCAL_JAVACFLAGS += -g2. Android.bp中增加:javacflags:["-g"]
然后重新编译。并再次确定,如果依然没有调试信息。可以尝试切换成userdebug版本
关掉AOSP中的模块优化
在AOSP生成apk的环节中,有一个优化环节,这个优化环节包括资源的压缩,无用代码的剥离,混淆代码等。为了不破坏调试信息,我们需要关闭优化。如下:
1. Android.mk中添加:LOCAL_PROGUARD_ENABLED := false2. Android.bp中添加:optimize:[enabled:false]
完成上述步骤之后,可关闭优化功能,且能够在单步调试中进行本地变量的查看
开始调试代码
为了能让SystemUI启动的时候就等待调试器的加入,我们运行下面的命令:
adb shell am set-debug-app -w com.android.systemui
上面代码的详细解释,可参考:android 如何分析应用的内存(十五)——Visual Studio Code 调试Android应用http://t.csdn.cn/JPBjC一文中的开始测试小节
调试结果
单步调试结果如下图
在上面的图中,可以一步一步单步下去,完成整个执行流程的熟悉。
本篇是我们分析SystemUI的基础环节,必不可少的环节,因为能够单步运行,减轻了许多分析源码的工作。说句人话就是少加班了。
至此,Android studio如何进行SystemUI的源码编辑和调试,介绍完毕。
从下一篇文章开始,我们将正式进入SystemUI的源码中,查看让人魂牵梦绕的SystemUI是怎样被写出来的。
另外,题外话,如果自己的PC性能还可以,可以使用一些AI工具,进行辅助编程,比如笔者正在使用tabnine插件,再比如使用variable extractor将对象翻译成json格式,然后使用工具,进行图形化查看,如前面文章中提及的Debug Visualizer工具
来源地址:https://blog.csdn.net/xiaowanbiao123/article/details/132366807
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341