JNI调用报错:找不到ImageStabilizer.hello()实现,请求技术协助
java.lang.UnsatisfiedLinkError for com.swoop.utility.ImageStabilizer.hello() Let's troubleshoot that pesky UnsatisfiedLinkError together—this usually boils down to mismatched JNI signatures, misconfigured build tools, or missing library references. Let's walk through each possible issue and fix them step by step:
1. Double-Check JNI Method Signature & extern "C" Wrapping
Your main.cpp has the right method name (Java_com_swoop_utility_ImageStabilizer_hello) and wraps it in extern "C"—that's crucial to prevent C++ name mangling, which would break the JVM's ability to find the method. But let's confirm a couple things:
- Verify the header file: Make sure
com_swoop_utility_ImageStabilizer.hexists in your JNI source directory. You can generate this automatically usingjavac -h(newer JDKs) orjavahfrom your compiledImageStabilizerclass to avoid typos in the method signature. - Check parameters: Since
hello()is a non-static native method, the second parameter must bejobject obj(the instance ofImageStabilizer). Your code looks correct here, but even a tiny mismatch (like usingjclassinstead) will trigger this error.
2. Fix Gradle's NDK Build Configuration
Your current Gradle setup disables the default JNI source directory but doesn't tell Gradle to use your Android.mk script. Update your build.gradle to explicitly use ndk-build:
apply plugin: 'com.android.application' android { compileSdkVersion 26 defaultConfig { applicationId "com.swoop" minSdkVersion 16 targetSdkVersion 26 versionCode 1 versionName "1.0" vectorDrawables.useSupportLibrary = true multiDexEnabled true ndk { moduleName "ImageStabilizer" } // Add this to point Gradle to your Android.mk externalNativeBuild { ndkBuild { path "src/main/jni/Android.mk" // Adjust this path if your Android.mk is elsewhere } } } // Keep this to ignore default JNI dir (since we're using custom build) sourceSets.main.jni.srcDirs = [] // Tell Gradle where to find compiled .so files sourceSets.main.jniLibs.srcDirs = ['src/main/libs'] buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } repositories { maven { url "https://jitpack.io" } mavenCentral() } aaptOptions { cruncherEnabled = false } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation project(':libraries:opencv') }
This config ensures Gradle runs ndk-build with your custom script and looks for the compiled library in the right place.
3. Correct Paths in Android.mk
Your Android.mk has a small issue with include paths—let's fix that:
LOCAL_PATH := $(call my-dir) CVROOT := D:/Rajesh/Downloads/OpenCV-android-sdk/sdk/native/jni include $(CLEAR_VARS) OPENCV_INSTALL_MODULES:=on OPENCV_LIB_TYPE:=STATIC include $(CVROOT)/OpenCV.mk LOCAL_MODULE := ImageStabilizer // Add the current directory to include paths so the compiler finds your header LOCAL_C_INCLUDES += $(LOCAL_PATH) LOCAL_SRC_FILES += main.cpp LOCAL_CFLAGS += -std=c++11 -frtti -fexceptions -fopenmp -w LOCAL_LDLIBS += -llog -L$(SYSROOT)/usr/lib LOCAL_LDFLAGS += -fopenmp include $(BUILD_SHARED_LIBRARY)
LOCAL_C_INCLUDES += $(LOCAL_PATH)ensures the compiler findscom_swoop_utility_ImageStabilizer.hif it's in the same folder asmain.cpp.- Double-check that
CVROOTpoints to the correct OpenCV native JNI directory on your system—an invalid path here will break the build.
4. Validate Library Build & Loading
- Clean and rebuild: In Android Studio, run
Build > Clean ProjectthenBuild > Rebuild Projectto ensure all artifacts are generated fresh. - Check for .so files: Look for
libImageStabilizer.soinapp/build/intermediates/ndkBuild/debug/obj/local/<your-abi>/(e.g.,armeabi-v7a). If it's missing, yourAndroid.mkhas a build error—check the Build tab for logs. - Library loading order: Your static block in
ImageStabilizerloads the library correctly, but make sure no code callshello()before the class is initialized (e.g., from a static initializer in another class).
5. Guard Against ProGuard Obfuscation
Even with minifyEnabled false, ProGuard might still touch native methods. Add this rule to proguard-rules.pro to keep your native method names intact:
-keep class com.swoop.utility.ImageStabilizer { native <methods>; }
This prevents ProGuard from renaming methods, which would break the JNI link.
After applying these fixes, run your app again—this should resolve the UnsatisfiedLinkError and let your hello() method return the JNI greeting as expected.
内容的提问来源于stack exchange,提问作者Rajesh

