一.準備工作
- 系統最好是Linux或者mac OS(本文基于Ubuntu)。
- Ubuntu設置永不休眠,在setting中搜索power.blank-screen選擇never。
- 一塊大一點兒的硬盤,至少得有200G剩余空間。
二.下載Aosp源碼
1.安裝GIT
首先需要安裝Git,因為源碼是用Git管理的。
sudo apt-get install git
接下來創建一個bin文件夾,并加入到PATH中,有點像Windows的環境變量。
mkdir ~/bin
PATH=~/bin:$PATH
然后初始化Git,郵箱和姓名。
git config --global user.email "xxx@gmail.com"
git config --global user.name "xxx"
2.安裝Python環境
sudo apt-get install python
3.安裝repo及配置
repo 是一個python 腳本(所以我們上面要配置Python環境),因為Android源碼包含數百個git庫,簡化幫助管理git Android版本庫的工具。
(1.)安裝curl下載的庫:
sudo apt-get install curl
(2.)下載repo并設置可以運行權限。
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
chmod a+x ~/bin/repo
(3.)添加下載源。
google 的AOSP 的話,因為FQ和數據量太大,且需要需要翻墻影響速度,因此優先考慮國內的鏡像(本文使用的是清華的源)。
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
4.初始化及同步源碼
(1.)創建文件夾
創建一個AOSP文件夾,cdd到文件夾里面去待會兒需要把源碼下載到這里:
mkdir aosp
cd aosp
(2.)初始化Aosp倉庫
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest
(3.)初始化并指定版本
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-8.0.0_r36
AOSP對應關系查看地址: 對應關系
(4.)開始同步源碼
repo sync -j4
-j表示并發數.
因為Android的源碼越來越大,repo sync失敗的概率也越來越高。所以我們可以避開使用repo sync的方式,而采用下載預下載包的方式來實現下載源碼。
5.預下載包的方式
1. 下載預下載包
在windows或者Linux上面通過迅雷下載https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar
。
wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar #下載初始化包
2. 解壓預下載包
tar xf aosp-latest.tar
cd AOSP->解壓得到的 AOSP 工程目錄,這時 ls 的話什么也看不到,因為只有一個隱藏的 .repo 目錄
3. 查看分支
cd .repo/manifests
git branch -a
4. 在aosp目錄選擇需要同步的版本
repo init -b android-9.0.0_r55
repo sync # 正常同步一遍即可得到完整目錄
或者直接在aosp目錄設置好你要同步的分支:
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-8.0.0_r36
repo sync # 正常同步一遍即可得到完整目錄
如果僅加載具體模塊:
repo sync platform/prebuilts/clang/host/darwin-x86
6.防止下載源碼執行腳本卡死
通過自定義Shell腳本啟動源碼下載可以有效防止,同步源碼時腳本被卡死的問題。
(1.)在AOSP文件夾中新建down.sh文件
#!/bin/bash
echo “======= start repo sync =======”
cd ~/Desktop/AOSP
repo sync -j4
while [ $? == 1 ]; do
echo “====== sync failed! re-sync again =====”
sleep 3
repo sync -j4
(2.)執行down.sh文件
sh down.sh
三.AOSP源碼目錄結構
- abi Application Binary Interface 應用程序二進制接口,abi相信同學們在SO庫調用上遇到過,如果不支持該平臺的話就說不ABI不支持。
- art Android Runtime 安卓運行時。這個會提前把字節碼編譯成二進制機器碼保存起來,執行的時候加載速度比較快。Dalvik虛擬機則是在加載以后再去編譯的,所以速度上ART會比Dalvik快一點。犧牲空間來贏取時間。
- bionic 基礎庫,Android系統與Linux內核的橋梁。Bionic 音標為 bī??nik,翻譯為"仿生"。
- bootable 系統啟動引導相關程序
- build 用于構建Android系統的工具,也就是用于編譯Android系統的
- cts Compatibility Test Suite 兼容性測試
- dalvik dalvik虛擬機,用于解析執行dex文件的虛擬機
- developers 開發者目錄
- developerment 開發目錄,比如說應用,application就在里面了,apps
- devices 設備相關的配置信息,什么索尼、HTC、自己的產品,就可以定義在這個目錄下了
- docs 文檔
- external 開源模組相關文件
- frameworks 系統架構,Android的核心了
- hardware hal層代碼,硬件抽象層
- libcore 核心庫
- libnativehelper native幫助庫,實現JNI的相關文件
- ndk native development kit
- out 輸出目錄,編譯以后生成的目錄,相關的產出就在這里了
- packages 應用程序包。一些系統的應用就在這里了,比如說藍牙,Launcher,相機,撥號之類的。
- pdk Plug-in Development Kit (PDK) is designed to help you build your own pattern projects
- platform_testing 平臺測試
- prebuilts x86/arm架構下預編譯的文件
- sdk software development kit
- system 底層系統文件
- toolchain 工具鏈
- tools 工具文件
- Makefile mk文件,用于控制編譯
四.AOSP源碼整編
編譯AOSP源碼需要配置好JAVA環境.
1.安裝Java編譯環境
sudo apt-get update
sudo apt-get install openjdk-8-jdk
2.進入AOSP文件夾,進行編譯
(1.)初始化編譯環境
source build/envsetup.sh
(2.)刪除上一次編譯的結果,初次編譯可以不需要這一步
make clobber
(3.)選擇與設備對應的編譯版本
lunch XX
選擇與設備對應的編譯版本.如:編譯開發工程師的版本lunch aosp_x86-eng
,可以方便debug
編譯版本選擇
如果lunch
命令沒有加對應的編譯版本則會有以下信息輸出:
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_mips-eng
4. aosp_mips64-eng
5. aosp_x86-eng
6. aosp_x86_64-eng
7. full_fugu-userdebug
8. aosp_fugu-userdebug
9. mini_emulator_arm64-userdebug
10. m_e_arm-userdebug
11. m_e_mips64-eng
12. m_e_mips-userdebug
13. mini_emulator_x86_64-userdebug
14. mini_emulator_x86-userdebug
15. aosp_dragon-userdebug
16. aosp_dragon-eng
17. aosp_marlin-userdebug
18. aosp_sailfish-userdebug
19. aosp_flounder-userdebug
20. aosp_angler-userdebug
21. aosp_bullhead-userdebug
22. hikey-userdebug
23. aosp_shamu-userdebug
Which would you like? [aosp_arm-eng]
這里需要選擇編譯目標的格式(選擇前面的序號,按回車即可),編譯目標的格式組成為BUILD-BUILDTYPE
,比如aosp_arm-eng的BUILD為aosp_arm,BUILDTYPE為eng。 其中BUILD表示編譯出的鏡像可以運行在什么環境,aosp代表Android開源項目,arm表示系統是運行在arm架構的處理器上。 更多參考官方文檔文檔。
BUILDTYPE 指的是編譯類型,有以下三種:
- user:用來正式發布到市場的版本,權限受限,如沒有 root 權限,不能 dedug,adb默認處于停用狀態。
- userdebug:在user版本的基礎上開放了 root 權限和 debug 權限,adb默認處于啟用狀態。一般用于調試真機。
- eng:開發工程師的版本,擁有最大的權限(root等),具有額外調試工具的開發配置。一般用于模擬器。
如果你沒有Nexus設備,只想編譯完后運行在模擬器查看,那么BUILD可以選擇aosp_x86,BUILDTYPE選擇eng。
(4.)開始編譯
make -j8
j后面數字幾就是多少線程,最多不超過你的cpu總線程,
編譯成功會顯示如下:
Creating filesystem with parameters:
Size: 2147483648
Block size: 4096
Blocks per group: 32768
Inodes per group: 8192
Inode size: 256
Journal blocks: 8192
Label: system
Blocks: 524288
Block groups: 16
Reserved block group size: 127
Created filesystem with 2216/131072 inodes and 199826/524288 blocks
[100% 7669/7669] Install system fs ima.../target/product/generic_x86/system.img
out/target/product/generic_x86/system.img+ maxsize=2192446080 blocksize=2112 total=2147483648 reserve=22146432
#### make completed successfully (01:24:41 (hh:mm:ss)) ####
會在源碼跟目錄out/target/product/angler目錄下生成鏡像文件:
- system.img:系統鏡像
- ramdisk.img:根文件系統鏡像
- userdata.img:用戶數據鏡像
- recovery.img:recovery鏡像
- boot.img:啟動鏡像
- vendor.img:驅動鏡像
最終會在 out/target/product/generic_x86/目錄生成了三個重要的鏡像文件: system.img、userdata.img、ramdisk.img。大概介紹著三個鏡像文件:
- system.img:系統鏡像,里面包含了Android系統主要的目錄和文件,通過init.c進行解析并mount掛載到/system目錄下。
- userdata.img:用戶鏡像,是Android系統中存放用戶數據的,通過init.c進行解析并mount掛載到/data目錄下。
- ramdisk.img:根文件系統鏡像,包含一些啟動Android系統的重要文件,比如init.rc。
3.編譯錯誤解決
(1.)缺少libncurses.so.5
報錯信息:
error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
解決方式:
sudo apt-get update
for 32-bit binaries :
sudo apt-get install libncurses5:i386
for 64-bit binaries :
sudo apt-get install libncurses5
(2.)缺少M4
報錯信息:
/bin/bash: m4: command not found
解決方式:
sudo apt-get install m4
(3.)去除所有本地化設置
報錯信息:
FAILED: out/host/linux-x86/obj/EXECUTABLES/checkpolicy_intermediates/policy_scan.c
解決方法:
export LC_ALL=C
LC_ALL=C 是為了去除所有本地化的設置,讓命令能正確執行, 但是不可以修改~/.bashrc,會導致終端內中文顯示為數字(應該是對應的編碼)
(4.)jack-server的問題
jack server交互命令:
jack-admin start-server
jack-admin kill-server
jack-admin list-server
jack-admin uninstall-server
mm -j32 showcommands &> mm.out
jack-admin install-server jack-launcher.jar jack-server-4.8.ALPHA.jar
jack-admin dump-report
jack-admin dump-re
jack-admin server-log 查找log所在目錄
問題一:多用戶同時編譯時報錯
錯誤信息:
FAILED: setup-jack-server
/bin/bash -c "(prebuilts/sdk/tools/jack-admin install-server prebuilts/sdk/tools/jack-launcher.jar prebuilts/sdk/tools/jack-server-4.11.ALPHA.jar 2>&1 || (exit 0) ) && (JACK_SERVER_VM_ARGUMENTS=\"-Dfile.encoding=UTF-8 -XX:+TieredCompilation\" prebuilts/sdk/tools/jack-admin start-server 2>&1 || exit 0 ) && (prebuilts/sdk/tools/jack-admin update server prebuilts/sdk/tools/jack-server-4.11.ALPHA.jar 4.11.ALPHA 2>&1 || exit 0 ) && (prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-4.31.CANDIDATE.jar 4.31.CANDIDATE || exit 47 )"
Jack server already installed in "/home/disk/lixialong/.jack-server"
Communication error with Jack server (35), try 'jack-diagnose' or see Jack server log
SSL error when connecting to the Jack server. Try 'jack-diagnose'
SSL error when connecting to the Jack server. Try 'jack-diagnose'
解決方案:同時修改HOME/.jack-server/config.properties中的端口號(比如都改為8386/8387,端口號值為0~65535,1024下的值不要用),方可支持多用戶同時編譯。
查看端口是否一致:cat ~/.jack-server/config.properties|grep -i port && cat ~/.jack|grep -i port|grep -v LOG &&cat ~/.jack-settings|grep -i port
- $HOME/.jack-settings
SERVER_PORT_SERVICE=8386
SERVER_PORT_ADMIN=8387
- $HOME/.jack-server/config.properties
jack.server.service.port=8386
jack.server.admin.port=8387
- $HOME/.jack
SERVER_PORT_SERVICE=8288
SERVER_PORT_ADMIN=8289
問題二: No Jack server running. Try 'jack-admin start-server'
錯誤信息
com.android.jack.server.api.v01.ServerException: './config.properties' musthave permission rw------- but have rwx------
Caused by: java.io.IOException: './config.properties' must have permissionrw------- but have rwx------
...
解決方案:通過查看文件 HOME/.jack-server/config.properties的權限由rwx改為rw即可解決問題。
問題三:未配置變量信息導致問題
錯誤信息:
ERROR: Communication error with Jack server (52) make: *** [out/target/common/obj/JAVA_LIBRARIES/libutil_intermediates/classes.jack] Error
這種情況多半屬于jack-admin缺少變量JACK_JAR而導致的。
解決方案:
工程根目錄內執行以下三句,再進行編譯。
export JACK_JAR=./out/host/linux-x86/framework/jack.jar
./out/host/linux-x86/bin/jack-admin stop-server
./out/host/linux-x86/bin/jack-admin start-server
問題四:TLSv1, TLSv1.1 禁用
報錯信息:
Ensuring Jack server is installed and started
解決方式:
sudo vim /etc/java-8-openjdk/security/java.security
vim里面輸入/搜索jdk.tls.disabledAlgorithms= 將TLSv1, TLSv1.1 光標選中輸入x刪除掉取消禁用.然后wq保存.
修改后:
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves
aosp/prebuilts/sdk/tools/ 目錄下執行./jack-admin kill-server && ./jack-admin start-server 成功。
(4.)xmllint的問題
報錯信息:
/bin/bash: xmllint: command not found
解決方案:
sudo apt-get install libxml2-utils
(5.)編譯內存不足
報錯信息
Try increasing heap size with java option '-Xmx<size>'錯誤
解決方案:
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g"
jack-admin kill-server
jack-admin start-server
五.運行模擬器
1.啟動模擬器
在編譯完成之后,就可以通過以下命令運行Android虛擬機了,由于之前已經執行過source和lunch命令了,可以直接運行:
source build/envsetup.sh
lunch aosp_x86-eng
emulator
就會啟動模擬器了.
2.啟動模擬器失敗
嘗試使用-verbose選項(即“emulator -verbose”),這將打印模擬器正在做什么/正在探測哪些文件,并給出有關錯誤的更多詳細信息。
emulator -use-system-libs
啟動模模擬器報錯:
emulator: ERROR: x86_64 emulation currently requires hardware acceleration!
Please ensure KVM is properly installed and usable.
CPU acceleration status: This user doesn't have permissions to use KVM (/dev/kvm)
- 安裝 Qemu-KVM 和 cpu-checker
sudo apt-get install qemu-kvm cpu-checker
sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
- 查看系統 KVM 是否可用
$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
- 創建 kvm 用戶組并把當前登錄用戶(如 peng )添加到 kvm 用戶組
sudo addgroup kvm
sudo usermod -a -G kvm peng
- 改變 /dev/kvm 用戶組為 kvm
sudo chgrp kvm /dev/kvm
- 創建 udev rule,并寫入 KERNEL=="kvm", GROUP="kvm", MODE="0660"
sudo gedit /etc/udev/rules.d/60-qemu-kvm.rules
KERNEL=="kvm", GROUP="kvm", MODE="0660"
- 重啟ubuntu系統然后運行emulator
六.AOSP源碼編譯某個單獨的模塊
上面的編譯我們都是對整個Android系統進行編譯的.如果我們要編譯系統的Settings應用模塊,這就屬于源碼單編某一個模塊.
在AOSP根目錄執行:
source build/envsetup.sh
lunch aosp_x86-eng
進入Settings的目錄:
cd packages/apps/Settings
通過mm編譯當前目錄下的模塊,不編譯依賴模塊。
mm
編譯成功后會有提示生成文件的存放路徑。除了Settings.odex文件,還會在out/target/product/generic_x86/system/priv-app/Settings目錄下生成Settings.apk。
此外還有以下命令可以進行單編:
- mmm:編譯指定目錄下的模塊,不編譯它所依賴的其它模塊。
- mma:編譯當前目錄下的模塊及其依賴項。
- mmma:編譯指定路徑下所有模塊,并且包含依賴。
如果對系統模塊的源碼進行修改,查看生成的APK文件,有兩種方式:
- 通過adb push或者adb install 來安裝APK。
- 使用make snod命令,重新生成 system.img,運行模擬器查看。
七.導入源碼到AS
1.編譯idegen模塊,生成IDE項目文件
在源碼中,存在idegen模塊,該模塊專門用來為idea工具生成系統源碼的project.默認情況下aosp編譯并不會生成該文件。
在開始編譯該模塊之前,首先確保你已經編譯過Android源碼了,如果沒有,先要進行AOSP編譯.和編譯普通的模塊一樣,我們用mmm命令編譯idegen.
在開始編譯之前,檢查out/host/linux-x86/framework/目錄下是否存在idegen.jar文件,存在則說明你已經編譯過該模塊,否者,則需要編譯.執行如下命令即可:
source build/envsetup.sh 將腳本添加到系統內
lunch 并選擇要編譯的項目
mmm development/tools/idegen/
sudo ./development/tools/idegen/idegen.sh
其中mmm development/tools/idegen/執行完成后會生成idegen.jar,而sodo ./development/tools/idegen/idegen.sh則會在源碼目錄下生成IEDA工程配置文件:android.ipr,android.iml及android.iws.
簡單的說明一下這三個文件的作用:
- android.ipr:通常是保存工程相關的設置,比如編譯器配置,入口,相關的libraries等
- android.iml:則是主要是描述了modules,比如modules的路徑,依賴關系等.
- android.iws:則主要是包含了一些個人工作區的設置.
"android.iml"和"android.ipr"一般是"只讀"的屬性,我們這里建議大家,把這兩個文件改成可讀可寫,否則,在更改一些項目配置的時候可能會出現無法保存的情況,執行如下兩條命令即可。
sudo chmod 777 android.iml
sudo chmod 777 android.ipr
2 導入源碼到AndroidStudio
(1.)配置AS
IDE內存優化
因為源碼數量非常多,所以導入時IDEA/AS會需要大量內存。所以我們需要編輯IDE的VM選項。配置文件為
IDEA的是IDEA_HOME/bin/idea.vmoptions
AS的是AS_HOME/bin/studio.vmoptions
注意,AS有一個64位版本的配置文件studio64.vmoptions最好一并修改了。
找到上面的配置文件,將對應的內容修改為
-Xms748m -Xmx748m
即將VM的堆內存最小和最大都設置為748m。官方要求至少在748m以上,根據實際情況進行配置即可
(2.)導入源碼
接下來,我們導入源碼:打開Android Studio,點擊File->Open,選擇剛才生成的android.ipr文件即可,然后就是漫長的等待,注意此時是將源碼完全導入到AS中了。
如果AS運行比較慢我們就需要排除一些不需要導入的模塊。
(3.) 排除模塊
很多情況下,我們希望不導入某些模塊,那么就可以在導入前修改android.iml文件,通過添加配置的方式告訴AS不導入某些模塊,比如現在我不想導入art模塊,那么就在android.iml文件中添加:
<excludeFloder url="file://$MODULE_DIR$"/abi>
不難發現,其格式為:<excludeFloder url="file://$MODULE_DIR$"/模塊名>
注:編譯生成的android.iml文件中已經默認排除了一些模塊,通過搜索excludeFolder關鍵字可找到.
如果比較關心framworks和packages模塊,則保留framworks和packages模塊,將其他模塊全部排除,在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$/external/bluetooth" />
<excludeFolder url="file://$MODULE_DIR$/external/chromium" />
<excludeFolder url="file://$MODULE_DIR$/external/emma" />
<excludeFolder url="file://$MODULE_DIR$/external/icu4c" />
<excludeFolder url="file://$MODULE_DIR$/external/jdiff" />
<excludeFolder url="file://$MODULE_DIR$/external/webkit" />
<excludeFolder url="file://$MODULE_DIR$/frameworks/base/docs" />
<excludeFolder url="file://$MODULE_DIR$/frameworks/base/extension" />
<excludeFolder url="file://$MODULE_DIR$/hardware" />
<excludeFolder url="file://$MODULE_DIR$/kernel" />
<excludeFolder url="file://$MODULE_DIR$/kernel-3.18" />
<excludeFolder url="file://$MODULE_DIR$/libcore" />
<excludeFolder url="file://$MODULE_DIR$/libnativehelper" />
<excludeFolder url="file://$MODULE_DIR$/ndk" />
<excludeFolder url="file://$MODULE_DIR$/oem-release" />
<excludeFolder url="file://$MODULE_DIR$/out" />
<excludeFolder url="file://$MODULE_DIR$/out/eclipse" />
<excludeFolder url="file://$MODULE_DIR$/out/host" />
<excludeFolder url="file://$MODULE_DIR$/out/target/common/docs" />
<excludeFolder url="file://$MODULE_DIR$/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates" />
<excludeFolder url="file://$MODULE_DIR$/out/target/product" />
<excludeFolder url="file://$MODULE_DIR$/pdk" />
<excludeFolder url="file://$MODULE_DIR$/platform_testing" />
<excludeFolder url="file://$MODULE_DIR$/prebuilt" />
<excludeFolder url="file://$MODULE_DIR$/prebuilts" />
<excludeFolder url="file://$MODULE_DIR$/rc_projects" />
<excludeFolder url="file://$MODULE_DIR$/sdk" />
<excludeFolder url="file://$MODULE_DIR$/system" />
<excludeFolder url="file://$MODULE_DIR$/tools" />
<excludeFolder url="file://$MODULE_DIR$/trusty" />
<excludeFolder url="file://$MODULE_DIR$/vendor" />
完成之后,按照上面說的步驟,使用Android Studio選中"android.ipr"打開項目即可。
等項目加載完成后,我們還可以通過Android Studio對Exclude的Module進行調整,所以也不用害怕這里Exclude掉了有用的代碼,或少Exclude了一部分代碼,在項目加載完以后再進行調整就行了。此處和在android.iml文件中添加excludeFolder 的功能是一樣的;
打開"Project Structure",中間的窗口選擇"android",在彈出的窗口中左邊欄中選擇"Modules",而后在右邊的窗口中選擇"Sources"。
在這里我們可以看到項目的所有代碼目錄,我們可以選中不需要的module,并點擊上面的"Excluded"按鈕,當被選中的目錄變為橙色,即表示完成Exclude操作;
如果想要取消對某代碼目錄的Exclude操作,選中該目錄,再次點擊"Excluded"按鈕,等待目錄變為藍色即可。
(3.) 配置源碼正確跳轉
當我們導入完源碼后,就可以查看整個系統的源碼,但是有個問題,打開的Java代碼,查看集成關系或者調用關系的時候,還是會跳轉到.class文件中,而不是相應的Java類,
比如PhoneWindow.java繼承了Window.java,但是我們跳轉的時候卻跳到了Window.class,并沒有跳轉到frameworks目錄下對應的源碼類,而是jar包中的類。
我們需要讓其跳轉到相應的類中。我們就需要新建一個沒有任何jar庫的SDK給到系統源碼項目的依賴, 這里的配置JDK/SDK,是用于解決在分析和調試源碼的過程,能正確地跳轉到目標源碼,
而非SDK中的代碼。
-
新建JDK
Project Structure -> SDKs, 新建 JDK, 其中JDK目錄可選擇跟原本JDK一致即可,任意取一個名字,這里取empty_jdk 然后刪除這里取empty_jdk其classpath和SourcePath的內容,確保使用Android系統源碼文件
jdk_none
-
配置SDK
Project Structure -> SDKs, 選中與自己編譯的AOSP對應的SDk版本(如果沒有對應的就到SDKmanager里面取下載一個對應的版本) Android API 28 Platform, 然后選擇其Java SDK為前面新建的empty_jdk
sdk_none
-
選擇SDK
Project Structure -> Project -> 選中Project SDK, 選擇前面的Android API 28 Platform
project_sdk
-
建立依賴
Project Structure -> Modules -> android -> Dependencies: Module選擇我們上面編輯過的SDK。然后點擊下圖綠色的+號來選擇Jars or directories,將 aosp/frameworks 目錄添加進來,再按照同樣的步驟將aosp/external 目錄, 也可添加其他所關注的源碼;
然后選中其他所有的依賴,點擊右邊的下移箭頭將其他依賴移動到我們添加的目錄下面。(或者將其他的所有依賴刪除)
注意,一般我們大部分人不在ubuntu下開發app ,為了能在Windows或Mac系統下也能使用Android Studio查看源碼,
可以按照上面的步驟,那樣直接拷貝ubuntu下的android.iml和android.ipr文件到Windows或Mac系統下的android源碼根目錄下,
然后導入Adnroid Studio中,這樣就可以在這兩個平臺上進行查看源碼了。
八.通過AS調試源碼
1. 打開模擬器
要調試代碼,首先要打開模擬器,注意不是Android Studio自帶的模擬器,而是通過編譯后的代碼啟動的模擬器,否則可能出現代碼不對應的問題。
直接運行emulator命令是無法啟動的,執行方法如下:
source build/envsteup.sh
lunch 6 //和編譯時對應
emulator
接下來通過Run->Attache debugger to Android process,在彈出的Choose Process框內必須選擇Show all processes,否則看不到相關的進程:然后選擇system_process,就可以進行調試了。
九.Android刷機知識
1.BootLoader
機器首先要啟動,CPU 最先執行的一段程序就是 BootLoader,是在操作系統內核運行之前運行的一段小程序。其實Bootloader就相當于電腦的bios。 通過這段小程序,進行硬件初始化,獲取內存大小信息等,調整手機到適配狀態,從而將系統的軟硬件環境帶到一個合適狀態,以便為最終調用操作系統內核準備好正確的環境。
。很多的手機廠商都會鎖住BootLoader,這樣你就只能使用官方的系統,想要第三方的ROM能夠運行,或者破解官方系統這時候就需要進行bootloader解鎖!這是刷機的第一步, 當然也有很多手機沒有bootloader鎖!我們只需要知道要想刷機就得先bootloader解鎖。
2.FastBoot
fastboot,它是bootloader后期進入的一個特殊階段。例如小米手機開機同時按音量下建就會進入這個模式.也是一種模式。可以通過數據線與電腦連接,然后在電腦上執行一些命令,如刷系統鏡像到手機上。fastboot可以理解為實現了一個簡單的通信協議,接收命令并更新鏡像文件,其他什么的干不了。
需使用USB數據線連接電腦和手機的一種線刷刷機模式,大部分第三方的Recovery刷入,或者救磚均是在Fastboot模式下進行,所以這種方式稱為線刷。 fastboot需要bootloader的支持,所以不是每家手機都會支持這種模式。Fastboot 可以說是一個通信協議,電腦可以通過這個通信協議,直接向手機系統不同分區中寫入文件(.img 文件)。
fastboot(bootloader)模式怎么進入?
大多數安卓手機,都可以在關機狀態下,然后同時按住【電源鍵】+【音量+】鍵,大約2-3s后,就可以進入Fastboot模式。 作為開發者在開機狀態下可以用下面的方式進入:
adb reboot bootloader
fastboot命令
然后就可以執行下面的fastboot命令了:
fastboot flashing unlock #6.0以上設備 設備必須解鎖,開始刷機(這個不同的手機廠商不同)
fastboot erase {partition} # 擦除分區
fastboot erase frp # 擦除 frp 分區,frp 即 Factory Reset Protection,用于防止用戶信息在手機丟失后外泄
fastboot flash boot boot.img # 刷入 boot 分區
fastboot flash system system.img # 刷入 system 分區
fastboot flash recovery recovery.img # 刷入 recovery 分區
fastboot flashall #燒寫所有分區,注意:此命令會在當前目錄中查找所有img文件,將這些img文件燒寫到所有對應的分區中,并重新啟動手機。
fastboot format data # 格式化 data 分區
fastboot flashing lock # 設備上鎖,刷機完畢
fastboot continue # 自動重啟設備
fastboot reboot# 重啟手機
fastboot reboot-bootloader# 重啟到bootloader 刷機用
fastboot devices ## 發現手機,顯示當前哪些手機通過fastboot連接了
3.Recovery
如果沒有進入fastboot,bootloader繼續執行,如果又發現有特殊的按鍵組合,比如小米上是音量上鍵和開機鍵,則會進入recovery模式。它里面包含了一個kernel以及一個可執行程序recovery,以
及一些初始化文件。Recovery模式指的是一種可以對安卓機內部的數據或系統進行修改的模式,也叫工程模式,像是電腦上的小型winPE系統,winPE可以在電腦上安裝操作系統,或者做些刪除備份、管理的工作。
官方Recovery用處不大,所以通常會刷入一個第三方的Recovery ,Recovery 更類似于一個小型的管理系統。只不過功能簡單,所做的管理有限。在recovery模式下,會加載了部分文件系統,所以才可以讀sdcard中的update.zip進行刷機,當然,也可以清除cache和用戶數據。
該模式可根據用戶的需要進行修改,因此有官方recovery模式以及第三方recovery模式。第三方recovery模式可以識別第三方rom包,因此可以用來刷機。而官方recovery一般不能識別第三方zip文件。好用的第三方RE:TWRP 和 CWM Recovery刷機包是稱為Google Update 格式。在用Recovery恢復時,刷機包通常放在SD卡里,所以這里刷機一般稱為卡刷。
4.線刷和卡刷
- 線刷: 直接想手機硬盤寫入*.img 文件,我個人覺得這種方法比較快捷,而且省事。但是必須借助電腦和數據線。
- 卡刷:就是利用recovery的從SD卡中更新系統的這個功能,如果你想刷第三方Rom,必須刷入個第三方recovery,只有fastboot模式才能刷recovery.img。卡刷有個限制,必須要把想要更新的ROM(Android系統)拷貝到SD卡上。如果手機已經是磚了。那只能用線刷了。
十.手機硬件驅動知識
1. 硬件驅動的作用
AOSP是一個由谷歌維護的開源操作系統開發項目,既然是開源項目,也就意味著任何人都可以自由地審查和貢獻代碼以及修復項目倉庫,而谷歌引領著大方向和大部分的開發工作。AOSP會定期為Android加入最新的安全補丁,谷歌每年也會在其I/O開發者大會上公布操作系統的新功能。除了開放貢獻代碼外,AOSP還可以在開源許可下自由使用和修改。
比如,小米,華為等廠商根據自己的目的自由調整該項目,并開發了自己的衍生產品,包括多用途的emui和miui。需要注意的是,AOSP包含了開發者構建Android所需的一切,但它并不包括成品智能手機所需的一切。
谷歌和AOSP無法為所有硬件配置提供內核設備驅動。所謂設備驅動,是指手機硬件所需的固件,比如處理器或攝像頭。手機和SoC制造商,如高通和三星,必須將這些驅動程序納入他們的Android構建中。
這也是為什么從AOSP到實際設備的系統更新需要一定時間的原因。其次AOSP也不包含谷歌的軟件應用套件,如Chrome瀏覽器、YouTube,甚至谷歌Play商店。
它也不包括谷歌的一些底層技術和API,而這些技術和API可以實現移動支付、語音命令和云存儲等功能,這些都是作為谷歌移動服務(GMS)單獨授權的。 任何廠商想要在系統中安裝GMS,都必須為自己的設備獲得GMS授權和移動應用分發協議(MADA),然后通過多項兼容性測試。有Android兼容性測試套件(CTS)來驗證軟件和硬件以及API。
正因為AOSP開源的特性,許多的硬件廠商的驅動代碼并不是開源的,所以AOSP會有一個硬件抽象層 (HAL),來保證驅動程序代碼不被泄露。大多數手機廠商都是從高通等芯片廠商那里獲得AOSP版本,該AOSP版本為硬件量身定坐了高通驅動程序,所以刷入真機是可以正常的運行。
2. 如何添加硬件驅動
在上面步驟中我們編譯好了AOSP可以直接通過模擬器運行.編譯aosp時也會生成system.img文件,這個文件是最終刷機用的,但是system.img文件必須依賴驅動文件生成,
如果沒有放入對應的驅動就編譯,那么生成的鏡像也是無法正常刷機的。通過上文我們知道aosp 僅是一套源碼,真機運行需要廠商的驅動,廠商的驅動是不包含在AOSP中的,
第三方ROM(如CM等)的廠家驅動是自行提取的。但是google也開源了nexus和pixel對應的AOSP版本的硬件驅動代碼.如果我們有nexus或者是pixel設備就可以下載相應的驅動進行編譯,
然后將編譯好的系統輸入到設備中去.
(1.)下載對應的驅動
(2.)生成驅動
將驅動文件下載后,解壓到AOSP根目錄,得到幾個.sh文件,執行后,會在AOSP下創建vendor目錄,里面包含了驅動。
(3.)編譯帶有驅動的AOSP
再次make -j4
,此次編譯的結果就包含了驅動,編譯出新的系統.
十一.ROM編譯及燒錄
一般定制ROM其實就是對手機內存里的system/app文件夾的內容進行自定義,系統所有的程序都在這個文件夾里,比如瀏覽器、撥號器、聯系人等。自己安裝的軟件\data\文件夾中。
1.真機驅動下載
在上文中可以了解到廠商的驅動是不包含在AOSP中的.因此編譯出來的AOSP系統源碼要在真機上運行,還需要加上廠商驅動進行編譯才能燒錄到真機上使用.
Google提供了Nexus和Pixel這兩個太子機的驅動,我們可以在驅動頁面下載合適的驅動。
Driver Binaries for Nexus and Pixel Devices
2.配置真機驅動到AOSP
- 在上面鏈接里面,兩個文件都進行下載,一個是google vendor,一個qcom。
- 解壓得到
extract-google_devices-blueline.sh
,extract-qcom-blueline.sh
- 將這兩個腳本放到aosp代碼目錄下,進行提取
sh extract-google_devices-blueline.sh
vendor/
vendor/google_devices/
vendor/google_devices/marlin/
vendor/google_devices/marlin/device-vendor-marlin.mk
vendor/google_devices/marlin/android-info.txt
vendor/google_devices/marlin/BoardConfigVendor.mk
vendor/google_devices/marlin/BoardConfigPartial.mk
vendor/google_devices/marlin/proprietary/
vendor/google_devices/marlin/proprietary/vendor.img
vendor/google_devices/marlin/device-partial.mk
Files extracted successfully.
第2個 高通驅動
sh extract-qcom-blueline.sh
vendor/
vendor/qcom/
vendor/qcom/marlin/
vendor/qcom/marlin/BoardConfigPartial.mk
vendor/qcom/marlin/proprietary/
vendor/qcom/marlin/proprietary/lib64/
vendor/qcom/marlin/proprietary/lib64/libbcc.so
vendor/qcom/marlin/proprietary/lib64/libLLVM_android.so
vendor/qcom/marlin/proprietary/lib64/libiperf.so
vendor/qcom/marlin/proprietary/lib64/libminui.so
vendor/qcom/marlin/proprietary/ATT_profiles.xml
vendor/qcom/marlin/proprietary/pktlogconf
vendor/qcom/marlin/proprietary/VZW_profiles.xml
vendor/qcom/marlin/proprietary/ROW_profiles.xml
vendor/qcom/marlin/proprietary/libclcore_neon.bc
vendor/qcom/marlin/proprietary/sanitizer-status
vendor/qcom/marlin/proprietary/libiperf.so
vendor/qcom/marlin/proprietary/qcrilhook.jar
vendor/qcom/marlin/proprietary/libminui.so
vendor/qcom/marlin/proprietary/libion.so
vendor/qcom/marlin/proprietary/iperf3
vendor/qcom/marlin/device-partial.mk
vendor/google_devices/
vendor/google_devices/marlin/
vendor/google_devices/marlin/device-vendor-marlin.mk
vendor/google_devices/marlin/android-info.txt
vendor/google_devices/marlin/BoardConfigVendor.mk
Files extracted successfully.
執行后,會在AOSP下創建vendor目錄,里面包含了驅動。編譯完成后,執行make fastboot adb
單獨編譯fastboot和adb。
3.編譯Rom
重新對AOSP進行編譯.此次編譯的結果就包含了驅動,編譯完成后,執行make fastboot adb 單獨編譯fastboot和adb。
4. 燒錄Rom到手機
- 手機啟用開發者模式,打開 USB 調試 adb shell 能進入。
- 開機鍵 + 音量- 進入 bootloader 模式。
- 電腦上能識別出來手機并裝上了驅動。
- fastboot devices 能看到設備。
- 再次執行./fastboot -w flashall將開始刷機,刷完會自動重啟,over!
參考資料:
Android 鏡像使用幫助
MIUI ROM適配之旅第一天——認識Android手機
Android FrameWork 學習之Android 系統源碼調試
從CM刷機過程和原理分析Android系統結構
Android ROM移植
android rom移植知識普及
Android系統源碼修改
android系統的分區結構
Android ROM的制作與燒錄
android系統源碼中添加app源碼(源碼部署移植)
參考資料:
Ubentu編譯Android源碼(AOSP)
AOSP源碼下載/編譯/刷機/調試
Android rom移植一
目前通用的Android拼包移植方法均是正向移植
Android驅動開發全過程