1. 程式人生 > >系統原始碼編譯

系統原始碼編譯

1.原始碼級開發(系統開發)

原始碼級開發就是基於AOSP(Android Open Source Project)環境的開發工作,主要開發場景為Android系統定製,比如手機裝置的MIUI,Flyme,Smartisan OS,基於電視的LetvUI,甚至還有針對投影儀,路由器等傳統物聯裝置的Android系統定製開發。

1.1 Android系統分層

HAL層:(Hardware Abstract Layer)硬體抽象層。Android系統裡封裝核心驅動程式的介面層。對上層提供介面,遮蔽底層驅動實現細節.
本來Linux核心可以負責驅動介面定義和驅動實現,但是受限於GNU License(開源感染性),如果廠商選擇驅動介面和實現都在核心空間完成,就必須開放自己的驅動原始碼。這是不符合廠商利益的(驅動包含核心硬體引數,與其他廠家競爭的法寶)。所以Google將Linux核心中跟底層硬體操作相關的邏輯封裝成HAL層介面,廠商基於介面去實現,不直接在核心空間實現驅動。因為Android系統遵循Apache License,不強制開源。

1.2三方應用開發與原始碼級開發的區別

三方應用開發是基於Android SDK開發。主要技術方向為APP及混合APP開發,資料庫,網路協議,應用架構等,服務於商業APP需求。
原始碼級開發是基於AOSP環境開發,主要技術方向為系統應用開發,Framework開發,底層瀏覽器核心開發,音視訊編解碼開發,虛擬機器開發,底層驅動開發等。服務於系統定製需求。

1.3 AOSP官網

AOSP官網提供系統開發相關指導,比如原始碼的環境搭建,下載,編譯,維護,更新版本,開放驅動的下載等。

2. Ubuntu系統安裝與介紹

AOSP環境要求作業系統為Linux或者Mac OS。如果想在Window下進行AOSP開發,通過通過虛擬機器軟體安裝一個Linux系統,比如Ubuntu或CentOS。一般不會虛擬Mac OS。
如果安裝虛擬機器進行AOSP開發,建議電腦的記憶體要在16G以上。
硬體要求:

2.1 安裝虛擬機器

VirtualBox為出自Oracle公司的開源免費虛擬機器軟體。
下載地址:https://www.virtualbox.org/
VMWare為VMware公司提供的商業虛擬機器軟體,可以選用免費版VMware Workstation Player.
下載地址:http://www.vmware.com/products/player/playerpro-evaluation.html

2.2 Ubuntu系統的安裝與介紹

Ubuntu系統是開發使用比較廣泛的一個Linux發行版。
下載地址:http://releases.ubuntu.com
截止2016年底,目前AOSP開發比較穩定的版本是14.04 LTS。帶LTS( Long Term Support),代表是官方長期維護的版本。

不同版本的AOSP,所推薦的Ubuntu系統版本也不同。具體要求如下:

3. 常見Linux命令

Linux命令是對Linux系統進行管理的命令。對於Linux系統來說,無論是中央處理器、記憶體、磁碟驅動器、鍵盤、滑鼠,還是使用者等都是檔案。命令就是去操作檔案,以達到管理系統的目的。
Linux包含系統內建shell命令(比如cd)及安裝的其他Linux命令(比如git)。
相比Window系統的強項-圖形化,Linux的命令則是它的強項。熟練掌握常見Linux命令,是做Linux環境下開發的基本技能。

PS:Linux命令大部分在Mac OS 下也是通用的,它們都屬於類Unix系統。

3.1目錄操作

pwd :獲取當前目錄路徑
ls :檢視檔案列表 eg: ls dirname
-a:檢視所有檔案,包括隱藏檔案
-l:檢視檔案詳細資訊
(.):代表當前目錄
(..):代表上一級目錄
cd :進入某一個目錄 eg: cd dirname
cd .. 進入上一級目錄
cd - 進入上次所在目錄

mkdir :建立目錄
-p :建立多級目錄
cp :拷貝檔案或者目錄 eg: cp src1 src2... dest
-r:拷貝目錄 eg: cp -r src dest
mv :移動檔案或者目錄 eg:mv src dest
(如果srcfile和destfile在同一目錄下,就是重新命名的效果)
rm :刪除檔案 eg: rm filename1 filename2 ...
-r:刪除目錄 eg: rm -r dirname

