全自动化预制APK

由于之前经常需要预制APK,需要写Android.mk和解压lib非常麻烦。所以之前写了https://blog.csdn.net/u013463707/article/details/75050910  这个博文解决此类问题。此博客发表以后帮助了很多开发者。但这个方法还是有弊端,仅仅解决了解压lib库的问题,效率还是不够高。

今天给大家介绍一种全自动化的方法,不用写Android.mk也不用解压lib.这种方案是我在RK Android中看到的,是通过Python脚本实现的。下面说下使用方法:

python auto_generator.py    参数一   参数二     参数三

参数一:代表项目路径,其实就是apk文件所在的文件夹的上级路径

参数二:代表APK所在文件夹的名字

参数三:代表这个APK是编译为可卸载还是不可卸载,其实就是编译后的存放路径(system  还是data  等,本脚本中是out/oem/不同文件夹,可以自行修改Python脚本中模板指定)

例如:APK在如下路径

 

使用这个脚本就是:python auto_generator.py ./ apk bundled_persist-app

说明:auto_generator.py我放在apk_unzip路径下,并且我也进入到apk_unzip路径下执行的该命令

执行后效果

 

完全解压出来了,也生成了Android.mk

 

项目中如何实现自动化呢?

(1)在device / rockchip/common/device.mk中添加如下代码

# Prebuild apps
ifneq ($(strip $(TARGET_PRODUCT)), )
    TARGET_DEVICE_DIR=$(shell test -d device && find device -maxdepth 4 -path '*/$(TARGET_PRODUCT)/BoardConfig.mk')
    TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(TARGET_DEVICE_DIR)))
#    $(info device-rockchip-common TARGET_DEVICE_DIR: $(TARGET_DEVICE_DIR))
    $(shell python $(LOCAL_PATH)/auto_generator.py $(TARGET_DEVICE_DIR) preinstall bundled_persist-app)
    $(shell python $(LOCAL_PATH)/auto_generator.py $(TARGET_DEVICE_DIR) preinstall_del bundled_uninstall_back-app)
    $(shell python $(LOCAL_PATH)/auto_generator.py $(TARGET_DEVICE_DIR) preinstall_del_forever bundled_uninstall_gone-app)
    -include $(TARGET_DEVICE_DIR)/preinstall/preinstall.mk
    -include $(TARGET_DEVICE_DIR)/preinstall_del/preinstall.mk
    -include $(TARGET_DEVICE_DIR)/preinstall_del_forever/preinstall.mk
endif

也就是编译时自动调用上述代码,$(TARGET_DEVICE_DIR)就是具体平台或项目的文件夹路径,preinstall就是这个路径下的文件夹名字,bundled_persist-app就是编译为可卸载APP

preinstall.mk是执行该脚本后自动生成的文件,include 该文件就会编译对应APK。

你只需要做的就是把这个APK放在$(TARGET_DEVICE_DIR)/preinstall/  路径下。

 

说明:本脚本仅不支持仅包含arm64库的apk,如果仅包含arm64库,lib不会被抽取。当同时含有arm64 和arm库,只会抽取arm库。如果需要支持仅包含arm64库的apk,自行修改脚本。

下面是该脚本源码,有兴趣的可以移植到你的工程中,仅做简单修改即可。也可以到这里下载

https://download.csdn.net/download/u013463707/11387804

#!/usr/bin/env python
import sys
import os
import re
import zipfile
import shutil

templet = """include $(CLEAR_VARS)
LOCAL_MODULE := %s
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_PATH := $(TARGET_OUT_OEM)/%s
LOCAL_SRC_FILES := $(LOCAL_MODULE)$(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
#LOCAL_DEX_PREOPT := false
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_JNI_SHARED_LIBRARIES_ABI := %s
MY_LOCAL_PREBUILT_JNI_LIBS := %s
MY_APP_LIB_PATH := $(TARGET_OUT_OEM)/%s/$(LOCAL_MODULE)/lib/$(LOCAL_JNI_SHARED_LIBRARIES_ABI)
ifneq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI), None)
$(warning MY_APP_LIB_PATH=$(MY_APP_LIB_PATH))
LOCAL_POST_INSTALL_CMD := \
    mkdir -p $(MY_APP_LIB_PATH) \
    $(foreach lib, $(MY_LOCAL_PREBUILT_JNI_LIBS), ; cp -f $(LOCAL_PATH)/$(lib) $(MY_APP_LIB_PATH)/$(notdir $(lib)))
endif
include $(BUILD_PREBUILT)

"""

copy_app_templet = """LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_APK_NAME := %s
LOCAL_POST_PROCESS_COMMAND := $(shell mkdir -p $(TARGET_OUT_OEM)/%s/$(LOCAL_APK_NAME) && cp $(LOCAL_PATH)/$(LOCAL_APK_NAME).apk $(TARGET_OUT_OEM)/%s/$(LOCAL_APK_NAME)/)
"""

