如何在 APK 中引用库,构建 Android 图像
How to reference libraries inside an APK, building an Android image
我需要构建一个 Android 9 图像,其中包括一些预构建的 APKs(OpenVPNForAndroid,在这种特定情况下)。
从 f-droid 下载的 APK 包含一些动态加载的库。我已经使用下面的 Android.mk 文件将它添加到图像中;该应用程序已安装并正常启动,但当我尝试连接时失败并出现此错误:
Cannot run program "/system/app/OpenVPNForAndroid/lib/arm64/libovpnexec.so": error=2, No such file or directory
java.io.IOException: Cannot run program "/system/app/OpenVPNForAndroid/lib/arm64/libovpnexec.so": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1050)
at de.blinkt.openvpn.core.OpenVPNThread.startOpenVPNThreadArgs(OpenVPNThread.java:139)
at de.blinkt.openvpn.core.OpenVPNThread.run(OpenVPNThread.java:68)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.VNIXProcess.forkAndExec(Native Method)
at java.lang.VNIXProcess.<init>(VNIXProcess.java:133)
at java.lang.ProcessImpl.start(ProcessImpl.java:132)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 3 more
,Error reading from output of OpenVPN process
Attempt to invoke virtual method 'void java.lang.Process.destroy()' on a null object reference
java.lang.NullPointerException: Attempt to invoke virtual method 'void java.lang.Process.destroy()' on a null object reference
at de.blinkt.openvpn.core.OpenVPNThread.stopProcess(OpenVPNThread.java:56)
at de.blinkt.openvpn.core.OpenVPNThread.startOpenVPNThreadArgs(OpenVPNThread.java:194)
at de.blinkt.openvpn.core.OpenVPNThread.run(OpenVPNThread.java:68)
at java.lang.Thread.run(Thread.java:764)
显然,APK 中的库将被忽略。
我想避免提取 .so 文件以将它们添加到图像中(因为我担心在未来的更新中我会忘记提取库再次),我认为这应该是可能的,但显然仍然缺少一些东西。
使用Android.mk文件,使用genandroidmk生成,是这样的:
LOCAL_PATH := $(call my-dir)
my_archs := arm x86 arm64
my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))
include $(CLEAR_VARS)
LOCAL_MODULE := OpenVPNForAndroid
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 := de.blinkt.openvpn_175.apk
LOCAL_PREBUILT_JNI_LIBS := \
@lib/arm64-v8a/libjbcrypto.so \
@lib/arm64-v8a/libopenvpn.so \
@lib/arm64-v8a/libopvpnutil.so \
@lib/arm64-v8a/libosslspeedtest.so \
@lib/arm64-v8a/libovpn3.so \
@lib/arm64-v8a/libovpnexec.so
LOCAL_MODULE_TARGET_ARCH := $(my_src_arch)
include $(BUILD_PREBUILT)
然后,在我的产品定义中我有:
PRODUCT_PACKAGES += OpenVPNForAndroid
我是不是遗漏了什么,或者如果不提取它们就无法再引用 APK 中的库?
提前致谢。
嵌入式库将不再提取。看:
Don't extract jni from prebuilt apks
所以你可以通过LOCAL_POST_INSTALL_CMD提取它。
尝试以下操作:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := OpenVPNForAndroid
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 := de.blinkt.openvpn_175.apk
# use lib/armeabi-v7a and lib/arm respectively, for 32bit apps
MY_PREBUILT_LIBS_SRC := lib/arm64-v8a
MY_PREBUILT_LIBS_DST := lib/arm64
ifeq ($(LOCAL_PRIVILEGED_MODULE),true)
MY_TARGET_DST := $(TARGET_OUT_APPS_PRIVILEGED)
else
MY_TARGET_DST := $(TARGET_OUT_APPS)
endif
LOCAL_POST_INSTALL_CMD := unzip -o $(LOCAL_PATH)/$(LOCAL_SRC_FILES) $(MY_PREBUILT_LIBS_SRC)/* -d $(MY_TARGET_DST)/$(LOCAL_MODULE) ; \
mv $(MY_TARGET_DST)/$(LOCAL_MODULE)/$(MY_PREBUILT_LIBS_SRC) $(MY_TARGET_DST)/$(LOCAL_MODULE)/$(MY_PREBUILT_LIBS_DST) ; \
chmod 0755 $(MY_TARGET_DST)/$(LOCAL_MODULE)/$(MY_PREBUILT_LIBS_DST)/*
include $(BUILD_PREBUILT)
我需要构建一个 Android 9 图像,其中包括一些预构建的 APKs(OpenVPNForAndroid,在这种特定情况下)。
从 f-droid 下载的 APK 包含一些动态加载的库。我已经使用下面的 Android.mk 文件将它添加到图像中;该应用程序已安装并正常启动,但当我尝试连接时失败并出现此错误:
Cannot run program "/system/app/OpenVPNForAndroid/lib/arm64/libovpnexec.so": error=2, No such file or directory
java.io.IOException: Cannot run program "/system/app/OpenVPNForAndroid/lib/arm64/libovpnexec.so": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1050)
at de.blinkt.openvpn.core.OpenVPNThread.startOpenVPNThreadArgs(OpenVPNThread.java:139)
at de.blinkt.openvpn.core.OpenVPNThread.run(OpenVPNThread.java:68)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.VNIXProcess.forkAndExec(Native Method)
at java.lang.VNIXProcess.<init>(VNIXProcess.java:133)
at java.lang.ProcessImpl.start(ProcessImpl.java:132)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 3 more
,Error reading from output of OpenVPN process
Attempt to invoke virtual method 'void java.lang.Process.destroy()' on a null object reference
java.lang.NullPointerException: Attempt to invoke virtual method 'void java.lang.Process.destroy()' on a null object reference
at de.blinkt.openvpn.core.OpenVPNThread.stopProcess(OpenVPNThread.java:56)
at de.blinkt.openvpn.core.OpenVPNThread.startOpenVPNThreadArgs(OpenVPNThread.java:194)
at de.blinkt.openvpn.core.OpenVPNThread.run(OpenVPNThread.java:68)
at java.lang.Thread.run(Thread.java:764)
显然,APK 中的库将被忽略。
我想避免提取 .so 文件以将它们添加到图像中(因为我担心在未来的更新中我会忘记提取库再次),我认为这应该是可能的,但显然仍然缺少一些东西。
使用Android.mk文件,使用genandroidmk生成,是这样的:
LOCAL_PATH := $(call my-dir)
my_archs := arm x86 arm64
my_src_arch := $(call get-prebuilt-src-arch, $(my_archs))
include $(CLEAR_VARS)
LOCAL_MODULE := OpenVPNForAndroid
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 := de.blinkt.openvpn_175.apk
LOCAL_PREBUILT_JNI_LIBS := \
@lib/arm64-v8a/libjbcrypto.so \
@lib/arm64-v8a/libopenvpn.so \
@lib/arm64-v8a/libopvpnutil.so \
@lib/arm64-v8a/libosslspeedtest.so \
@lib/arm64-v8a/libovpn3.so \
@lib/arm64-v8a/libovpnexec.so
LOCAL_MODULE_TARGET_ARCH := $(my_src_arch)
include $(BUILD_PREBUILT)
然后,在我的产品定义中我有:
PRODUCT_PACKAGES += OpenVPNForAndroid
我是不是遗漏了什么,或者如果不提取它们就无法再引用 APK 中的库?
提前致谢。
嵌入式库将不再提取。看: Don't extract jni from prebuilt apks
所以你可以通过LOCAL_POST_INSTALL_CMD提取它。 尝试以下操作:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := OpenVPNForAndroid
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 := de.blinkt.openvpn_175.apk
# use lib/armeabi-v7a and lib/arm respectively, for 32bit apps
MY_PREBUILT_LIBS_SRC := lib/arm64-v8a
MY_PREBUILT_LIBS_DST := lib/arm64
ifeq ($(LOCAL_PRIVILEGED_MODULE),true)
MY_TARGET_DST := $(TARGET_OUT_APPS_PRIVILEGED)
else
MY_TARGET_DST := $(TARGET_OUT_APPS)
endif
LOCAL_POST_INSTALL_CMD := unzip -o $(LOCAL_PATH)/$(LOCAL_SRC_FILES) $(MY_PREBUILT_LIBS_SRC)/* -d $(MY_TARGET_DST)/$(LOCAL_MODULE) ; \
mv $(MY_TARGET_DST)/$(LOCAL_MODULE)/$(MY_PREBUILT_LIBS_SRC) $(MY_TARGET_DST)/$(LOCAL_MODULE)/$(MY_PREBUILT_LIBS_DST) ; \
chmod 0755 $(MY_TARGET_DST)/$(LOCAL_MODULE)/$(MY_PREBUILT_LIBS_DST)/*
include $(BUILD_PREBUILT)