3.2檔案查詢

find :查詢某一個檔案
find [path] -name <filename>
grep :從某一個檔案/目錄下所有檔案 中匹配字串
grep [-r -n ]<string> path
-r:遍歷目錄查詢
-n:顯示行號

3.3系統操作

su :切換到某一個使用者(需要輸入要切換的使用者的密碼) eg: su username
sudo :非root使用者強制執行一些需要root許可權的操作(需要輸入當前使用者的密碼) eg: sudo rm filename

apt-get : Ubuntu的軟體管家,進行軟體的更新,解除安裝與維護。
sudo apt-get update :更新到最新軟體列表
sudo apt-get install vim :安裝VIM
sudo apt-get remove vim :解除安裝VIM
vim :終端下的文字編輯器。
i:進入編輯模式
ESC:跳到命令模式
dd:刪除一行
(:wq):儲存退出
(:q!):不儲存退出
cat :檢視檔案,將文字內容列印到控制檯。
chmod :修改檔案許可權。eg:chmod a+x xxx.sh chmod 777 xxx.sh
許可權設定可以使用字串[ugoa][+-=][rwx]或者數字 (r=4,w=2,x=1,-=0)
u 擁有者,g 使用者組,o 其他使用者,a 所有人。

  • 表示增加許可權、- 表示取消許可權、= 表示直接指定許可權

4. AOSP原始碼工作環境

原始碼工作環境,就是安裝所依賴的一些軟體庫,以及開發除錯時需要進行的一些配置。
主要分為編譯環境準備,AOSP原始碼下載,原始碼預編譯等。這裡主要介紹在Ubuntu14.04 LTS下開發Android6.0程式碼的工作環境準備。
4.1編譯環境搭建(Ubuntu14.04)
JDK和依賴包下載

$ sudo apt-get update #獲取源的更新
$ sudo apt-get install openjdk-7-jdk #下載openjdk7

sunjdk 採用Java研究許可(Java Research License,簡稱JRL)許可證書,部分開源,僅限研究。openjdk採用GNU許可證書,完全開源。sunjdk中私有APIs用類似功能的開原始碼替換/重新實現。Google為了解決與Oracal公司的版權糾紛,在Android 5.0以後JavaAPIS替換為openjdk。不同版本的AOSP程式碼,所要求的JDK版本也不一樣,詳附:

安裝其他依賴

$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip

不同版本的Ubuntu系統所需要安裝的依賴也是不一樣的,在一些低版本即使按照官方文件做,編譯的時候也會出現很多錯誤,所以建議使用Google推薦的Ubuntu系統版本。
USB裝置許可權配置

在 GNU/Linux系統下(比如Ubuntu),普通使用者預設是沒有許可權去訪問USB裝置的,如果希望某個使用者訪問,可以以root身份在/etc/udev/rules.d/ 目錄下建立一個rules規則檔案,AOSP提供的rules裡配置了常見Android裝置。

下載並配置AOSP的usb裝置許可權規則模板

$ wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules
上述模板只配置了一些Nexus裝置,如果是自己的Android裝置,執行adb devices的時候可能會提示permission denied,原因就是因為自己的Android裝置沒有加入到這個配置檔案當中。可以利用lsusb命令列出當前系統識別到的USB裝置:
$lsusb #獲取當前的usb裝置,輸出類似以下的資訊
Bus 001 Device 007: ID 0403:cb48 Future Technology Devices International, Ltd
Bus 001 Device 006: ID 0461:4d15 Primax Electronics, Ltd Dell Optical Mouse
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
找出自己的手機裝置,以第一行為例,idVendor是0403,idProduct是cb48。
可以在51-android.rules裡新增一行:
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="cb48", MODE="0600", OWNER="<username>"
記得要把<username>替換為自己的登入使用者名稱。然後再執行:
$sudo udevadm control --reload-rules#重新載入USB訪問規則
然後重新插拔USB裝置即可。
OUT目錄配置(可選)

