Android 12 源码分析 —— 应用层 一(SystemUI准备篇)

Android 12 源码分析 —— 应用层一(SystemUI准备篇)

在接下来的时间中,将会使用Pixel 3(blueline)作为研究对象,选用AOSP的android-12.0.0_r34分支作源代码。

先从android的应用层进行探析,然后慢慢深入android的framework,接着进入android的hal层,最后以android的linux内核结束,期间可能会穿插一些其他文章如android的art虚拟机分析等。

本文是整个系列的第一篇,但是在此之前,请务必阅读以下的文章,他们将在以后的源码分析中时不时出场

  1. android 如何分析应用的内存(二)——xdd,gdb命令行(http://t.csdn.cn/RENbG)
  2. android 如何分析应用的内存(三)——LLDB命令行(http://t.csdn.cn/Vpw8e)
  3. android 如何分析应用的内存(四)——Visual studio code的LLDB(http://t.csdn.cn/8ZM8A)
  4. android 如何分析应用的内存(十四)——jdb命令行(http://t.csdn.cn/99r2G)
  5. 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的编辑工作,需要进行如下的配置:

  1. 使用AOSP源码中aidegen工具,构建依赖模块
  2. 使用AOSP源码中的JDK
  3. 使用AOSP源码中的SDK
  4. 如何让AndroidManifest.xml和各种资源xml能相互引用
  5. 如何修改静态代码分析工具lint,以解决IDE中各种标红的错误(实际非错误)
  6. 如何使用Android studio单步调试SystemUI

接下来我们依次解决上面的步骤。

使用aidegen工具,构建依赖模块

在aosp源码中,加载完编译环境之后,即运行下面的命令之后:

. build/envsetup.sh
lunch

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目录下,会出现一下几个文件:

  1. .idea文件夹,Android studio使用的工程文件夹,里面可以配置有多少个模块,从上图可以看到,有三个模块分别为:R,SystemUI,dependencies
  2. SystemUI.iml:配置SystemUI模块的配置文件
  3. dependencies.iml:配置dependencies模块的配置文件

接下来我们将要对上面的模块进行JDK和SDK的配置。这样as才能正确地在java类之间跳转。

使用AOSP源码中的JDK

可以使用which javac命令,查看具体的jdk路径如下:
在这里插入图片描述

然后打开Android studio,将这个jdk加入配置中,

  1. File->Project Structure
  2. 按照下图进行配置
    在这里插入图片描述

在这里插入图片描述

如上图,我们选择了aosp目录中的jdk,并将这个jdk配置命名为:aosp-jdk11

接下来配置sdk

使用AOSP源码中的SDK

在android-12.0.0_r34分支中,默认并不会编译SDK,因此,运行下面的命令进行源码的编译。

. build/envsetup.sh
lunch
make 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资源配置之前,我们需要先解决几个问题
如下:

  1. 如何正确跳转到源码中,而不是跳转到SDK中
  2. 源码中的重复文件该怎么操作

如何正确跳转到源码中

在上面的配置中,如果我们跳转源码,将会首先跳转到SDK中。为了能够成功跳转到我们的源码中而不是SDK中
可以有如下两种办法:

  1. 修改依赖的优先级
  2. 去掉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和资源文件的处理。进行如下配置。

  1. 添加Android
    在这里插入图片描述

  2. 选择清单文件和资源文件夹。其中清单文件和资源文件夹是必须
    在这里插入图片描述

注意:在Android中,一次只能添加一个资源文件夹,如果有多个资源文件夹需要编辑,可以修改此处的配置。例如,我想在res-product中编辑资源的时候,IDE能给我正确的提示,那么可以将此处的Resource directory改为对应的文件夹。

至此,IDE中已经基本可以使用Android的资源了。但是在使用之前,依然还需要处理两个问题:

  1. 引用系统资源时,跳转到源码而不是sdk
  2. 处理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的资源,也会报错

这些都属于静态代码检查工具的功能,我们将对其进行一些修改。

针对上述错误,可做如下修改:
方法一:

  1. 打开AndroidManifest.xml文件之后,右键单击
  2. 选中Analyze->Configure Current File Analysis
  3. 最后选择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的场景。为了解决这个问题。需要处理如下几个步骤:

  1. 确定编译的时候,添加了javac -g选项
  2. 关掉AOSP中的优化配置

确定编译出来的class文件包含调试信息

在android 如何分析应用的内存(十四)——jdb命令行http://t.csdn.cn/GtbBH文章中,讲解了使用javap进行查看的命令。

接下来我们直接查看SystemUIApplication.class是否含有调试信息。
在这里插入图片描述

如果没有上面的输出,则尝试如下修改:

1. Android.mk中增加:LOCAL_JAVACFLAGS += -g
2. Android.bp中增加:javacflags:["-g"]

然后重新编译。并再次确定,如果依然没有调试信息。可以尝试切换成userdebug版本

关掉AOSP中的模块优化

在AOSP生成apk的环节中,有一个优化环节,这个优化环节包括资源的压缩,无用代码的剥离,混淆代码等。为了不破坏调试信息,我们需要关闭优化。如下:

1. Android.mk中添加:LOCAL_PROGUARD_ENABLED := false
2. 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工具

猜你喜欢

转载自blog.csdn.net/xiaowanbiao123/article/details/132366807