您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關Android源代碼編譯原理與有什么前期準備,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
大家都知道,Android是開源的,可以在Android Open Source Project(點擊打開鏈接)下載。下載的流程與方法,可以訪問上述網頁查看詳細說明。
首先,我們應該對Android的編譯原理有所了解。普通的Android應用開發,多數是在eclipse中開發的。在eclipse中,Android Project是通過安裝在eclipse中ADT插件進行編譯的。這種編譯方式與在Liunx系統下的編譯方式是不同的。
在Liunx系統下,Android源代碼的編譯方式是通過make file(Android.mk)來實現的。也就是說,在編譯過程中,編譯命令會查找每個文件夾中是否存在Android.mk文件,如果存在,那么系統就會按照Android.mk文件中的編譯規則進行編譯。
「jdk版本不符合」
我們都知道,Android編譯的命令是make -j*(*代表CPU的核發數)。執行make -j*后,執行的文件就是build/core/main.mk。在開始編譯之前,會檢測系統是否符合編譯需要的要求。例如檢測系統是否安裝jdk以及jdk的版本等。
不同的Android版本對jdk的版本要求也不盡相同。本文將以android-4.1.2_r1為例進行講解。
Android 4.1規定的jdk版本是1.6,也就是說,如果Linux系統安裝的jdk版本不是1.6的話,編譯將無法繼續進行。
在終端在會出現以下提示信息:
You are attempting to build with the incorrect version
Your version is: 1.7.0_21.
The correct version is: Java SE 1.6.
解決這個問題的方法就是修改Android源代碼中的文件,將其規定的版本號改為本機中已安裝的jdk的版本號即可。
修改文件:
android-4.1.2_r1/build/core/main.mk
# Check for the correct version of java java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]') ifneq ($(shell java -version 2>&1 | grep -i openjdk),) java_version := endif ifeq ($(strip $(java_version)),) $(info ************************************************************) $(info You are attempting to build with the incorrect version) $(info of java.) $(info $(space)) $(info Your version is: $(shell java -version 2>&1 | head -n 1).) $(info The correct version is: Java SE 1.6.) $(info $(space)) $(info Please follow the machine setup instructions at) $(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html) $(info ************************************************************) $(error stop) endif
如果本機中安裝的jdk版本為1.7,那么只需將
java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.6[\. "$$]')
修改為
java_version := $(shell java -version 2>&1 | head -n 1 | grep '^java .*[ "]1\.7[\. "$$]')
即可。
同樣,javac的版本號也需要修改。
# Check for the correct version of javac javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]') ifeq ($(strip $(javac_version)),) $(info ************************************************************) $(info You are attempting to build with the incorrect version) $(info of javac.) $(info $(space)) $(info Your version is: $(shell javac -version 2>&1 | head -n 1).) $(info The correct version is: 1.6.) $(info $(space)) $(info Please follow the machine setup instructions at) $(info $(space)$(space)$(space)$(space)https://source.android.com/source/download.html) $(info ************************************************************) $(error stop) endif
將
javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]')
修改為
javac_version := $(shell javac -version 2>&1 | head -n 1 | grep '[ "]1\.7[\. "$$]')
「編譯中常見問題」
解決了jdk版本的問題后,隨著編譯的進行可能會出現其他錯誤(主要為command not found),導致編譯中止。
如果在沒有修改過的源代碼中編譯,出現錯誤的話,絕大部分是由于系統中缺少必要的軟件造成的。
經過本人親身實踐,編譯中會用到下列軟件:
bison
zlib1g-dev
flex
libncurses-dev
gperf
xsltproc
build-essential
g++
g++-multilib
ia32-libs
libxml2-utils
解決辦法就是在編譯之前,提前安裝上述軟件,安裝命令如下:
sudo apt-get install bison sudo apt-get install zlib1g-dev sudo apt-get install flex sudo apt-get install libncurses-dev sudo apt-get install gperf sudo apt-get install xsltproc sudo apt-get install build-essential sudo apt-get install g++ sudo apt-get install g++-multilib sudo apt-get install ia32-libs sudo apt-get install libxml2-utils
安裝完上述軟件后,再重新進行編譯,就可以正常編譯了。普通的4核電腦整個編譯過程大約會需要4個小時。
「out文件夾」
編譯成功后,會在android-4.1.2_r1目錄下生成一個out文件夾。out里面的文件就是編譯后的產物。
下面對out文件夾的構成做簡單的講解。
out下有兩個文件夾
host
target
其中,target文件夾中有我們需要的東西。
target下又有兩個文件夾
common
product
common 文件夾中用的最多的就是取得編譯生成的java libraries。因為在sdk中所有標記為@hide的方法或變量都是無法訪問的,所以當你需要訪問他們的時候,就必須使用下面文件夾內的library。
out/target/common/obj/JAVA_LIBRARIES
product文件夾,顧名思義,就是編譯后最終生成的文件的存放位置。
標準Android源代碼中,生成的文件夾叫generic。廠商定制之后,這個文件夾的名字會發生變化,會變成手機的型號。
在generic文件夾內,有兩個地方是比較重要的。
一個是system.img
這是編譯生成的system文件夾的鏡像文件,制作ROM必不可少的文件。
另一個就是system文件夾
這里面有我們需要的apk文件,存放在system/app文件夾下。
「odex與dex」
需要說明的是,默認情況下sytem/app文件夾下的apk包括兩個文件:
Launcher2.apk
Launcher2.odex
這是因為編譯過程中沒有將classes.jar與資源文件打在同一個文件中(classes.dex),而是單獨生成了odex文件。
關閉odex化的方法是
修改android-4.1.2_r1/build/core/package.mk
ifneq (true,$(WITH_DEXPREOPT)) LOCAL_DEX_PREOPT := else ifeq (,$(TARGET_BUILD_APPS)) ifneq (,$(LOCAL_SRC_FILES)) ifndef LOCAL_DEX_PREOPT #feizl mod start #LOCAL_DEX_PREOPT := true LOCAL_DEX_PREOPT := false #feizl mod end endif endif endif endif ifeq (false,$(LOCAL_DEX_PREOPT)) LOCAL_DEX_PREOPT := endif
將
LOCAL_DEX_PREOPT := true
修改為
LOCAL_DEX_PREOPT := false
同樣,如果想讓framework也不生成odex文件的話,就可以修改以下文件
android-4.1.2_r1/build/core/java_library.mk
ifneq (true,$(WITH_DEXPREOPT)) LOCAL_DEX_PREOPT := else ifeq (,$(TARGET_BUILD_APPS)) ifndef LOCAL_DEX_PREOPT #feizl mod start #LOCAL_DEX_PREOPT := true LOCAL_DEX_PREOPT := false #feizl mod end endif endif endif ifeq (false,$(LOCAL_DEX_PREOPT)) LOCAL_DEX_PREOPT := endif
將
LOCAL_DEX_PREOPT := true
修改為
LOCAL_DEX_PREOPT := false
修改之后,重新執行編譯命令,但要注意提前刪除system/app和system/framework下的文件。
在編譯完成后,上述文件夾內的文件就是classes與資源文件合二為一了。
上述就是小編為大家分享的Android源代碼編譯原理與有什么前期準備了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。