ASOP程式碼編譯以後預設會在你當前工作目錄建立/out目錄,編譯產出的所有檔案都會放在這個目錄。編譯完以後這個目錄大小比AOSP原始碼還要大,如果希望自定義out目錄的位置:

export:配置環境變數

OUT_DIR_COMMON_BASE:環境變數名,配置儲存編譯AOSP原始碼所生成檔案的out目錄位置。預設在AOSP原始碼的目錄下。僅支援4.1及以後

$ export OUT_DIR_COMMON_BASE=<path-to-your-out-directory>
設定ccache快取(可選)

開啟ccache,在AOSP編譯的過程中,會對C/C++程式碼的編譯結果進行快取。當執行了make clean命令以後,再次執行make編譯的時候,可以大大提高編譯速度。
$ export USE_CCACHE=1 #開啟CCACHE。此配置可以提高二次全編譯的速度。可以新增到.bashrc檔案中,
$ export CCACHE_DIR=/<path_of_your_choice>/.ccache #設定快取目錄的路徑。也可以新增到.bashrc檔案中,
$ prebuilts/misc/linux-x86/ccache/ccache -M 50G #設定快取目錄的大小。這個配置一次即可。

.bashrc是home目錄下的一個指令碼檔案,每開啟一個終端視窗,這個啟動腳本里的命令就會執行,相當於開機啟動。

4.2原始碼下載與管理

AOSP原始碼下載
由於國內的網路限制,以下執行的命令,有些會將訪問的Google地址替換為國內的映象網站,比如清華映象源。映象源:定期同步Google的AOSP程式碼伺服器,供國內網路訪問。

1. 下載repo

建立~/bin目錄並加到環境變數

$ mkdir ~/bin
$ PATH=~/bin:$PATH

下載repo指令碼到本地並配置可執行許可權

$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo

清華大學提供的repo

curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo

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

$ chmod a+x ~/bin/repo #所有使用者可執行

2. 初始化本地repo

建立工作目錄,用於儲存下載的AOSP原始碼

$ mkdir WORKING_DIRECTORY
$ cd WORKING_DIRECTORY

配置git賬戶資訊,用於提交程式碼到Gerrit(code-review程式碼審查)上

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

初始化repo,指定要下載的android原始碼分支名。不指定,預設下載master分支程式碼(最新版本程式碼)。執行完以後WORKING_DIRECTORY下會生成.repo目錄。

$ repo init -u https://android.googlesource.com/platform/manifest -b android-6.0.1_r78

清華大學提供的AOSP映象網站

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

3.下載,同步。會將repo所維護的伺服器上對應分支的所有project的.git倉庫更新下載到本地並checkout程式碼到WORKING_DIRECTORY目錄

$ repo sync

repo與git的關係
AOSP:本質上是一堆使用git進行版本控制的project。
repo:針對AOSP大量git倉庫的管理工具。可以執行批量git同步,更新,提交等操作。
原理:通過讀取manifest.git裡維護的manifests.xml檔案當中配置的projects的git倉庫地址,分支等資訊執行git操作。將伺服器上按照特定目錄結構儲存的project原封不動的同步到本地。
關係:repo基於git,讓超大型的專案程式碼管理更有效率。

manifest.xml檔案解釋:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote fetch="https://android.googlesource.com" name="aosp" review="android-review.googlesource.com" revision="refs/tags/android-6.0.1_r74" />

<remote name="repo_remote"
fetch="." />




<default revision="master"
remote="repo_remote"
sync-j="4" />

<project path="build/project1" name="project1" remote="repo_remote" revision="master"/>

<project path="project1" name="project1" remote="repo_remote" revision="master"/>
</manifest>

4.3原始碼預編譯
驅動下載(可選)
如果要使用Nexus裝置進行學習,則需要下載Nexus的驅動,再進行編譯。驅動下載地址:https://developers.google.com/android/nexus/drivers 找到對應裝置的驅動,下載到工作目錄解壓後為.sh結尾的指令碼,執行後會將驅動安裝在vendor/目錄下
如果之前編譯過AOSP,則需要刪除所有編譯結果,重新編譯。
$make clobber #刪除out目錄下的內容。

