安卓预置系统应用加载so库失败问题

需求和背景

由于项目需要将apk应用预置到定制安卓系统,且apk中带有so库。正常情况下通过install直接安装是使用PackageManager,它会将so文件拷贝到系统读取的系统so目录(system/lib或system/lib64)下,提供给App使用;但系统应用需要提前将so文件拷贝到系统目录或者app/lib目录下(/system/priv-app/xxx/lib/arm或…/arm64)。否则运行时将报错“无法找到该so库”。

解决方法

解决该问题有两种方案:

方案一,解压apk中so文件,拷贝到apk所在目录的lib目录下。

编译apk的Android.mk文件如下:


# 解压apk并将所有so文件拷贝到apk对应的lib目录下。
PRIVATE_EMBEDDED_JNI_LIBS := 'lib/*.so'
JNI_LIBS :=
$(foreach FILE,$(shell if unzip -l $(LOCAL_PATH)/$(LOCAL_SRC_FILES) $(PRIVATE_EMBEDDED_JNI_LIBS) > /dev/null ; then \
        rm -rf $(LOCAL_PATH)/uncompressedlibs && \
        mkdir $(LOCAL_PATH)/uncompressedlibs; \
        unzip $(LOCAL_PATH)/$(LOCAL_SRC_FILES) $(PRIVATE_EMBEDDED_JNI_LIBS) -d $(LOCAL_PATH)/uncompressedlibs > /dev/null && \
        find $(LOCAL_PATH)/uncompressedlibs -name *.so; \
    fi),$(eval JNI_LIBS += $(FILE)))
$(info echo $(JNI_LIBS))
LOCAL_PREBUILT_JNI_LIBS := $(subst $(LOCAL_PATH),,$(JNI_LIBS))

include $(BUILD_PREBUILT)

方案二,采用@符号指定apk运行时加载apk中的so。

赋值LOCAL_PREBUILT_JNI_LIBS 变量时加上@符号,运行时会加载apk中对应的so库,这样就不需要解压apk中的so并拷贝到lib目录。如果不加@符号,则会寻找apk安装目录下lib目录中对应so。


# 方案二、采用@符号指定apk运行时加载apk中的so
ifeq ($(TARGET_ARCH), arm)
LOCAL_PREBUILT_JNI_LIBS := \
@lib/armeabi-v7a/libxxx1.so \
@lib/armeabi-v7a/libxxx2.so
else ifeq ($(TARGET_ARCH),arm64)
LOCAL_PREBUILT_JNI_LIBS := \
@lib/armeabi-v7a/libxxx1.so \
@lib/armeabi-v7a/libxxx2.so
endif

注: 无论方案一还是方案二、System.loadLibrary方法都会先找到apk所在目录的lib或者apk中所带的so文件。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值