4

I have an android app with native code where I use openCV library. When running the app in phone everything is working well but when I try to run it on tablet(Lenovo yoga 2 pro) I am encountering this error:

01-03 11:53:13.007: E/AndroidRuntime(25632): FATAL EXCEPTION: main
01-03 11:53:13.007: E/AndroidRuntime(25632): Process: <appname>, PID: 25632
01-03 11:53:13.007: E/AndroidRuntime(25632): java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app-lib/<appname>/libnative_module.so" has unexpected e_machine: 40
01-03 11:53:13.007: E/AndroidRuntime(25632):    at java.lang.Runtime.loadLibrary(Runtime.java:364)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at java.lang.System.loadLibrary(System.java:526)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at <appname>.SplashActivity$1.onManagerConnected(SplashActivity.java:35)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at org.opencv.android.AsyncServiceHelper$1.onServiceConnected(AsyncServiceHelper.java:318)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1127)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1144)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at android.os.Handler.handleCallback(Handler.java:733)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at android.os.Handler.dispatchMessage(Handler.java:95)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at android.os.Looper.loop(Looper.java:149)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at android.app.ActivityThread.main(ActivityThread.java:5283)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at java.lang.reflect.Method.invokeNative(Native Method)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at java.lang.reflect.Method.invoke(Method.java:515)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
01-03 11:53:13.007: E/AndroidRuntime(25632):    at dalvik.system.NativeStart.main(Native Method)

this is on the line 45 in SplashActivity:

System.loadLibrary("native_module");

Can someone help me to solve this error? or What am I doing wrong?

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
mark
  • 354
  • 2
  • 5
  • 15

2 Answers2

4

Your tablet is based on Intel Atom CPU. You must build your native_module for APP_ABI=x86. Note that you also need the compatible version of OpenCV.

Update: in this particular case, the app was built for both x86 and ARM. But the app installer chose the wrong subfolder, maybe because the filenames listed in libs/x86 and libs/armeabi did not exactly match. The reliable and efficient approach for apps that have non-trivial native component is to upload separate APKs to PlayStore.

Community
  • 1
  • 1
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • I thought the same thing and I checked the APP_ABI but it is set like this: APP_ABI := armeabi armeabi-v7a x86 mips so it should be ok. How do you mean the compatible version of OpenCV? because when I downloaded the openCV for android there was no option for choosing the processor type – mark Jan 03 '15 at 17:48
  • Do you use shared or static version of OpenCV? – Alex Cohn Jan 03 '15 at 19:05
  • In my project I have directory libs where are subfolders with .so and .a libraries for different processor types(these subfolders are from downloaded opencv project for android, in folder structure sdk/native/libs). And then I have linked opencv android project in eclipse(sdk/java). – mark Jan 03 '15 at 20:55
  • You can verify the contents of the `libs/` folder of your Eclipse project. In C/C++ perspective, you can see "binaries" tab, and it will list the `so` files that you have, marked for architecture (x86/arm/whatever). But you should also check which files are actually installed on the device. – Alex Cohn Jan 03 '15 at 22:07
  • How can I check which files are installed on device? But to run the app I had to download opencv manager app and this app is working(does not crash) so it is bit weird. – mark Jan 05 '15 at 09:33
  • Even if your device is not rooted, you can `adb pull /data/app-lib//libnative_module.so`. You can even `adb shell ls -l /data/app-lib//` to know which native libraries got installed on the device. Compare the results on a (arm) phone and on the (x86) tablet. – Alex Cohn Jan 05 '15 at 12:06
  • sorry for late answer but I tried it with adb but it did not work I could not access it. When I tried to list it using ls-l the access was denied. Maybe I have to root it but I tried it on intel smartphone and it was working well. Do you know why was it so? or Is it really possible that some .so libraries are not installed/moved to tablet during deployment of app? – mark Jan 14 '15 at 09:11
  • If you could not pull the file, most likely it is simply not there. But you can try `adb shell ls -l /data/app-lib//libnative_module.so` or `adb shell ls -l /data/data//lib/libnative_module.so`, too. Make sure that you don't misspell **** because `/data/app-lib/` is not public. To verify the ****, you can use `adb shell pm list packages`. – Alex Cohn Jan 14 '15 at 09:57
  • I am really sorry for late response but I have not had much time for this. I listed the libnative_module.so and it was there then I looked what other .so files are in the lib folder. Everything except .a files were there but the thing is that the .so file names were corresponding to armeabi subfolder in folder libs in Eclipse project and not to x86. Is there some way how to get those x86 files on the device when the device is Intel one? – mark Feb 24 '15 at 17:24
  • e.g.: in armeabi folder is libnative_camera_r2.2.0.so and in x86 is libnative_camera_r2.3.3.so and when I use adb to list lib folder I see libnative_camera_r2.2.0.so and other files from armeabi but not from x86 folder – mark Feb 24 '15 at 17:26
  • I would suggest to try package x86 libraries only. Will the app install and run on your target device? There has been a [fruitful discussion](http://stackoverflow.com/a/20029256/192373) on SO how an APK can be split into separate "target architecture" smaller APKs. – Alex Cohn Feb 24 '15 at 19:46
  • Thanks I tried it but different way and I used just APP_ABI=x86 instead specifying there other types and it worked. I really do not understand why if I specify there also other types of architectures it chooses arm instead of x86 despite the fact it is Intel tablet. BTW I found really good app which lists all the apps and shows you what ndk libraries and of what type each installed application has( https://play.google.com/store/apps/details?id=com.xh.nativelibsmonitor.app&hl=en) So your initial answer is right but you can modify it that sometimes despite it is specified also with other it has – mark Mar 03 '15 at 09:12
  • The app installer expects `libs/` folders' contents to have exactly same filenames, so you hit unchartered waters with **_r2.2.0** vs **_r2.3.3**. The problem with Atom is that too often apps don't have native support for it; so the vendor has no choice but to add *crippled* ARM emulation. In your specific case, this fired back. I believe that if you only build for `APP_ABI=armeabi-v7a`, your app will work (but much slower). – Alex Cohn Mar 03 '15 at 09:55
0

I have an Asus Zenfone 5 (which uses the x86 ABI) and I was having the same problem. Apparently the problem was with the OpenCV 2.x versions. Start using the OpenCV 3.x version and the problem is going to be solved.

The OpenCV 3.x version has more ABI options, such as:

arm64v8a
arm
armv7a
mips
mips64
x86
x86-64

You can find the 3.x version here.

Hope it helped!

Geraldo Neto
  • 3,670
  • 1
  • 30
  • 33