Android 编译Android 7.1.1源码

谁不是一边燃一边丧,一边拼命一边又不想活了。

前言

最近这阵子又回来爱奇艺实习了,实习的任务是分析爱奇艺的APM平台上的卡顿栈的问题。爱奇艺的APM平台上的卡顿栈都是系统栈,很少有比较明显的栈。因此,只能从源码开始逐层分析。通过分析源码的逐层调用,来判断是否是因为主线程(UI线程)持有子线程的锁导致卡顿,亦或者是由于频繁的进行IPC导致,或者是因为读写竞争导致的问题……

对于源码的分析有利于快速的定位到问题所在,当然,可以借此机会,深入了解Android底层原理和实现。工作本身就是枯燥无味的,但是能够将枯燥无味的生活变为提升自己的方式,有何不可呢?

下载源码

看源码还是看这个好:BeesAndroid——This project aims to help more wireless development engineers understand and master the Android system by providing a series of tools and methods.
这里的教程也是基于这个项目而写的,欢迎关注这个项目。

repo

在线撸源码的网站:http://androidxref.com/

repo是拉取谷歌官方源码的工具,必须要用到它。

下载

下载repo,默认是官方源:

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

如果你没有翻墙,可以使用清华大学的repo镜像:https://mirrors.tuna.tsinghua.edu.cn/help/git-repo/

下载完成后将bin/repo打开,将里面的REPO_URL改成清华大学的镜像:

https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'

在这里插入图片描述

配置git

git config --global user.text "Your Name"
git config --global user.email "[email protected]"

如果是没在翻墙的环境中,就需要配置下git的代理:

扫描二维码关注公众号,回复: 8723383 查看本文章
git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'

初始化仓库

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest

如果需要某个特定的Android版本,可以在后面指定版本号。

Android系统各版本号:https://source.android.com/source/build-numbers.html#source-code-tags-and-builds

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-7.1.1_r28

注:更多源码版本可以参见https://source.android.com/source/build-numbers

下载源码

注意:源码编译之后大概有140G的大小,请确保有充足的空间来下载源码并编译。如果是希望导入到IDEA中,需要对源码进行编译,我编译Android 7.1.1大概花了两个小时多。

同步源码树,开始下载源码,如果后续下载中断,也可以重复执行这个命令。

# 单线程
repo sync

# 指定并发数
repo sync -j4 

源码的下载会经常中断,我们可以写一个脚本自动repo sync,保存成repo.sh,放到WORKING_DIRECTORY目录下

#!/bin/bash   
#FileName  jkYishon.sh  
PATH=~/bin:$PATH   
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-7.1.1_r28
repo sync   
while [ $? = 1 ]; do   
echo "================sync failed, re-sync again ====="   
sleep 3   
repo sync   
done

配置可执行权限,运行即可。

chmod 777 repo.sh
./repo.sh

编译

OpenJDK

Android 7.1.1的源码依赖的是OpenJDK 8版本,因此需要安装下:

sudo apt-get update
sudo apt-get install openjdk-8-jre
sudo apt-get install openjdk-8-jdk

生效的方案1

配置环境:sudo vim /etc/profile添加以下内容,之后执行source /etc/profile

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64
export JRE_HOME=${JAVA_HOME}/jre 
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib 
export PATH=${JAVA_HOME}/bin:$PATH

生效的方案2

临时方案:在工作的Terminal中输入export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64;export PATH=/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin:$PATH

生效的方案3

切换当前的Java版本

sudo update-alternatives --config java
sudo update-alternatives --config javac

安装需要的环境

这是编译需要的一些环境,需要先安装完毕,sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib flex bison gperf build-essential libncurses5-dev:i386 tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 dpkg-dev libsdl1.2-dev libesd0-dev gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev libgl1-mesa-dev libxml2-utils xsltproc unzip m4 lib32z-dev ccache

顺便安装:sudo apt-get install gcc

之后顺手更新下系统吧:sudo apt-get clean && sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get dist-upgrade -y

修改mk

不修改我会遇到这种问题:build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed

修改android-7.1/prebuilts/sdk/tools/jack-admin,找到以下内容:

JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"

改为:

JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096M -cp $LAUNCHER_JAR $LAUNCHER_NAME"

