2

I'm trying to make my 64-bit Android device compile local 32-Bit jniLibs which so far is going OK but I sort of ran into a snag.

I have been researching exactly what went wrong for a couple days and puttering around here and there but this is the current error I am getting:

java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/org.opencv.engine-1/lib/arm64/libopencv_java3.so" is 64-bit instead of 32-bit

Which is actually promising considering the 64-bit device recognizes that it is supposed to be compiling 32-bit architecture which I have achieved by omitting arm64, x86_64, and mips64 as according to this answer: Android JNI: 32-bit compatability with 64-bit devices?

The initialization code I use is:

 OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);

So my questions are as follows:

  1. Is there some way to edit the Abi included in OpenCV 3.0 to recognize that I only desire the 32-bit framework to be loaded after the fact that the device recognizes it is supposed to only be searching for 32-bit framework?

  2. Would the feature loss be worse having reverted to OpenCV 2.4.11 (I am aware that the native camera doesn't work properly on new framework)

  3. If the Abi answer is correct will it correspond to the gradle build at the app level, the project level, or some other (likely opencvlib) level? That part went over my head reading another answer.

Community
  • 1
  • 1
KoalaKoalified
  • 687
  • 4
  • 15
  • I believe that this is just one of the reasons why when using native OpenCV with private JNI libraries, [static linking](http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#application-development-with-static-initialization) is prefferable. – Alex Cohn Dec 22 '15 at 12:19
  • I can get it to load properly when I include the 64-bit armeabi-v8a/arm64, but the project libs I'd like to use are all 32-bit. I also use Android Studio as an IDE but its not that much different: importing, generating a build.gradle, including jniLibs and their respective subdirs, referencing at a project level, and adding a module dependency EDIT: Also upon double checking, I'm not loading my custom libs yet and have only included (to my knowledge) the 32-bit opencv libs – KoalaKoalified Dec 22 '15 at 12:59
  • I don't think you can force `OpenCVLoader` with OpenCV Manager installed independently to choose 32-bit libs. – Alex Cohn Dec 22 '15 at 13:02
  • Perhaps I misunderstood what the OpenCVLoader actually does and should instantiate everything in a different way – KoalaKoalified Dec 22 '15 at 13:04
  • After a quick search I found the OpenCVLoader.initDebug() will only browse app jni files but it doesn't seem very stable in that if the files are not all included in some way or another I wind up with a ton of exceptions thrown... – KoalaKoalified Dec 22 '15 at 13:11
  • Perhaps I should simply be more dilligent but it would be nice if I could tell OpenCVs Abi to only interface with 32-bit libraries – KoalaKoalified Dec 22 '15 at 13:12
  • Yes it would be nice. You are welcome to open a request at the OpenCV website. – Alex Cohn Dec 22 '15 at 14:49
  • Alex & Koala -- I have this same problem, but on top of that my instinct would be to use static linking rather than have my users install OpenCV Manager as well. Any idea why the OpenCV folks say the static linking approach is "deprecated"? – TonyC Jan 04 '16 at 09:54
  • Could be because it doesn't account for OpenCV updates by the OpenCVManager. If you keep an eye out for whether or not your application works under new versions, I think it can still be used. – KoalaKoalified Jan 05 '16 at 18:30

1 Answers1

0

I got it installing correctly by removing all 64 bit libraries and keeping all 32-bit libraries in the jniLibs folder under app -> src -> main but instead of calling the OpenCVLoader to load the library, I just did a call like the following:

   if (!OpenCVLoader.initDebug()) {
        Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
    } 
    else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }

Which detects if your application already locally contains the files OpenCVManager would otherwise handle. Another advantage of including these files in your jniLibs folder is the prompt to download OpenCVManager no longer appears and your app still has the functionality as though the user has.

I guess the quick guide to implement everything locally would be:

  1. File -> New -> Import Module -> Navigate to OpenCV 3.1 -> sdk -> java

  2. Edit the build.gradle of the new OpenCV module to match that of your application's build.gradle

  3. Right click on your project's app folder -> Open Module Settings -> Dependencies -> + -> Module Dependency -> Select your imported OpenCV Version

  4. Create a folder under app -> src -> main called jniLibs (as it is called by default but can be edited through your build.gradle file)

  5. Navigate to your OpenCV directory -> sdk -> native -> libs -> Copy and paste armeabi, armeabi-v7a, mips to your newly created jniLibs folder

  6. Then initialize using the code sample above and OpenCV should be loaded locally.

KoalaKoalified
  • 687
  • 4
  • 15