android 中未找到本机代码的实现
No implementation found for native code in android
现在我在 android 中使用 ffmpeg java 库。我想直接在我的应用程序中使用它,所以我导入了这个库。但我有一个问题。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.softcode.kihnoplay, PID: 15313
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String androidFfmpeg.ArmArchHelper.cpuArchFromJNI() (tried Java_androidFfmpeg_ArmArchHelper_cpuArchFromJNI and Java_androidFfmpeg_ArmArchHelper_cpuArchFromJNI__)
at androidFfmpeg.ArmArchHelper.cpuArchFromJNI(Native Method)
at androidFfmpeg.CpuArchHelper.getCpuArch(CpuArchHelper.java:16)
at androidFfmpeg.FFmpeg.loadBinary(FFmpeg.java:40)
at com.softcode.tablet.Mp3Concat_Thread.startThread(Mp3Concat_Thread.java:90)
at com.softcode.tablet.Mp3Concat_Thread.<init>(Mp3Concat_Thread.java:54)
at com.softcode.phone.record.view.RecordActivity.onCreate(RecordActivity.java:182)
at android.app.Activity.performCreate(Activity.java:6955)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
我不知道为什么会出现这个错误。
我的目录树是
和c文件代码。
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <cpu-features.h>
jstring
Java_androidFfmpeg_ArmArchHelper_cpuArchFromJNI(JNIEnv* env, jobject obj)
{
char arch_info[11] = "";
if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) {
strcpy(arch_info, "ARM");
uint64_t cpuFeatures = android_getCpuFeatures();
if ((cpuFeatures & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0) {
strcat(arch_info, " v7");
if((cpuFeatures & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {
strcat(arch_info, "-neon");
}
}
}
return (*env)->NewStringUTF(env, arch_info);
}
这是成绩(应用)
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "com.softcode.kihnoplay"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.00"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
abiFilters "armeabi", "armeabi-v7a","x86"
}
aaptOptions
{
cruncherEnabled = false
}
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = [] //important!!!! disable automatic ndk-build call
}
我不知道为什么会出现这个错误。如果您知道这个问题,请告诉我。谢谢!
我猜你是用clang++编译c源码吧?如果为真,请尝试将您的文件名更改为 armArch.cpp 并将关键字 extern 添加到您的 C 头文件和源文件中。例如
#ifdef __cplusplus
extern "C" {
#endif
// your function declarations or implementations.
#ifdef __cplusplus
}
#endif
此外,我想建议使用 externalNativeBuild 和 cmake 块而不是旧的 ndk 块,这不是 Android 本机构建的现代约定。例如。
android {
//....
defaultConfig {
applicationId "com.softcode.kihnoplay"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.00"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
}
buildTypes {
release {
//....
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
Android NDK 已弃用 armeabi,您实际上不需要包含此 ABI 是您的 abiFilters 设置。 ABI 'armeabi-v7a'、'arm64-v8a'、'x86'、'x86_64' 足以支持几乎所有当前的 Android 设备,因为以及模拟器。
您可以从 https://arophix.com/2017/12/17/andoid-jni-summary/ 找到全面的 JNI 教程
和来自 https://github.com/russell-shizhen/JniExample
的示例 JNI 项目
现在我在 android 中使用 ffmpeg java 库。我想直接在我的应用程序中使用它,所以我导入了这个库。但我有一个问题。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.softcode.kihnoplay, PID: 15313
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String androidFfmpeg.ArmArchHelper.cpuArchFromJNI() (tried Java_androidFfmpeg_ArmArchHelper_cpuArchFromJNI and Java_androidFfmpeg_ArmArchHelper_cpuArchFromJNI__)
at androidFfmpeg.ArmArchHelper.cpuArchFromJNI(Native Method)
at androidFfmpeg.CpuArchHelper.getCpuArch(CpuArchHelper.java:16)
at androidFfmpeg.FFmpeg.loadBinary(FFmpeg.java:40)
at com.softcode.tablet.Mp3Concat_Thread.startThread(Mp3Concat_Thread.java:90)
at com.softcode.tablet.Mp3Concat_Thread.<init>(Mp3Concat_Thread.java:54)
at com.softcode.phone.record.view.RecordActivity.onCreate(RecordActivity.java:182)
at android.app.Activity.performCreate(Activity.java:6955)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2927)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3045)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1642)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
我不知道为什么会出现这个错误。
我的目录树是
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <cpu-features.h>
jstring
Java_androidFfmpeg_ArmArchHelper_cpuArchFromJNI(JNIEnv* env, jobject obj)
{
char arch_info[11] = "";
if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) {
strcpy(arch_info, "ARM");
uint64_t cpuFeatures = android_getCpuFeatures();
if ((cpuFeatures & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0) {
strcat(arch_info, " v7");
if((cpuFeatures & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {
strcat(arch_info, "-neon");
}
}
}
return (*env)->NewStringUTF(env, arch_info);
}
这是成绩(应用)
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "com.softcode.kihnoplay"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.00"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
abiFilters "armeabi", "armeabi-v7a","x86"
}
aaptOptions
{
cruncherEnabled = false
}
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = [] //important!!!! disable automatic ndk-build call
}
我不知道为什么会出现这个错误。如果您知道这个问题,请告诉我。谢谢!
我猜你是用clang++编译c源码吧?如果为真,请尝试将您的文件名更改为 armArch.cpp 并将关键字 extern 添加到您的 C 头文件和源文件中。例如
#ifdef __cplusplus
extern "C" {
#endif
// your function declarations or implementations.
#ifdef __cplusplus
}
#endif
此外,我想建议使用 externalNativeBuild 和 cmake 块而不是旧的 ndk 块,这不是 Android 本机构建的现代约定。例如。
android {
//....
defaultConfig {
applicationId "com.softcode.kihnoplay"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.00"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
}
buildTypes {
release {
//....
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
Android NDK 已弃用 armeabi,您实际上不需要包含此 ABI 是您的 abiFilters 设置。 ABI 'armeabi-v7a'、'arm64-v8a'、'x86'、'x86_64' 足以支持几乎所有当前的 Android 设备,因为以及模拟器。
您可以从 https://arophix.com/2017/12/17/andoid-jni-summary/ 找到全面的 JNI 教程 和来自 https://github.com/russell-shizhen/JniExample
的示例 JNI 项目