2

Update : I managed to pack *.so files with final apk, simply appending this to build.gradle :

    tasks.withType(com.android.build.gradle.tasks.PackageApplication) {
        pkgTask -> pkgTask.jniDir new File(projectDir, 'src/main/libs')
    }

But now the native function is not being called.

code of native.c

    #include <jni.h>
    #include <string.h>
    #include <android/log.h>

    JNIEXPORT jstring JNICALL Java_com_myndkapp_mybullet_MainActivity_helloLog(JNIEnv * env, jobject this) {
        __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", "Check string you received in the Activity");
        return (*env)->NewStringUTF(env, "Hello from Native code :)");
    }

Snippet from MainActivity.java :

    .
    ..
    static {
            System.loadLibrary("myfndk");
        }
    private native String helloLog();
    .
    ..

Some traces of ADB log are here :

    11-18 16:53:43.261    3469-3469/? D/PackageAddedReceiver﹕ package added com.myndkapp.mybullet
    11-18 16:53:43.856    2963-3214/? V/SmartFaceService - 3rd party pause﹕ onReceive [android.intent.action.ACTIVITY_STATE/com.myndkapp.mybullet/create]
    11-18 16:53:43.886    2823-2823/? D/dalvikvm﹕ Trying to load lib /data/app-lib/com.myndkapp.mybullet-1/libmyfndk.so 0x42a99270
    11-18 16:53:43.886    2823-2823/? D/dalvikvm﹕ Added shared lib /data/app-lib/com.myndkapp.mybullet-1/libmyfndk.so 0x42a99270
    11-18 16:53:43.886    2823-2823/? D/dalvikvm﹕ No JNI_OnLoad found in /data/app-lib/com.myndkapp.mybullet-1/libmyfndk.so 0x42a99270, skipping init
    11-18 16:53:50.596    2823-2823/? W/dalvikvm﹕ No implementation found for native Lcom/myndkapp/mybullet/MainActivity;.helloLog:()Ljava/lang/String;
    11-18 16:53:50.606    2823-2823/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: Native method not found:         com.myndkapp.mybullet.MainActivity.helloLog:()Ljava/lang/String;
        at com.myndkapp.mybullet.MainActivity.helloLog(Native Method)
        at com.myndkapp.mybullet.MainActivity.access$000(MainActivity.java:15)
        at com.myndkapp.mybullet.MainActivity$1.onClick(MainActivity.java:35)
        at android.view.View.performClick(View.java:4475)
        at android.view.View$PerformClick.run(View.java:18786)
        at android.os.Handler.handleCallback(Handler.java:730)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5419)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
        at dalvik.system.NativeStart.main(Native Method)
    11-18 16:53:50.691    2963-3214/? V/SmartFaceService - 3rd party pause﹕ onReceive [android.intent.action.ACTIVITY_STATE/com.myndkapp.mybullet/pause]
    11-18 16:53:50.696    2963-3043/? D/CrashAnrDetector﹕ processName: com.myndkapp.mybullet
    11-18 16:53:50.696    2963-3043/? D/CrashAnrDetector﹕ broadcastEvent : com.myndkapp.mybullet data_app_crash
    11-18 16:54:05.781    2963-3449/? I/ActivityManager﹕ Process com.myndkapp.mybullet (pid 2823) (adj 9) has died.

I am trying to build an android NDK app using android-ndk-r9 in Android Studio 0.3.5 132.910074 on Fedora 19 x86_64.

It look's like libmyfndk.so is not added to the final apk file. I confirmed this by viewing contents of apk file. When I run this test app on my Galaxy S4 (Jelly Bean 4.3) it throws error.

    11-17 19:03:28.816  26472-26472/com.myndkapp.mybullet E/AndroidRuntime﹕ 
    FATAL EXCEPTION: main
    java.lang.UnsatisfiedLinkError: Couldn't load myfndk from loader 
    dalvik.system.PathClassLoader[dexPath=/data/app/com.myndkapp.mybullet-1.apk,
    libraryPath=/data/app-lib/com.myndkapp.mybullet-1]: findLibrary returned null

I've looked on to solutions here:

1.) https://groups.google.com/forum/#!msg/adt-dev/xj51eCWwhFw/pfhvCoquPysJ

2.) https://groups.google.com/forum/?fromgroups#!searchin/adt-dev/so/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J

3.) Android studio, gradle and NDK

3.1) https://stackoverflow.com/a/16790675/1673000 (This worked for me)

4.) https://github.com/OnlyInAmerica/Android-JNI-Gradle

5.) Include .so library in apk in android studio

None of these seems to work.

This is my build-gradle file's content

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

    repositories {
        mavenCentral()
    }

    android {
        compileSdkVersion 18
        buildToolsVersion '19.0.0'

        defaultConfig {
            minSdkVersion 10
            targetSdkVersion 19
        }
    }

    dependencies {
        compile 'com.android.support:appcompat-v7:+'
    }

