不带源码
常规预制
例:
1、在package/app下创建应用文件夹:Bs_yingyongbao
2、文件夹中放入需要预制的应用:Bs_yingyongbao.apk
3、对应的device.mk下添加PRODUCT_PACKAGES +=Bs_yingyongbao
4、创建Android.mk文件,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Bs_yingyongbao
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := APPS
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)
Android.mk各种参数解释
-
OCAL_PATH := $(call my-dir)
每个 Android.mk 文件必须以定义 LOCAL_PATH 为开始,它用于在开发 tree 中查找源文件。
-
include $(CLEAR_VARS)
CLEAR_VARS 变量由 Build System 提供,并指向一个指定的 GNU Makefile,由它负责清理很多 LOCAL_xxx。
例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES 等等,但不清理 LOCAL_PATH。
-
LOCAL_MODULE_TAGS := user eng tests optional
- user: 指该模块只在 user 版本下才编译 - eng: 指该模块只在 eng 版本下才编译 - tests: 指该模块只在 tests 版本下才编译 - optional:指该模块在所有版本下都编译
-
LOCAL_MODULE
模块名,可不用定义,默认 = $(LOCAL_PACKAGE_NAME),不能和既有模块相同,如果该变量未设置,则使用 LOCAL_PACKAGE_NAME,如果再没有,就会编译失败。
-
LOCAL_CERTIFICATE
使用的APK签名。
PRESIGNED:为应用本身的签名 testkey:普通 APK,默认情况下使用。 platform:使用Android系统源码中的系统签名,路径在build/make/target/product/security/platform.x509.pem和 build/make/target/product/security//platform.pk8,分别是公钥和私钥。这种方式编译出来的 APK 所在进程的 UID 为 system。 shared:该 APK 需要和 home/contacts 进程共享数据,可以参考 Launcher。 media:该 APK 是 media/download 系统中的一环,可以参考 Gallery。
-
LOCAL_MODULE_CLASS 指定模块的类型,可不用定义。
# 编译 apk 文件 LOCAL_MODULE_CLASS := APPS # 编译 jar 包 LOCAL_MODULE_CLASS := JAVA_LIBRAYIES # 定义动态库文件 LOCAL_MODULE_CLASS := SHARED_LIBRAYIES # 编译可执行文件 LOCAL_MODULE_CLASS := EXECUTABLES
- include $(BUILD_PACKAGE) 表示生成一个 APK,它可以是多种类型
BUILD_PACKAGE(既可以编apk,也可以编资源包文件,但是需要指定LOCAL_EXPORT_PACKAGE_RESOURCES:=true) BUILD_JAVA_LIBRARY(java共享库) BUILD_STATIC_JAVA_LIBRARY(java静态库) BUILD_EXECUTABLE(执行文件) BUILD_SHARED_LIBRARY(native共享库) BUILD_STATIC_LIBRARY(native静态库)
常规预制可能遇到的问题
- 预制应用是V2签名的,导致在out目录下生成的其apk,但第一次开机安装时无法成功安装。其原因是编译破环了V2签名的完整性,可考虑使用copy预制的方式:
$(shell mkdir -p $(TARGET_OUT_VENDOR)/operator/app/baicizhan) $(shell cp packages/apps/401apk/baicizhan.apk $(TARGET_OUT_VENDOR)/operator/app/baicizhan)
- so库文件找不到
方法一 不从apk中解压lib库而直接添加 如下例,在Android.mk中添加并配置变量(注意路径对应): LOCAL_PREBUILT_JNI_LIBS = \ @lib/armeabi-v7a/libcryptox.so \ @lib/armeabi-v7a/libfb.so 注意前面的 @符号,@标识符会将apk中的so抽离出来,拷贝到对应编译后的apk目录; 方法二 手动解压lib文件到当前apk的编译目录并添加 先解压当前apk内的lib文件夹到当前apk编译目录,同方法一在Android.mk中添加并配置变量(注意路径对应),如下例: 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)) <二>、然后需要注意当前Android环境是否符合apk运行条件(64位和32位)并配置apk运行环境 之所以要配置apk运行环境,是因为包含lib库的apk在添加lib库到编译环境之后,在Android环境和apk运行条件不符的情况下,需要在编译环境中指定环境。举例说明: 目前一般的apk运行环境为32位Android系统环境,当在64位Android系统中预置带有lib库的apk时,手动添加lib库文件到编译环境后,默认情况下编译环境会在编译后apk目录建立64位的环境的lib库路径 /lib/arm64,虽然编译过程未报错,但之后在执行该apk时,会出现apk因找不到lib库而报错 因此,需要在Android.mk中对当前apk编译环境进行配置,配置的方法常见的也有两种: <1>指定编译目标为 32位 或 64位 在Android目标中添加并配置变量: LOCAL_MULTILIB := ###可选值 /32/64/first/both <2>指定目标lib库的 类型 在Android.mk中添加并配置变量: LOCAL_MODULE_TARGET_ARCH := ###可选值 arm/arm x86/arm64 此处, LOCAL_MODULE_TARGET_ARCH 的值只能是当前编译环境所支持的类型,如果需要配置当前系统不支持类型,则需要配置如下另一个变量 LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH := ###可选值 arm/arm x86/arm64 与 LOCAL_MODULE_TARGET_ARCH 相反, LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH 的值只能是当前编译环境所不支持的类型,否则编译将不会生效 如下是一个完整的Android.mk脚本示例,其中apk运行环境为32位,系统为64位: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := UCBrowser LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_TAGS := optional LOCAL_BUILT_MODULE_STEM := package.apk LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) LOCAL_CERTIFICATE := PRESIGNED LOCAL_SRC_FILES := HK_UCBrowser*.apk LOCAL_PRIVILEGED_MODULE := true LOCAL_MULTILIB := 32 JNI_LIBS := $(foreach FILE,$(shell find $(LOCAL_PATH)/lib/ -name *.so), $(eval JNI_LIBS += $(FILE))) LOCAL_PREBUILT_JNI_LIBS := $(subst $(LOCAL_PATH),,$(JNI_LIBS)) include $(BUILD_PREBUILT)
静默安装
- 有些时候常规预制与拷贝预制都无法正常使用apk,但手动安装却可以正常使用,那么我们可以使用静默安装来实现。
进入系统后静默
android9静默安装Musicolet diff --git a/ap/build/make/core/Makefile b/ap/build/make/core/Makefile old mode 100644 new mode 100755 index fc3d9df..f6e71cb --- a/ap/build/make/core/Makefile +++ b/ap/build/make/core/Makefile @@ -13,11 +13,11 @@ LOCAL_PATH := $(BUILD_SYSTEM) # src:dest pair is the first one to match the same dest" #$(1): the src:dest pair #$(2): the dest -define check-product-copy-files -$(if $(filter-out $(TARGET_COPY_OUT_SYSTEM_OTHER)/%,$(2)), \ - $(if $(filter %.apk, $(2)),$(error \ - Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!))) -endef +# define check-product-copy-files +# $(if $(filter-out $(TARGET_COPY_OUT_SYSTEM_OTHER)/%,$(2)), \ + # $(if $(filter %.apk, $(2)),$(error \ + # Prebuilt apk found in PRODUCT_COPY_FILES: $(1), use BUILD_PREBUILT instead!))) +# endef # filter out the duplicate <source file>:<dest file> pairs. unique_product_copy_files_pairs := $(foreach cf,$(PRODUCT_COPY_FILES), \ diff --git a/ap/device/mediatek/mt6755/device.