3

Now Im using ffmpeg java library in android. I want to use it directly in my app, So Im inporting this library. But I have a problem with it.

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)

I don't know why this error is occurring.

My directory tree is

enter image description here and c file code.

#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);
}

And this is a grade(app)

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
}

I don't know why this error is occurring. If you know this problem please let me know. Thanks you!

Junburg
  • 350
  • 5
  • 23
  • Possible duplicate of [Android NDK C++ JNI (no implementation found for native...)](https://stackoverflow.com/questions/2197889/android-ndk-c-jni-no-implementation-found-for-native) – Vikasdeep Singh Jul 02 '18 at 04:48
  • @VicJordan Thank you... but It's not works. – Junburg Jul 02 '18 at 05:16
  • `externalNativeBuild {ndkBuild {path 'src/main/jni/Android.mk'}}` add this block in your gradle file i hope it will help you! – Hardik Vasani Jul 02 '18 at 05:20

1 Answers1

3

I guess you are using a clang++ compiling c source code, right? If true, try to change your file name to be armArch.cpp and add keyword extern into your C header and source files. e.g.

#ifdef __cplusplus
extern "C" {
#endif

// your function declarations or implementations. 

#ifdef __cplusplus
}
#endif

Also, i would like to suggest use externalNativeBuild and cmake block rather than the older ndk block which is not the modern convention for Android native builds. E.g.

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 has deprecated armeabi, you don't actually need to include this ABI is your abiFilters setting. ABIs 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' will be enough for supporting almost all the current Android devices as well as emulators.

You can find a comprehensive JNI tutorial from https://arophix.com/2017/12/17/andoid-jni-summary/ and a sample JNI project from https://github.com/russell-shizhen/JniExample

shizhen
  • 12,251
  • 9
  • 52
  • 88
  • Maybe it's not c++. I just use this library https://github.com/WritingMinds/ffmpeg-android-java. I just want to use it with editing some codes. – Junburg Jul 02 '18 at 06:24
  • I did a quick check on the project ffmpeg-android-java, it is an old Android Studio project which has many older plugins and deprecated gradle closures used. For the native build part, it is actually only one simple file inside which is to check the CPU architecture. – shizhen Jul 02 '18 at 08:24
  • Probably for your case, using the latest native build pattern, i.e. externalNativeBuild and cmake will be easier. – shizhen Jul 02 '18 at 08:30
  • Oh, Really appreciate for your favor. So, What I have to do is doing your answer? – Junburg Jul 02 '18 at 08:39
  • // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } changes classpath 'com.android.tools.build:gradle:2.3.3' – shizhen Jul 02 '18 at 09:22
  • also commented out inside build.gradle under FFmpegAndroid //apply plugin: 'com.github.dcendents.android-maven'. Then remove //install { } block, open this project with latest android studio. Then run "CpuArchHelperTest", you will have this test passed. – shizhen Jul 02 '18 at 09:25