我们习惯于在Google提供的eclipse和Android studio里面构建自己的项目,但是我们如何能够直接在源码中构建编译自己的程序呢?相对于实用工具来说,其实是要复杂很多的,因为工具帮我们做了很多工作,如果我们想要更加了解Android项目源码的构建方式,就必须尝试去摆脱对工具的依赖。
一、路径
我们打包好的项目源码资源文件需要放在源码中指定目录下才能够完成编译,因为就Makefile本来就是一个树状结构,他会根据目录逐层的去编译各个模块,然后将这些模块组装打包起来,就形成了一个完整的项目产品。
我们自己打包好的APK源文件一般可以放到以下几个目录:
- 可以放在vendor 目录下自己项目的package/app/下面
- 可以放在vendor/google/partner_gms/apps 或者 vendor/mtk/qcom 等
- 也可以直接放在 packages/apps/ 下面
二、编写Android.mk文件
我们想让我们的APK被编译,那么一定要有一个Makefile文件来引导编译,Android.mk有他自己的一些规则,我们在编写Makefile的时候,也可以参考编译器生成build.gradle文件,里面有项目所依赖或者引用的库文件。下面贴出一个例子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
src_dirs := app/src/main/java/
res_dirs := app/src/main/res/
#这个主要用于是 eng、user还是 userdebug 版本参与编译; optional值所有版本都参与编译
LOCAL_MODULE_TAGS = optional
#生成的APK的名字
LOCAL_PACKAGE_NAME := BuildTest
#apk 签名 platform为默认使用平台签名
LOCAL_CERTIFICATE := platform
#使用的SDK版本 current未默认为源码的版本
LOCAL_SDK_VERSION := current
# 指定Manifest文件
LOCAL_MANIFEST_FILE := app/src/main/AndroidManifest.xml
#编译的资源文件文件路径
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/$(res_dirs)
#编译的java文件文件路径
LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
#引用的静态库
LOCAL_STATIC_JAVA_LIBRARIES := \
androidx-constraintlayout_constraintlayout
include $(BUILD_PACKAGE)
三、编译
编译APK和编译源码一样,也需要执行脚本加载环境变量,然后lunch要编译的版本,最后就是选择用mmm或者mm编译,mmm和mm的区别是,前者可以在别的目录下来编译这个APK,mm必须在APK Makefile文件所在的目录下执行。
$ source build/envsetup.sh
$ lunch xx
$ $(Your APK pos)mm