在x86设备上加载ARM共享库的Android应用程序失败

时间:2018-02-06 18:10:48

标签: android x86 arm java-native-interface shared-libraries

我有一个非常简单的Android应用程序。我想加载一个名为'libcamera.so'的共享库,然后通过JNI调用方法。 我没有这个库,我无法访问源代码。它最初是为ARM编译的。 x86版本不可用。

项目可以检测库并在jniLibs文件夹中正确显示它。

在我的主要活动中,我正在尝试加载第三方库:

static {
    System.loadLibrary("camera");
}

执行此行时,logcat显示以下内容:

02-06 14:11:38.517 4455-4455/uk.co.test.myApp E/art: dlopen("/data/app/uk.co.test.myApp-2/lib/x86/libcamera.so", RTLD_LAZY) failed: dlopen failed: "/data/app/uk.co.test.myApp-2/lib/x86/libcamera.so" has unexpected e_machine: 40
02-06 14:11:38.519 4455-4455/uk.co.test.myApp E/AndroidRuntime: FATAL EXCEPTION: main
 Process: uk.co.test.myApp, PID: 4455
 java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/uk.co.test.myApp-2/lib/x86/libcamera.so" has unexpected e_machine: 40
     at java.lang.Runtime.loadLibrary(Runtime.java:371)
     at java.lang.System.loadLibrary(System.java:988)
     at uk.co.test.myApp.MainActivity.<clinit>(MainActivity.java:17)
     at java.lang.reflect.Constructor.newInstance(Native Method)
     at java.lang.Class.newInstance(Class.java:1603)
     at android.app.Instrumentation.newActivity(Instrumentation.java:1066)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2226)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
     at android.app.ActivityThread.access$800(ActivityThread.java:151)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:135)
     at android.app.ActivityThread.main(ActivityThread.java:5258)
     at java.lang.reflect.Method.invoke(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:372)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

使用此库的其他第三方应用程序可以在我的x86设备(Epson BT350)上运行,所以我觉得这应该是可行的。 我已经发现了一个名为'Houdini'的东西,允许ARM应用程序在x86上运行 - 我已经检查过,我的设备有这个库,所以我很困惑为什么它不能正常工作。但我也很可能不明白Houdini是如何运作的!

我试过在x86模拟器上运行 - 同样的错误。

非常感谢任何想法。

1 个答案:

答案 0 :(得分:0)

我通过强制我的应用程序仅构建armeabi版本来解决问题。我是通过在gradle中使用abifilter来做到这一点的。我将以下内容添加到defaultConfig

ndk {
    abiFilters "armeabi"
}

这将在我的x86设备上运行,因为Houdini将启动并进行翻译。它不理想,因为这种翻译影响了性能 - 但它是一个开始,让我进入下一阶段。