編譯AOSP

1.初始化編譯環境 source或者(.)都可以執行一個shell指令碼

$ source build/envsetup.sh
$ . build/envsetup.sh

2.選擇編譯目標

$ lunch aosp_arm-eng #模擬器

3.開始編譯 -jN:job,開多少個任務去執行編譯。

$make -j4
lunch BUILD-BUILDTYPE解釋:
BUILD為內部開發程式碼,比如Nexus 6P為aosp_angler
BUILDTYPE為編譯型別。不同的編譯型別,在編譯過程中會有不同的編譯配置。
user:類似MIUI釋出的的穩定版ROM。會關閉一些除錯性的配置。比如adb。
userdebug:類似MIUI釋出的開發版ROM。跟user版本差不多,但是具備root,方便進行測試。
eng:內部開發版。包含開發過程中使用到的測試工具,帶root。
執行編譯結果
如果是模擬器,可直接執行emulator 命令。
$ emulator

如果是硬體裝置,需要進入bootloader模式將映象檔案通過fastboot燒寫到裝置上。
$adb reboot bootloader #進入bootloader模式
$fastboot flash system system.img #燒寫system分割槽
$fastboot reboot #重啟裝置

知識擴充套件:
 刷機
刷機,手機方面的專業術語,是指通過一定的方法更改或替換手機中原本存在的一些語言、圖片、鈴聲、軟體或者作業系統。通俗來講,刷機就是給手機重灌系統。刷機可以使手機的功能更加完善,並且可以使手機還原到原始狀態。一般情況下Android手機出現系統被損壞,造成功能失效或無法開機,也通常通過刷機來解決。一般Andriod手機刷機分為線刷,卡刷,軟刷和廠刷。
卡刷:進入recovery模式刷機。將ROM包(一般為zip,bin格式)放到SD卡目錄下,手機重啟到recovery模式下進行刷機的方式。所謂的OTA(Over-the-Air Technology)升級,指的就是這個。
線刷:進入bootloader模式刷機。通過USB線連線Android裝置,在電腦上通過adb、fastboot等工具(或特定手機的線刷工具,比如MiFlash)直接將映象檔案(一般為img格式)/打包後的映象包(一般為bin格式)燒寫到對應分割槽的方式。
 Android系統常用分割槽:
分割槽名 介紹
bootloader 相當於PC的BIOS,負責硬體自檢和初始化,以及啟動模式選擇。在bootloader模式下可以進行分割槽的燒寫。
recovery 包含Linux核心和recovery程式,簡易的linux系統。在recovery模式下可以進行分割槽的擦寫,OTA升級操作。
boot 包含Linux核心和一個迷你的根檔案系統。負責system、cache、userdata等分割槽的掛載。
system 常規的Android系統所在分割槽。掛載在/system目錄下,包含系統APK,framework層的jar/so/bin等所有AOSP編譯輸出產物。
userdata 使用者資料分割槽。掛載在/data目錄下。使用者安裝的APK,以及app的資料都在這個分割槽。
cache 快取分割槽,一般用於OTA升級進入recovery前,臨時放置OAT升級包,以及儲存OTA升級的一些臨時輸出檔案。
sdcard 外接儲存。內建sdcard一般掛載在/sdcard,

out目錄

 out目錄:編譯過程中生成的檔案以及最終生成的檔案所在目錄。 
/out/host/:該目錄下包含了針對當前作業系統所編譯出的 Android 開發工具產物。例如:adb,aapt,fastboot等命令。

