安卓预置系统应用加载so库失败问题
正常情况下通过install直接安装是使用PackageManager,它会将so文件拷贝到系统读取的系统so目录(system/lib或system/lib64)下,提供给App使用;但系统应用需要提前将so文件拷贝到系统目录或者app/lib目录下(/system/priv-app/xxx/lib/arm或…否则运行时将报错“无法找到该so库”。赋值LOCAL_PREBUILT_JNI_LIB
·
需求和背景
由于项目需要将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文件。
更多推荐
已为社区贡献2条内容
所有评论(0)