推荐阅读
系统定制编译之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/appLOCAL_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\appvendor\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.txt8776 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 flag8782 || sPmsExt.isRemovableSysApp(pkg.packageName) && pkg.codePath.contains("/system/") ;
LOCAL_CERTIFICATE := platform或LOCAL_CERTIFICATE := PRESIGNED是否开启混淆LOCAL_PROGUARD_ENABLED := disabledLOCAL_MODULE_TAGS := optional使用platform签名LOCAL_CERTIFICATE := platform指定src目录LOCAL_SRC_FILES := $(call all-java-files-under, src)指定res目录LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/resLOCAL_SRC_FILES变量必须包含将要打包的模块的C/C++/java源码LOCAL_SRC_FILES := $(call all-java-files-under, app/src/main/java)编译AndriodManifest.xmlLOCAL_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.jarinclude $(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.soLOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_base_v4_2_1.soLOCAL_MODULE_TARGET_ARCHS:= arm arm64include $(BUILD_PREBUILT)include $(CLEAR_VARS)LOCAL_REQUIRED_MODULES := libBaiduMapSDK_base_v4_2_1LOCAL_JNI_SHARED_LIBRARIES := libBaiduMapSDK_base_v4_2_1include $(BUILD_PACKAGE)
include $(CLEAR_VARS)my_archs := arm arm64my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))LOCAL_PREBUILT_JNI_LIBS := \lib/$(my_src_arch)/libXXX.so \lib/$(my_src_arch)/libXXX.soLOCAL_MODULE_TARGET_ARCH := $(my_src_arch)include $(BUILD_PACKAGE)
#lib/baidumap.mkinclude $(CLEAR_VARS)LOCAL_MODULE_TAGS := optionalLOCAL_MODULE_SUFFIX := .soLOCAL_MODULE := libBaiduMapSDK_map_v4_2_1LOCAL_MODULE_CLASS := SHARED_LIBRARIESLOCAL_SRC_FILES_arm :=libs/armeabi-v7a/libBaiduMapSDK_map_v4_2_1.soLOCAL_SRC_FILES_arm64 :=libs/arm64-v8a/libBaiduMapSDK_map_v4_2_1.soLOCAL_MODULE_TARGET_ARCHS:= arm arm64LOCAL_MULTILIB := bothinclude $(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_LIBSJNI_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 := optionalLOCAL_SRC_FILES := $(call all-subdir-Java-files) \src/com/gm/cn/XXX.aidlLOCAL_PACKAGE_NAME := Testinclude $(BUILD_PACKAGE)
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_SRC_FILES += libutils_test.cpp test_demo.cpp\libutilsbasic_test.cppLOCAL_SHARED_LIBRARIES += libutils libcutils libbase liblogLOCAL_SHARED_LIBRARIES += libhidlbaseLOCAL_SHARED_LIBRARIES += libbinder libion \libEGL libGLESv1_CM libGLESv2LOCAL_C_INCLUDES +=LOCAL_CFLAGS += -DLOG_TAG=\"test_demo\"LOCAL_VENDOR_MODULE := trueinclude $(BUILD_EXECUTABLE)
二、预置无源码的第三方apk
1.预置apk的路径为/system/app/
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_CERTIFICATE := PRESIGNEDinclude $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_MODULE_PATH := $(TARGET_OUT)/appLOCAL_CERTIFICATE := PRESIGNEDinclude $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_MODULE_PATH := $(TARGET_OUT_APPS)LOCAL_CERTIFICATE := PRESIGNEDinclude $(BUILD_PREBUILT)
2.预置apk的路径为/system/priv-app/
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_PRIVILEGED_MODULE := trueLOCAL_CERTIFICATE := PRESIGNEDinclude $(BUILD_PREBUILT)
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_MODULE_PATH := $(TARGET_OUT)/priv-appLOCAL_CERTIFICATE := PRESIGNEDinclude $(BUILD_PREBUILT)
3.预置apk的路径为/system/vendor/operator/app
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_CERTIFICATE := PRESIGNEDLOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/appLOCAL_PROPRIETARY_MODULE := trueLOCAL_MODULE_OWNER := mtkinclude $(BUILD_PREBUILT)
4.预置apk的路径为/data/app/
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)#LOCAL_PRIVILEGED_MODULE := trueLOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)LOCAL_CERTIFICATE := PRESIGNEDinclude $(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 := TestLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_MODULE_CLASS := APPSLOCAL_VENDOR_MODULE := trueLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)LOCAL_CERTIFICATE := platforminclude $(BUILD_PREBUILT)
三、预制带so的apk
LOCAL_PATH := $(call my-dir)my_archs := arm arm64my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))include $(CLEAR_VARS)LOCAL_MODULE := TestLOCAL_MODULE_CLASS := APPSLOCAL_MODULE_TAGS := optionalLOCAL_BUILT_MODULE_STEM := package.apkLOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)#LOCAL_PRIVILEGED_MODULE :=LOCAL_CERTIFICATE := PRESIGNED#LOCAL_OVERRIDES_PACKAGES :=LOCAL_SRC_FILES := $(LOCAL_MODULE).apkLOCAL_PREBUILT_JNI_LIBS := \lib/$(my_src_arch)/libXXX.so \lib/$(my_src_arch)/libXXX.soLOCAL_MODULE_TARGET_ARCH := $(my_src_arch)include $(BUILD_PREBUILT)
编写Android.mk把Android studio项目编译到AOSP源码中
https://blog.csdn.net/u012514113/article/details/124384430Android APP应用开发引用系统framework.jar
sdk/out/target/common/obj/JAVA_LIBRARIES/framework-minus-apex_intermediates/classes.jarclasses.jar修改为framework.jarlibs/framework.jar
配置build.gradle
allprojects {repositories {google()jcenter()}//add startgradle.projectsEvaluated {tasks.withType(JavaCompile) {options.compilerArgs.add('-Xbootclasspath/p:app/libs/framework.jar')}}//add end}dependencies {compileOnly files('libs/framework.jar')}
商务合作
更多业务合作,点击下方"阅读原文"