/out/target/common/:該目錄下包含了針對Android裝置的通用的編譯產物,主要是 Java 應用程式碼和 Java 庫。(framework.jar,services.jar,android.policy.jar等等)
/out/target/product/<product_name>/:包含了針對特定裝置的編譯結果以及平臺相關的 C/C++ 庫和二進位制檔案。其中,<product_name>是具體目標裝置的名稱。
Build 的產物中最重要的是三個映象檔案,它們都位於 /out/target/product/目錄下。
ramdisk.img:在啟動時將被 Linux 核心掛載為只讀分割槽,它包含了 /init 檔案和一些配置檔案。它用來掛載其他系統映象並啟動 init 程序。
system.img:包含了 Android OS 的系統檔案,庫,可執行檔案以及預置的應用程式,將被掛載為system分割槽。
userdata.img:將被掛載為 /data,包含了應用程式相關的資料以及和使用者相關的資料。
4.4 AOSP常見的命令,目錄介紹
常見AOSP命令
在envsetup.sh裡定義的一些shell函式。
命令 解釋
gettop 獲取WORKING_DIRECTORY目錄的完整路徑
croot 回到WORKING_DIRECTORY目錄
mm 編譯當前目錄下的模組。比如在packages/apps/Calculator目錄下執行mm,就是編譯Calculator.apk。
cgrep 執行grep命令,但只匹配C/C++的原始檔。
jgrep 執行grep命令,但只匹配java原始檔。
resgrep 執行grep,但只匹配路徑名為res/下的xml資原始檔。
godir 去某一個目錄。第一次執行會將AOSP的所有目錄路徑存到filelist檔案中。類似everythings的作用。

常見AOSP目錄
介紹一些做AOSP開發時,一般會接觸到的目錄。
目錄名 介紹
build/ ├─ core/ AOSP整個編譯過程中核心的編譯規則makefile
├─ envsetup.sh 編譯環境初始化指令碼
├─ target/ AOSP自帶的Target(模擬器)的一些makefile
└─ tools / 編譯中使用的shell及python寫的工具指令碼
packages/ 電話,桌面,設定,相簿,照相機,鬧鈴,日曆等經常操作的系統app,以及一些provider,輸入法等桌面上看不到的app。
frameworks/av/ 多媒體相關的native層的原始碼目錄
framework/webview 瀏覽器核心chromium的原始碼目錄
framework/native power,surface,input,binder等服務的native層實現的原始碼目錄
frameworks/base/ ├─core framework.jar ,framework-res.apk,libandroid_runtime.so等的原始檔
├─native libandroid.so的原始碼目錄。java api的native實現。比如assertmanager,looper等。
├─media 多媒體相關的JavaAPI及JNI層的原始檔
├─packages SettingsProvider,SystemUI等不在桌面直接啟動的APP的原始碼目錄
├─services services.jar,libandroid_servers.so的原始檔
└─wifi wifi服務相關的Java API,WifiManager,WifiService等
device/<vendor_name>/<product_name> 跟某些廠商的某個硬體平臺相關的核心,硬體配置等
vendor/<vendor_name>/<product_name> 廠商對AOSP進行的修改或者定製,放在vendor目錄。包括但不限於framework層新增API,新增APP等業務需求。但是現在Google更推薦放在devices目錄下。

  1. Android Build System入門
    Android Build 系統用來編譯 Android 系統,Android SDK 以及相關文件。該系統主要由 Make 檔案,Shell 指令碼以及 Python 指令碼組成,在編譯時能夠支援面向不同的硬體裝置,不同的編譯型別,且提供面向各個廠商的定製擴充套件。
    5.1 什麼是makefile
    makefile是一些有特定語法的,可供make命令讀取並執行的指令碼性質的配置檔案。作用就是可以告知編譯系統,對哪些原始檔進行編譯,怎麼編譯,怎麼處理依賴關係。makefile可以定義變數,函式,呼叫系統命令,shell/python指令碼,管理module之間的依賴。整個 Android Build 系統中的 Make 檔案可以分為三類:
  2. Build系統核心Makefile
    這類makefile定義了整個 Build 系統的框架,而其他所有 Make 檔案都是在這個框架的基礎上編寫出來的。位於/build/core目錄下.
  3. 針對某個產品的Makefile
    這類makefile是針對某個產品Make 檔案,這些檔案通常位於 device/<vendor>/<product> 目錄下。
  4. 針對某個模組的Makefile-Android.mk
    第三類是針對某個模組的 Make 檔案。AOSP中,不會針對某一個檔案進行編譯,每一個編譯單位都是一個模組,每個模組由一個名為“Android.mk”的makefile來宣告。該檔案中定義瞭如何編譯當前模組。
    5.2 ABS的工作流程

