前言:
我们在工作中使用它Android studio开发apk当我们想把工程代码放在工程代码上时,它非常方便android
在源代码中编译时,我们需要自己编写Andorid.mk 文件。以下内容是正确的Android.mk文件中的代码
解释说明。
Android.mk 编写:
#每个Android.mk文件必须定义LOCAL_PATH开始。它用于开发tree查找源文件
LOCAL_PATH := $(call my-dir)
$(call my-dir) #获取当前文件夹的路径。 $(call all-java-files-under, <src>) #在指定目录下获的一切java文件。 $(call all-c-files-under, <src>) #在指定目录下获取所有c文件。 $(call all-Iaidl-files-under, <src>) #在指定目录下获的一切AIDL文件。 $(call all-makefiles-under, <folder>) #在指定目录下获的一切Make文件。 $(call intermediates-dir-for, <class>, <app_name>, <host or target>, <common?>) #获取Build输入目标文件夹路径。 $(call first-makefiles-under,$(LOCAL_PATH)) #在LOCAL_PATH在所有子目录中搜索.mk不包括当前目录的文件
#CLEAR_VARS 变量由Build System提供。并指向指定GNU Makefile,它负责清理很多 LOCAL_xxx.例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 但不清理LOCAL_PATH,这种清洁动作是必要的,因为所有的编译控制文件都是由同一个GNU Make其变量是全局分析和执行的。因此,清洗后可以避免相互影响。
include $(CLEAR_VARS)
#LOCAL_MODULE_TAGS := user eng tests optional
user: 只指模块user编译版本
eng: 只指模块eng编译版本
tests: 只指模块tests编译版本
optional:指所有版本的模块编译
LOCAL_MODULE_TAGS := optional
#LOCAL_SRC_FILES变量必须包含将要打包如模块的C/C , java源码。
LOCAL_SRC_FILES := $(call all-java-files-under, app/src/main/java)
#编译AndriodManifest.xml
LOCAL_MANIFEST_FILE := app/src/main/AndroidManifest.xml
# 系统资源文件的编译
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/src/main/res
# 编译asset资源文件,必须要单独写出来,不然在工程中无法访问到asset路径下的资源文件
LOCAL_ASSET_DIR := $(LOCAL_PATH)/app/src/main/assets
#指定APP应用名称
LOCAL_PACKAGE_NAME := MyTestApp
#在指定分区中安装此模块
一般有 system system_ext product vendor odm 分区
#模块编译输出分区 #system :主要包含 Android 框架, google 官方实现 #Android.mk 默认是输出 system 分区,无需指定 #Android.bp 默认是输出 system 分区,不用指定 #system_ext: android11 新划分区 #vendor :SoC芯片分区(高通等系统级核心厂商), 为他们提供一些核心功能和服务,由 soc 实现 #Android.mk LOCAL_VENDOR_MODULE := true #Android.bp vendor: true #odm :设备制造商分区(如华为、小米),为其传感器或外围设备提供一些核心功能和服务 #Android.mk LOCAL_ODM_MODULE := true #Android.bp device_specific: true #product :产品型号分区 #Android.mk LOCAL_PRODUCT_MODULE := true #Android.bp product_specific
#安装到product分区 LOCAL_PRODUCT_MODULE := true
#LOCAL_PRIVILEGED_MODULE := true对于Android系统应用LOCAL_PRIVILEGED_MODULE 决定了app编译后,放在里面ROM分区中的 app 或者 priv-app位置
LOCAL_PRIVILEGED_MODULE := true #如果配置为false 在设备中编译的路径是 (system or product or vendor/app) #如果配置为true 在设备中编译的路径是 (system or product or vendor/priv-app)
#使用sdk的hide的api来编译,Android P 之后,Android.mk 必须定义 LOCAL_SDK_VERSION 和 LOCAL_PRIVATE_PLATFORM_APIS 变量中的一个, 这两种是或的关系只需要定义一个
如果需要使用系统来隐藏 API编译 需要定义: LOCAL_PRIVATE_PLATFORM_APIS := true 如果不需要隐藏系统API需要定义编译: LOCAL_SDK_VERSION := current #注意,两个是 if --else 的定义原则,根据实际情况进行选择
LOCAL_MODULE_CLASS 可以选择不定义指定模块的类型
以下类型: 编译 apk 文件 ,最后生成的文件路径一般放在 /system/app目录下 LOCAL_MODULE_CLASS := APPS 编译 jar 包 LOCAL_MODULE_CLASS := JAVA_LIBRAYIES 定义动态库文件 最终生成的文件路径放置在/sysem/lib目录下 LOCAL_MODULE_CLASS := SHARED_LIBRAYIES 可执行文件的编译 最置最终生成的文件路径system/bin下 LOCAL_MODULE_CLASS := EXECUTABLES 配置文件的编译 最终生成的文件路径放置在 /system/etc/目录下 LOCAL_MODULE_CLASS := ETC
#aapt 它是编译和包装资源的工具。aapt2是在aapt上做了优化
LOCAL_USE_AAPT2 := true
#指定依赖共享java编译时依赖类库,最终不会打包apk中
LOCAL_JAVA_LIBRARIES := javax.obex telephony-common services.net
#指定依赖的静态java类库,最终会打包到apk里面。
使用多个引用时,写法如下:
LOCAL_STATIC_JAVA_LIBRARIES := \ com.android.vcard \ bluetooth.cc\ services.net \ libprotobuf-java-lite \
#指定依赖的模块。指定模块运行所依赖的模块(模块安装所依赖的模块将同步安装)
LOCAL_REQUIRED_MODULES := libjni_pinyin_tst
#混淆配置,默认为full obfuscation,全代码混淆,disabled不开启
#不需要使用代码混淆的工具进行代码混淆
LOCAL_PROGUARD_ENABLED := disabled
#默认为: 使用将该工程代码全部混淆
LOCAL_PROGUARD_ENABLE := full
# LOCAL_CERTIFICATE 用于设置不同的签名方式
LOCAL_CERTIFICATE := PRESIGNED,打包apk时,沿用apk中原来的签名
用于设置不同的签名方式build/target/product/security目录中有四组默认签名供Android.mk在编译APK使用:
1、testkey:普通APK,默认情况下使用。
2、platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
3、shared:该APK需要和home/contacts进程共享数据。
4、media:该APK是media/download系统中的一环。
应用程序的Android.mk中有一个LOCAL_CERTIFICATE字段,由它指定用哪个key签名,未指定的默认用testkey.
LOCAL_CERTIFICATE : #使用平台文件签名
(1)platform签名:
AndroidManifest.xml的manifest节点中添加 android:sharedUserId=”android.uid.system”,
Android.mk中增加 LOCAL_CERTIFICATE := platform
(2)shared签名:
AndroidManifest.xml的manifest节点中增加android:sharedUserId=”android.uid.shared”,
Android.mk中增加LOCAL_CERTIFICATE := shared
(3)media签名:
AndroidManifest.xml的manifest节点中增加 android:sharedUserId=”android.media”,
Android.mk中增加 LOCAL_CERTIFICATE := media
Settings.apk就是platform级别的签名,系统级应用都应该使用这个签名
LOCAL_CERTIFICATE := platform
#声明要调用android包,会打包到apk中,调用多个时,写法如下:
LOCAL_STATIC_ANDROID_LIBRARIES := \
androidx.appcompat_appcompat \
com.google.android.material_material \
androidx-constraintlayout_constraintlayout \
lottie-2.8.0 //lottie 第三方aar
#aapt是Android的打包工具,
1、–auto-add-overlay意思是当不同文件夹有相同的资源id时,只将第一个资源合并打包进来, 2、–extra-packages android.support.v7.appcompat,意思是将extra-package包后边的文件包引入到当前代码框架中,就像给当前代码导入一个jar包,但是这里不限jar、library等等,这样引入编译之后就能合并在一起使用
LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages com.airbnb.lottie //lottie 第三方aar的包名
#编译APK
include $(BUILD_PACKAGE)
延伸定义
BUILD_HOST_STATIC_LIBRARY 编译静态库(适用与主机) BUILD_HOST_SHARED_LIBRARY 编译动态库(适用与主机) BUILD_HOST_EXECUTABLE 编译可执行程序(适用与主机) BUILD_HOST_PREBUILT 预编译(适用与主机) BUILD_HOST_JAVA_LIBRARY 编译java包(适用与主机) BUILD_JAVA_LIBRARY 编译java包 BUILD_STATIC_JAVA_LIBRARY 编译java静态包
BUILD_STATIC_LIBRARY 编译静态库 BUILD_SHARED_LIBRARY 编译动态库
官方解释是这样:
1、 LOCAL_STATIC_JAVA_LIBRARIES-静态库是在连接阶段直接拷贝到代码 中使用的,BUILD_STATIC_JAVA_LIBRARY指定生成静态库。编译出来的静态库(这里指jar包)里每个java文件对应的class文件都单独存在,可以直接导入Eclipse等IDE使用,
2、LOCAL_JAVA_LIBRARIES -而共享库是由加载器加载到内存,在运行时使用的。而编译出来的共享库(jar包),内部是Android字节码Dex格式的文件,一般无法导入Eclipse等IDE使用。Android.mk中由BUILD _ JAVA _ LIBRARY指定生成共享库
静态库和动态库本质上没有区别,可能就是说静态库是编译时期就把jar包中的代码整合到项目中了,动态库就是说在程序运行期,把jar包加载到内存中,每次使用再继续重新加载到内存
BUILD_EXECUTABLE 编译可执行程序 BUILD_PACKAGE 编译apk ---- 需要有源码文件的app模块 BUILD_PREBUILT 预编译(针对单个预编译文件) BUILD_MULTI_PREBUILT 预编译(针对多个预编译文件)
#Android.mk 文件结尾,make文件最后一句话
include $(call all-makefiles-under,$(LOCAL_PATH))