Any hints, why the Native function is not being called ?

Community
  • 1
  • 1
Manmohan Bishnoi
  • 791
  • 13
  • 37
  • did you load the library at runtime with System.load? Is your file copied in the right abi subfolder inside libs? – MLProgrammer-CiM Nov 18 '13 at 12:25
  • I load the library in MainActivity like this `static {System.loadLibrary("myfndk");}` and `libmyfndk.so` file is here `src/main/libs/armeabi/` – Manmohan Bishnoi Nov 18 '13 at 12:29
  • maybe your testing unit uses armeabi-v7a? – MLProgrammer-CiM Nov 18 '13 at 12:40
  • **Android.mk** has this line `APP_ABI := all`, so I guess that should not be a problem. – Manmohan Bishnoi Nov 18 '13 at 12:43
  • Don't guess, change it to armeabi-v7a manually, rebuild and make sure that's the one on your app. APP_ABI usually goes in Application.mk too, not sure if it is applied when called from Android.mk – MLProgrammer-CiM Nov 18 '13 at 12:45
  • I tried that just now, rebuild my library using `ndk-build`, rebuild apk. Still the same error. – Manmohan Bishnoi Nov 18 '13 at 12:51
  • http://stackoverflow.com/a/10098466/1266326 confirming APP_ABI must go in Application.mk – MLProgrammer-CiM Nov 18 '13 at 12:51
  • 1
    It is NOT an ABI problem, as the log indicates the library found and loaded. – Chris Stratton Nov 18 '13 at 12:57
  • "FATAL EXCEPTION: main java.lang.UnsatisfiedLinkError: Couldn't load myfndk from loader" that's on the question so I assumed it was. – MLProgrammer-CiM Nov 18 '13 at 12:58
  • Does he have an autogenerated header file? – MLProgrammer-CiM Nov 18 '13 at 13:01
  • @EfEs It's `Native method not found` error that I am not able to get rid of. – Manmohan Bishnoi Nov 18 '13 at 13:03
  • Have you used javah to generate the correct header? – MLProgrammer-CiM Nov 18 '13 at 13:05
  • No, I didn't use that. – Manmohan Bishnoi Nov 18 '13 at 13:08
  • But you do have a correct header? – MLProgrammer-CiM Nov 18 '13 at 13:09
  • I just have 'Android.mk', 'Application.mk' and 'native.c' files in 'jni' directory. I followed this tutorial http://mobile.tutsplus.com/tutorials/android/ndk-tutorial/ – Manmohan Bishnoi Nov 18 '13 at 13:11
  • It would be useful to extract the .so from the .apk with zip tools and use the ndk objdump on it to verify that the function is actually inside. Sometimes changes don't propagate and when you are testing current code you actually are testing stale build artifacts. Also, for completeness please post the java declaration of the native method. – Chris Stratton Nov 18 '13 at 15:28
  • @ChrisStratton here's the objdump for libmyfndk.so : http://pastebin.com/GPt5QPDy , Also added java declaration of the function in the original question. – Manmohan Bishnoi Nov 18 '13 at 16:16
  • If that's all of it, you appear to have an effectively empty library or at least one without any useful dynamic symbols. Are you using the nkd build system properly? If you for example build the hello-jni sample using ndk-build, you'll find the Java_ functions listed in the objdump of that .so file. – Chris Stratton Nov 18 '13 at 16:21
  • Here's how I build it http://pastebin.com/dCGevjif , I execute this in project directory and libraries are generated as shown. – Manmohan Bishnoi Nov 18 '13 at 16:25
  • 2
    It would nonetheless appear something is wrong with your build. Does `grep` find any occurrence of the Java_ function name in the library file? In the intermediate objects? Try building hello-jni strictly according to the instructions for sake of comparison. – Chris Stratton Nov 18 '13 at 16:26
  • I built hello-jni then it's obj-dump gives this http://pastebin.com/XaNgi2Xy so my NDK is setup properly. – Manmohan Bishnoi Nov 18 '13 at 16:32
  • 1
    Well, now you just have to figure out where the difference is - why you get a function in one library and none in the other. One thing that can help is to transform a copy of the hello-jni project into what you need, one step at a time, seeing where it breaks. – Chris Stratton Nov 18 '13 at 16:44
  • Thanks, I'll carry out postmortem of my project and see what is causing this. Thanks a lot for guiding in the right direction. – Manmohan Bishnoi Nov 18 '13 at 16:46

1 Answers1

1

It was not placing the code of native.c in libmyfndk.so, and that because of a missing '=' in my Android.mk in this line :

LOCAL_SRC_FILES : native.c

Changing the above line to LOCAL_SRC_FILES := native.c, resolved this issue.

Manmohan Bishnoi
  • 791
  • 13
  • 37