參考文件:https://sites.google.com/a/itspaclub.com/www/android/android-build-system-anatomy
6.AOSP下進行系統開發
從系統APP開發,Framework層定製,native層定製三個環節,學會如何修改AOSP程式碼達到開發需求。
6.1 Android的啟動流程簡述
AOSP開發的覆蓋面是非常廣的,從上層的系統APP到底層的HAL層驅動,每一個環節都是息息相關的。我們不可能一下子就能打通任督二脈,但是瞭解Android的啟動流程,會幫助我們加深對Andorid系統的理解。

6.2修改系統APP程式碼
系統開發,很大一部分人員會從事系統APP定製的工作。
如何去編譯APK
在原始碼環境下,使用mm命令編譯module,APK會輸出到out/target/product/product_name目錄下。
mm –B :強制重新編譯。相當於clean後再編譯。
Dalvik與ART的區別
Dalvik:
JIT(Just-in-time)實時編譯,執行的時候將位元組碼翻譯成機器碼,所執行的目標檔案(dex)與硬體平臺無關,APP執行效率較低。
ART:
AOT (Ahead-Of-Time - 預先編譯),執行前將位元組碼翻譯成機器碼,所執行的目標檔案(oat)與硬體平臺相關。APP執行效率高,但會佔用空間。APK安裝所需時間增加。
odex是幹什麼的
dalvik時代:APK執行的時候,會把APK中的classes.dex解壓出來並通過dexopt優化為成.odex檔案,快取在/data/dalvick-cache目錄下,提高後續執行的效率。
ART時代:APK安裝的時候,會把APK中的classes.dex解壓後,通過dex2oat工具轉化為.odex檔案(ELF格式),儲存在apk所在目錄的oat目錄下。

為什麼在原始碼環境下編譯就產出了odex檔案
ROM:apk,jar,bin,so等組成。
優點:

  1. 降低系統更新後啟動的時間。
    未odex的Rom,首次開機的過程中會執行odex操作。編譯時做,開機時候就不用做了。
  2. 減少在裝置上進行odex操作所造成的空間浪費。
    編譯時dexopt/dex2oat,會直接將APK的資源與程式碼拆開。如果在裝置上安裝時dexopt/dex2oat,apk的大小不會減少,但又會多一個odex檔案佔據磁碟空間。
    缺點:
  3. 增加開發時編譯的時間
  4. 不能直接執行APK的install操作,需要將APK和odex都sync到裝置上。
    如何在開發階段關閉dex2oat
     在當前module的Android.mk裡關閉
    LOCAL_DEX_PREOPT = false
     在build/core/main.mk中關閉所有module的dex優化

eng

ifeq ($(TARGET_BUILD_VARIANT),eng)
tags_to_install := debug eng

關閉odex優化

WITH_DEXPREOPT := false
Odex優化只在Linux環境下生效。
6.3定製framework
framework的定製,一般是為了滿足APP層或者整個系統的某一種需求。
需求1:在系統所有的服務啟動之前,列印一句日誌,模擬對系統行為的修改。
SystemServer.java ---> services.jar stop;start重啟Android系統生效
需求2:在App層呼叫Log.wtf列印日誌,當TAG=“ITCAST”的時候,在Framework層修改Log的輸出結果。
android.util.Log.java ---> framework.jar stop;start重啟Android系統生效
6.4進一步修改native層的程式碼
native層的定製,一般是為了滿足framework層程式碼的呼叫需求。Native層分為兩部分,JNI-native。JNI層是native層C/C++與framework層Java互動的橋樑。
需求:在列印日誌TAG=“ITCAST”的時候,在JNI層和native層分別修改Log的輸出結果。
android_util_Log.cpp ---> libandroid_runtime.so stop;start重啟Android系統生效
logd_write.c ---> liblog.so 重啟裝置生效
7.原始碼級開發的職業發展
工作崗位:
系統APP開發工程師(系統應用)
Framework開發工程師(安全,影象,電話,系統服務,瀏覽器核心,多媒體等)
Android系統架構師(Android系統定製,ABS定製,升級,維護)
技術儲備:
C/C++,Shell,Python,Smali等