推荐阅读
系统定制编译之Android.mk和Android.bp详解
Android系统定制之Android.mk内置第三方apk和资源文件的方法总结
预置apk进入到五个特定目录,提取每个apk所包含的so文件。各目录对应的apk和so文件的安装路径不同,如下所示:
(1).data_app目录下apk对应安装到data/app,为便于产线生产测试,该路径下应用在默认保存到system区,在恢复出厂设置时复制到data/app,系统启动时候会解析安装。
(2).system_app_platform目录下应用对应安装到system/app,采用系统签名
(3).system_app_presigned目录下应用对应安装到system/app,应用自签名
(4).system_priv-app目录下应用安装到system/priv-app,应用自签名
(5).system_app_presigned_lib目录下应用安装到 system/app下,应用自签名,该目录下应用所包含的so 文件将编译到system/lib/下
Android.mk中通过 LOCAL_MODULE_PATH来指定预置apk的路径,如下所示:
其中 $(TARGET_OUT)表示预置到/system/目录
(1).预置apk的路径为/system/app/
LOCAL_MODULE_PATH := $(TARGET_OUT_APPS)
或
LOCAL_MODULE_PATH := $(TARGET_OUT)/app
或
去掉LOCAL_PRIVILEGED_MODULE := true
(2).预置apk的路径为/system/priv-app/
LOCAL_MODULE_PATH := $(TARGET_OUT)/priv-app
或
LOCAL_PRIVILEGED_MODULE := true
(3).预置apk的路径为/system/vendor/operator/app
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app
(4).预置apk的路径为/data/app/
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)/
在可卸载清单列表添加对应的包名,白名单文件中加入需要卸载的apk的包名
(5).out\target\product\版本号\system\app
\vendor\mediatek\proprietary\frameworks\base\data\etc\pms_sysapp_removable_system_list.txt
添加上应用包名
(6).out\target\product\版本号\vendor\app
vendor\mediatek\proprietary\frameworks\base\data\etc\pms_sysapp_removable_vendor_list.txt
添加上应用包名
有时候会因为内存分配的不够导致编译不过,可在device/mediateksample/对应版本/BoardConfig.mk设置扩大内存
白名单文件中加入需要卸载的apk的包名
/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_system_list.txt
8776 private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8777 @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8778 @Nullable UserHandle user)
8779 throws PackageManagerException {
8780 final boolean scanSystemPartition = ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0)
8781 // M:operator app also is removable and not system flag
8782 || sPmsExt.isRemovableSysApp(pkg.packageName) && pkg.codePath.contains("/system/") ;
LOCAL_CERTIFICATE := platform
或
LOCAL_CERTIFICATE := PRESIGNED
是否开启混淆
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_MODULE_TAGS := optional
使用platform签名
LOCAL_CERTIFICATE := platform
指定src目录
LOCAL_SRC_FILES := $(call all-java-files-under, src)
指定res目录
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res
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
#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)
#如果需要使用系统隐藏API编译,则需要定义:
LOCAL_PRIVATE_PLATFORM_APIS := true
#如果不需要使用系统隐藏API编译,则需要定义:
LOCAL_SDK_VERSION := current
#注意,两个是 if --else 的定义原则,根据实际情况选择
编译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
混淆配置,默认为full obfuscation,全代码混淆,disabled不开启
#不需要使用代码混淆的工具进行代码混淆
LOCAL_PROGUARD_ENABLED := disabled
#默认为使用将该工程代码全部混淆
LOCAL_PROGUARD_ENABLE := full
指定编译目标为32位或64位
LOCAL_MULTILIB :=
###可选值/32/64/first/both
指定目标lib库的类型
LOCAL_MODULE_TARGET_ARCH :=
###可选值arm/arm x86/arm64
配置当前系统不支持的类型
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH :=
###可选值arm/arm x86/arm64
应用程序的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
在指定分区中安装此模块
一般有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分区
#Android.mk LOCAL_PRODUCT_MODULE := true
aapt是Android的打包工具
(1).–auto-add-overlay #当不同文件夹有相同的资源id时,只将第一个资源合并打包进来,
(1).–extra-packages android.support.v7.appcompat #将extra-package包后边的文件包引入到当前代码框架中,就像给当前代码导入一个jar包,但是这里不限jar、library等等,这样引入编译之后就能合并在一起使用
LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages com.airbnb.lottie //lottie第三方aar的包名
引用多个jar包
第一步:先声明多个 jar 包的位置
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
CloudHelper:/libs/CommonUtil.jar \
BaiduLBS:/libs/BaiduLBS_Android.jar \
logger:/libs/logger.jar
include $(BUILD_MULTI_PREBUILT)
第二步:引用我们声明的多个jar包的变量
LOCAL_STATIC_JAVA_LIBRARIES := \
CommonUtil \
BaiduLBS \
logger
引用so库
include $(CLEAR_VARS)
LOCAL_SRC_FILES_arm :=libs/armeabi-v7a/libBaiduMapSDK_base_v4_2_1.so
LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_base_v4_2_1.so
LOCAL_MODULE_TARGET_ARCHS:= arm arm64
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
LOCAL_REQUIRED_MODULES := libBaiduMapSDK_base_v4_2_1
LOCAL_JNI_SHARED_LIBRARIES := libBaiduMapSDK_base_v4_2_1
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
my_archs := arm arm64
my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))
LOCAL_PREBUILT_JNI_LIBS := \
lib/$(my_src_arch)/libXXX.so \
lib/$(my_src_arch)/libXXX.so
LOCAL_MODULE_TARGET_ARCH := $(my_src_arch)
include $(BUILD_PACKAGE)
#lib/baidumap.mk
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE := libBaiduMapSDK_map_v4_2_1
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_SRC_FILES_arm :=libs/armeabi-v7a/libBaiduMapSDK_map_v4_2_1.so
LOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_map_v4_2_1.so
LOCAL_MODULE_TARGET_ARCHS:= arm arm64
LOCAL_MULTILIB := both
include $(BUILD_PREBUILT)
#Android.mk中添加include $(LOCAL_PATH)/lib/baidumap.mk
不从apk中解压lib库而直接添加
LOCAL_PREBUILT_JNI_LIBS = \
@lib/armeabi-v7a/libcryptox.so \
@lib/armeabi-v7a/libfb.so
手动解压lib文件到当前apk的编译目录并添加
LOCAL_PREBUILT_JNI_LIBS = \
lib/armeabi-v7a/libcryptox.so \
lib/armeabi-v7a/libfb.so
若当前apk包含的lib库文件数量比较多时,优化的思路是用递归搜索来替代手工对lib库文件进行添加
###清空临时变量JNI_LIBS
JNI_LIBS :=
###当前目录递归搜索
$(foreach FILE,$(shell find $(LOCAL_PATH)/lib/ -name *.so), $(eval JNI_LIBS += $(FILE)))
###获取搜索文件目录集(相对目录)
LOCAL_PREBUILT_JNI_LIBS := $(subst $(LOCAL_PATH),,$(JNI_LIBS))
Andoird.mk的递归查找
$(call all-java-files-under, $(LOCAL_PATH)) #获取指定目录下的所有 Java 文件。
$(call all-c-files-under, $(LOCAL_PATH)) #获取指定目录下的所有 C 语言文件。
$(call all-Iaidl-files-under, $(LOCAL_PATH)) #获取指定目录下的所有 AIDL 文件。
$(call all-makefiles-under, $(LOCAL_PATH)) #获取指定目录下的所有 Make 文件
Android.mk文件拷贝脚本
创建文件夹
$(shell mkdir -p out/target/product/customer/system/***)
拷贝文件
$(shell cp vendor/customer/thirdapp/your_assets/my.so out/target/product/customer/system/***)
拷贝文件夹
$(shell cp vendor/customer/thirdapp/your_assets/* -r out/target/product/customer/system/***)
拷贝的目的目录不能是data目录。Android默认是无法直接操作,data根目录和相关的目录,想直接读写/data是做不到的
$(shell mkdir $(TARGET_OUT)/vendor/operator/app/Facebook)
$(shell cp $(LOCAL_PATH)/Facebook.apk $(TARGET_OUT)/vendor/operator/app/Facebook)
一、预置带源码的apk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-Java-files) \
src/com/gm/cn/XXX.aidl
LOCAL_PACKAGE_NAME := Test
include $(BUILD_PACKAGE)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_SRC_FILES += libutils_test.cpp test_demo.cpp\
libutilsbasic_test.cpp
LOCAL_SHARED_LIBRARIES += libutils libcutils libbase liblog
LOCAL_SHARED_LIBRARIES += libhidlbase
LOCAL_SHARED_LIBRARIES += libbinder libion \
libEGL libGLESv1_CM libGLESv2
LOCAL_C_INCLUDES +=
LOCAL_CFLAGS += -DLOG_TAG=\"test_demo\"
LOCAL_VENDOR_MODULE := true
include $(BUILD_EXECUTABLE)
二、预置无源码的第三方apk
1.预置apk的路径为/system/app/
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_MODULE_PATH := $(TARGET_OUT)/app
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_MODULE_PATH := $(TARGET_OUT_APPS)
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
2.预置apk的路径为/system/priv-app/
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_PRIVILEGED_MODULE := true
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_MODULE_PATH := $(TARGET_OUT)/priv-app
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
3.预置apk的路径为/system/vendor/operator/app
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_OWNER := mtk
include $(BUILD_PREBUILT)
4.预置apk的路径为/data/app/
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE := true
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
Android O版本以后google加入了patch,不允许预置apk到data/app目录下,只允许使用adb install的方式来安装apk到data/app目录下,需要将其回到以前的版本
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11394,6 +11394,10 @@
+ " but expected at " + known.codePathString
+ "; ignoring.");
}
} /*else {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+ "Application package " + pkg.packageName
+ + " not found; ignoring.");
}*/
}
}
Android 11(R)预装APP到data/app目录
https://blog.csdn.net/zmlovelx/article/details/125664260
5.预置apk的路径为/vendor/app/
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := platform
include $(BUILD_PREBUILT)
三、预制带so的apk
LOCAL_PATH := $(call my-dir)
my_archs := arm arm64
my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))
include $(CLEAR_VARS)
LOCAL_MODULE := Test
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_TAGS := optional
LOCAL_BUILT_MODULE_STEM := package.apk
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
#LOCAL_PRIVILEGED_MODULE :=
LOCAL_CERTIFICATE := PRESIGNED
#LOCAL_OVERRIDES_PACKAGES :=
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_PREBUILT_JNI_LIBS := \
lib/$(my_src_arch)/libXXX.so \
lib/$(my_src_arch)/libXXX.so
LOCAL_MODULE_TARGET_ARCH := $(my_src_arch)
include $(BUILD_PREBUILT)
编写Android.mk把Android studio项目编译到AOSP源码中
https://blog.csdn.net/u012514113/article/details/124384430
Android APP应用开发引用系统framework.jar
sdk/out/target/common/obj/JAVA_LIBRARIES/framework-minus-apex_intermediates/classes.jar
classes.jar修改为framework.jar
libs/framework.jar
配置build.gradle
allprojects {
repositories {
google()
jcenter()
}
//add start
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xbootclasspath/p:app/libs/framework.jar')
}
}
//add end
}
dependencies {
compileOnly files('libs/framework.jar')
}
商务合作
更多业务合作,点击下方"阅读原文"