💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
**1. 部署JDK** Froyo的编译依赖JDK1.5,所以首先要做的就是下载JDK1.5。下载网址是http://www.oracle.com/technetwork/java/javase/downloads/index-jdk5-jsp-142662.html。下载得到的文件为jdk-1_5_0_22-linux-i586.bin。把它放到一个目录中,比如我本人,就将它放在了/develop中,然后在这个目录中执行: `./jdk-1_5_0_22-linux-i586.bin #执行这个文件` 这个命令其实就是解压,解压后的结果在/develop/jdk1.5.0_22目录中。现有了JDK,再按照下面的步骤部署它即可: - 在~/.bashrc文件的末尾添加以下几句话: exportJAVA_HOME=/develop/jdk1.5.0_22 #设置为刚才解压的目录 exportJRE_HOME=JAVA_HOME/jre exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH - 重新登录系统,这样,JDK资源就能被正确找到了。 **2. 编译源码** Android的编译有自己的一套规则,主要利用的就是mk文件。网上有太多关于它的解说了,这里不再赘述,只简单介绍其编译工序: 进入源码目录(以我的开发环境为例),也就是 cd /develop/download_froyo - 执行 . build/envsetup.sh,这个脚本用来设置Android的编译环境。 - 执行choosecombo命令,这个命令用来选择编译目标(如目标硬件平台、eng还是user等)。一般而言,手机厂商会设置自己特有的编译选项。 执行完上面几个步骤后,就可以编译系统了。Android平台提供了三个命令用于编译,它们分别是make、mmm和mm,这三个命令的使用方法及其优劣如下: - make:不带任何参数,它用于编译整个系统,时间较长,我本人不推荐这种做法,除非读者想编译整个系统。 - make MediaProvider :下面几个例子都以编译MediaProvider为例。这种方式对应于单个模块编译。它的优点是,会把该模块依赖的其他模块也一起编译。例如 make libmedia,就会把libmedia依赖的库全编译好。其缺点也很明显,它需要搜索整个源码来定义MediaProvider模块所使用的Android.mk文件,并且还要判断该模块所依赖的其他模块是否有修改。整体编译时间较长。 - mmm packages/providers/MediaProvider :该命令将编译指定目录下的目标模块,而不编译它所依赖的模块。所以如果读者是初次编译,采用这种方式编译一个模块往往会报错。错误的原因是因为它依赖的模块没有被编译。 - mm :这种方式需要先cdpackages/providers/MediaProvider目录,然后mm。该命令会编译当前目录下的模块。它和mmm一样,只编译目标模块。mm和mmm命令编译的速度都很快。 从使用的角度来看,我本人有如下建议: - 如果只知道目标模块名,则应使用make 模块名的方式来编译目标模块。例如编译libmedia,则直接使用make libmedia即可。另外,初次编译时也要采用这种方法。 - 如果不知道目标模块名,而知道目标模块所处的目录,则可使用mmm或mm命令来编译。当然,初次编译还必须使用make命令。而以后的编译就可使用mmm或mm了,这样会节约不少时间。 >[info] **注意** > 一般的编译方式都使用增量编译,即只编译发生变化的目标文件。但有时则需重新编译所有目标文件,那么就可使用make命令的-B选项。例如 make –B 模块名,或者mm –B、mmm –B 。mm和mmm内部,也是调用make命令的,而make的-B选项将强制编译所有目标文件。 Android的编译工序比较简单,难点主要在Android.mk文件的编写。读者可上网搜索与此相关的学习资料。 **3. 本书各模块的编译目标** 本书各模块的编译目标如表1-1所示,这里仅列出几个有代表性的模块: :-: 表1-1 本书各模块编译目标 | 目标模块 | make命令 | mmm命令 | | --- | --- | --- | | init | make init | mmm system/core/init | |zygote | make app_process | mmm frameworks/base/cmds/app_process | | system_server |make services | mmm frameworks/base/services/java | | RefBase等 | make libutils | mmm frameworks/base/libs/utils | | Looper等 | make framework | mmm frameworks/base | | AudioTrack | make libmedia |mmm frameworks/base/media/libmedia | | AudioFlinger | make libaudioflinger | mmm frameworks/base/libs/audioflinger | | AudioPolicyService| make libaudiopolicy | mmm hardware/msm7k/libaudio-qsd8k (示例) | | SurfaceFlinger | make libsurfaceflinger | mmm frameworks/base/libs/surfaceflinger | | Vold | make vold | mmm system/vold/ | | Rild| make rild | mmm hardware/ril/rild/ | | MediaProvider | make MediaProvider | mmm packages/providers/MediaProvider | | Phone| make Phone | mmm packages/apps/Phone/ | 假设make framework,那么编译完的结果则如图1-5所示: :-: ![ make framework的结果](https://box.kancloud.cn/4e480348ac50672ed9a7e16cf8fd2926_865x88.png =865x88) 图1-5 make framework的结果 从上图可看出,make命令编译了framework-res.apk以及framework.jar两个模块。它们编译的结果在out/target/product/generic/system/framework下。读者利用adb 命令把这两个文件push到手机的system/framework目录,即可替换旧的文件。如想测试这个新模块,则需要先杀掉所有使用该模块的进程,进程重启后会重新加载模块,这时就能使用新的文件了。例如,想测试刚修改的libaudioflinger模块,adb push上去后,先杀掉mediaserver进程,因为libaudioflinger库目前只有该进程使用。当mediaserver重启后,就会加载新push上来的libaudioflinger库了。 * * * * * **注意**:系统服务被杀掉后一般都会自动重启(由init控制,在第三章中可见到)。 * * * * *