检查Jack服务

建议编译机器的内存大于8G,╮(╯▽╰)╭

Jack服务的基本命令:

./prebuilts/sdk/tools/jack-admin list-server
prebuilts/sdk/tools/jack-admin  start-server
prebuilts/sdk/tools/jack-admin  stop-server

检查下是否安装了Jack服务:./prebuilts/sdk/tools/jack-admin list-server

如果不存在,就直接安装就好了:

cd prebuilts/sdk/tools/
./jack-admin install-server jack-launcher.jar jack-server-4.8.ALPHA.jar

Error

如果出现了以下问题,就是需要分配更多的内存:

Try increasing heap size with java option '-Xmx<size>'.
Warning: This may have produced partial or corrupted output.

如果是内存足够,可以给Jack分配更多的内存:

# 给6G:-Xmx6g
export ANDROID_JACK_VM_ARGS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx6g"
prebuilts/sdk/tools/jack-admin  stop-server
prebuilts/sdk/tools/jack-admin  start-server

更多问题请见:ubuntu 18.04编译Android 7.1源码

开始编译

初始化环境变量:source build/envsetup.sh

选择版本:lunch

选择要编译的版本,可以选aosp_arm-eng的,编译:make -j8j8表示线程数,最好和CPU核数一致。

大概需要编译两个多小时,耐心等候。╮(╯▽╰)╭

编译成功的时候:

在这里插入图片描述

生成索引

生成ipr文件

初始化环境变量:source build/envsetup.sh

运行命令,生成android.ipr文件:make idegen && development/tools/idegen/idegen.sh

大概需要花10多分钟吧,耐心等候,之后会在工程的根目录下生成android.imlandroid.ipr两个文件。

成功了!
在这里插入图片描述

导入IDEA或者AS

接下来我们就要导入源码,但是源码的体积很大,如果全部导入会比较卡,我们可以排除一些代码。例如我只想研究framework里的代码,我们可以在android.iml了添加以下内容。

<excludeFolder url="file://$MODULE_DIR$/.repo" />
<excludeFolder url="file://$MODULE_DIR$/abi" />
<excludeFolder url="file://$MODULE_DIR$/art" />
<excludeFolder url="file://$MODULE_DIR$/bionic" />
<excludeFolder url="file://$MODULE_DIR$/bootable" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/cts" />
<excludeFolder url="file://$MODULE_DIR$/dalvik" />
<excludeFolder url="file://$MODULE_DIR$/developers" />
<excludeFolder url="file://$MODULE_DIR$/development" />
<excludeFolder url="file://$MODULE_DIR$/device" />
<excludeFolder url="file://$MODULE_DIR$/docs" />
<excludeFolder url="file://$MODULE_DIR$/external" />
<excludeFolder url="file://$MODULE_DIR$/hardware" />
<excludeFolder url="file://$MODULE_DIR$/libcore" />
<excludeFolder url="file://$MODULE_DIR$/libnativehelper" />
<excludeFolder url="file://$MODULE_DIR$/ndk" />
<excludeFolder url="file://$MODULE_DIR$/out" />
<excludeFolder url="file://$MODULE_DIR$/packages" />
<excludeFolder url="file://$MODULE_DIR$/pdk" />
<excludeFolder url="file://$MODULE_DIR$/prebuilt" />
<excludeFolder url="file://$MODULE_DIR$/prebuilts" />
<excludeFolder url="file://$MODULE_DIR$/sdk" />
<excludeFolder url="file://$MODULE_DIR$/system" />
<excludeFolder url="file://$MODULE_DIR$/tools" />

添加完毕,我们大概IDEA或者AS,打开android.ipr文件,就会将整个工程导入,可能会需要花十几分钟。

在这里插入图片描述不放张图感觉过意不去……╮(╯▽╰)╭

启动虚拟机

export ANDROID_PRODUCT_OUT=out/target/product/generic 
export ANDROID_BIN=out/host/linux-x86/bin 
PATH=$ANDROID_BIN:$PATH 
source build/envsetup.sh 
lunch aosp_arm-eng 
emulator64-arm -gpu off -memory 2048

附录

调试

发布了181 篇原创文章 · 获赞 217 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/Notzuonotdied/article/details/89192675