Android force OpenCV 3.0 to load as a 32-bit library

2k Views Asked by At

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.

1

There are 1 best solutions below

2
On

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.