Android NDK unsatisfiedLinkError(仅限 android <4.3)

Android NDK unsatisfiedLinkError (only on android <4.3)

我发现了很多类似的问题,但其中 none 似乎与此完全相同并且 none 的建议有效。

我编写了一个 Android 应用程序,它使用 NDK 和 OpenCv 进行一些图像处理。我所有的算法都是用 C++ 编写的。我正在使用 android studio、gradle 2.2.2 和实验性 gradle 插件 0.8.3.

在 HTC M8、Galaxy S5 和 LG V10 上进行测试时,一切正常。但是当尝试在 Samsung Galaxy S2 或 Galaxy Ace3 上 运行 时,启动时会出现以下错误:

java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1892]: 1835 could not load needed library 'libopencv_java3.so for 'libnative.so' (load_library[1094]: Library 'libopencv_java3.so' not found)

在我的 MainActivity.java 中,我加载了库:

static {
    System.loadLibrary("native")
}

并让我的 BaseLoaderCallback 如下:

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS: {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
            }
            break;
            default: {
                super.onManagerConnected(status);
            }
            break;
        }
    }
};

此外,在 onCreate 中进行 OpenCv 初始化:

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

我的build.gradle:

buildscript {
repositories {
    mavenCentral()
}
dependencies {
    classpath 'com.android.tools.build:gradle:2.2.2'
}
}

apply plugin: 'com.android.model.application'

model {
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig.with {
        applicationId "com.me.myapp"
        minSdkVersion.apiLevel 15
        targetSdkVersion.apiLevel 23
        versionCode 9
        versionName "1.5.3"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    ndk {
        moduleName = "native"
        cppFlags.add("-I${file(getOpenCVDir())}".toString())
        cppFlags.add("-frtti")
        cppFlags.add("-fexceptions")
        ldLibs.addAll(["log", "opencv_java3"])
        stl = "gnustl_static"
    }
}
    buildTypes {
        release {

            //minifyEnabled false
            //proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    android.productFlavors {
        // for detailed abiFilter descriptions, refer to "Supported ABIs" @
        // https://developer.android.com/ndk/guides/abis.html#sa
        create("fat") {
            ndk.abiFilters.add("armeabi")
            ndk.abiFilters.add("armeabi-v7a")
            ndk.abiFilters.add("mips")
            ndk.abiFilters.add("x86")
            ndk.abiFilters.add("arm64_v8a")
            ndk.ldFlags.add("-L${file('src/main/jniLibs/armeabi')}".toString())
            ndk.ldFlags.add("-L${file('src/main/jniLibs/armeabi-v7a')}".toString())
            ndk.ldFlags.add("-L${file('src/main/jniLibs/mips')}".toString())
            ndk.ldFlags.add("-L${file('src/main/jniLibs/arm64_v8a')}".toString())
            ndk.ldFlags.add("-L${file('src/main/jniLibs/x86')}".toString())
        }
    }
}

def getOpenCVDir() {
    Properties properties = new Properties()
    properties.load(new File(rootDir.absolutePath + "/local.properties").newDataInputStream())
    def externalModuleDir = properties.getProperty('opencv.dir', null)
    if (externalModuleDir == null) {
        throw new GradleException(
            "OpenCV location not found. Define location with opencv.dir in the local.properties file!")
}
    return externalModuleDir
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.2.1'
testCompile 'junit:junit:4.12'
compile project(':openCVLibrary300')
compile 'com.google.android.gms:play-services-appindexing:9.0.0'
}

apply plugin: 'com.google.gms.google-services'

我在 app/src/main/jniLibs 中还有以下带有 opencv 库的文件夹:

arm64-v8a
armeabi
armeabi-v7a
mips
mips64
x64
x86_64

一开始我以为是ABI的问题,但是好像M8和S2都是armeabi-v7a。我还检查了编译后的 apk 的 lib 文件夹,每个选择的 abi 文件夹都存在并且里面有 libopencv_java3.so 和 libnative.so 文件)。是否存在一些我不知道的较低 android 版本 (<4.4) 的不兼容性?

万一其他人遇到这个问题,这就是为我解决的方法:

我改变了

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

static {
    if(!OpenCVLoader.initDebug())
         // Handle Error
    }else
    {
         System.loadLibrary("native");
    }
}

此外,我刚刚将对 mLoaderCallback.onManagerConnected 的调用添加到 OnResume:

public void onResume() {
    super.onResume();
    mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    .......
}

我不知道为什么会这样,所以仍然感谢对此的解释。否则,希望这对某人有帮助