def main(argv):
    preinstall_dir = os.path.join(argv[1],argv[2])
    if os.path.exists(preinstall_dir):
        #Use to include modules
        isfound = 'not_found_lib'
        include_path = preinstall_dir + '/preinstall.mk'
        android_path = preinstall_dir + '/Android.mk'

        if os.path.exists(include_path):
            os.remove(include_path)
        if os.path.exists(android_path):
            os.remove(android_path)

        includefile = file(include_path, 'w')
        androidfile = file(android_path, 'w')

        androidfile.write("include $(call all-subdir-makefiles)\n\n")

        MY_LOCAL_PREBUILT_JNI_LIBS = '\\' + '\n'

        for root, dirs, files in os.walk(preinstall_dir):
            for file_name in files:
                p = re.compile(r'\S*(?=.apk\b)')
                found = p.search(file_name)
                if found:
                    include_apk_path = preinstall_dir + '/' + found.group()
                    makefile_path = include_apk_path + '/Android.mk'
                    apk = preinstall_dir + '/' + found.group() + '.apk'
                    try:
                        zfile = zipfile.ZipFile(apk,'r')
                    except:
                        if os.path.exists(include_apk_path):
                            shutil.rmtree(include_apk_path)
                        os.makedirs(include_apk_path)
                        apkpath = preinstall_dir + '/' + found.group() + '/'
                        shutil.move(apk,apkpath)
                        makefile = file(makefile_path,'w')
                        makefile.write("LOCAL_PATH := $(my-dir)\n\n")
                        makefile.write(templet % (found.group(),argv[3],'None',MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))
                        continue
                    for lib_name in zfile.namelist():
                        include_apklib_path = include_apk_path + '/lib' + '/arm'
                        if os.path.exists(include_apk_path):
                            shutil.rmtree(include_apk_path)
                        os.makedirs(include_apklib_path)
                        makefile = file(makefile_path,'w')
                        makefile.write("LOCAL_PATH := $(my-dir)\n\n")
                        apkpath = preinstall_dir + '/' + found.group() + '/'
                    for lib_name in zfile.namelist():
                        lib = re.compile(r'\A(lib/armeabi-v7a/)+?')
                        find_name = 'lib/armeabi-v7a/'
                        if not cmp(lib_name,find_name):
                            continue
                        libfound = lib.search(lib_name)
                        if libfound:
                            isfound = 'armeabi-v7a'
                            data = zfile.read(lib_name)
                            string = lib_name.split(libfound.group())
                            libfile = include_apklib_path + '/' + string[1]
                            MY_LOCAL_PREBUILT_JNI_LIBS += '\t' + 'lib/arm' + '/' + string[1] + '\\' + '\n'
                            if(os.path.isdir(libfile)):
                                continue
                            else:
                                includelib = file(libfile,'w')
                                includelib.write(data)
                    if not cmp(isfound,'not_found_lib'):
                        for lib_name in zfile.namelist():
                            lib = re.compile(r'\A(lib/armeabi/)+?')
                            find_name = 'lib/armeabi/'
                            if not cmp(lib_name,find_name):
                                continue
                            libfound = lib.search(lib_name)
                            if libfound:
                                data = zfile.read(lib_name)
                                string = lib_name.split(libfound.group())
                                libfile = include_apklib_path + '/' + string[1]
                                MY_LOCAL_PREBUILT_JNI_LIBS += '\t' + 'lib/arm' + '/' + string[1] + '\\' + '\n'
                                if(os.path.isdir(libfile)):
				    continue
				else:
                                    includelib = file(libfile,'w')
                                    includelib.write(data)
                    tmp_jni_libs = '\\' + '\n'
                    if not cmp(MY_LOCAL_PREBUILT_JNI_LIBS,tmp_jni_libs):
                        nolibpath = preinstall_dir + '/' + found.group() + '/lib'
                        shutil.rmtree(nolibpath)
                        makefile.write(templet % (found.group(),argv[3],'None',MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))
                    else:
                        if argv[2]=='preinstall_del' or argv[2]=='preinstall_del_forever':
                            makefile.write(templet % (found.group(),argv[3],'arm',MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))
                        else:
                            makefile.write(templet % (found.group(),argv[3],'arm',MY_LOCAL_PREBUILT_JNI_LIBS,argv[3]))
                    shutil.move(apk,apkpath)
                    isfound = 'not_found_lib'
                    MY_LOCAL_PREBUILT_JNI_LIBS = '\\' + '\n'
                    makefile.close()
            break
        for root, dirs,files in os.walk(preinstall_dir):
            for dir_file in dirs:
                includefile.write('PRODUCT_PACKAGES += %s\n' %dir_file)
            break
        includefile.close()

if __name__=="__main__":
  main(sys.argv)

 

之前脚本不支持arm64 库,下面是修改后的脚本,需要的点击下载

https://download.csdn.net/download/u013463707/12366148

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Free飝Fly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值