这期内容当中小编将会给大家带来有关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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。