我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

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

  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 += -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

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

在前面几篇文章中,我们详细介绍了Android系统进程间通信机制Binder的原理,并且深入分析了系统提供的Binder运行库和驱动程序的源代码。细心的读者会发现,这几篇文章分析的Binder接口都是基于C/C++语言来实现
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录