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);
.......
}
我不知道为什么会这样,所以仍然感谢对此的解释。否则,希望这对某人有帮助
我发现了很多类似的问题,但其中 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);
.......
}
我不知道为什么会这样,所以仍然感谢对此的解释。否则,希望这对某人有帮助