artem
artem

Reputation: 16798

Android NDK app failed to load library

My native library code:

#include <string.h>
#include <jni.h>

jstring Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
  return env->NewStringUTF("Hello from native code!");
}

Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE    := libpacman
LOCAL_SRC_FILES := main.cpp
LOCAL_CFLAGS := -DANDROID_NDK
LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

MainActivity.java:

public class MainActivity extends Activity {

    static {
        System.loadLibrary("libpacman");
    }

    // declare the native code function - must match main.cpp
    private native String invokeNativeFunction();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // this is where we call the native code
        String hello = invokeNativeFunction();

        new AlertDialog.Builder(this).setMessage(hello).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

Library is compiled successfully and libpacman.so is in libs/armeabi directory, but logcat says:

E/AndroidRuntime(13060): FATAL EXCEPTION: main
E/AndroidRuntime(13060): java.lang.ExceptionInInitializerError
E/AndroidRuntime(13060):    at java.lang.Class.newInstanceImpl(Native Method)
E/AndroidRuntime(13060):    at java.lang.Class.newInstance(Class.java:1319)
E/AndroidRuntime(13060):    at android.app.Instrumentation.newActivity(Instrumentation.java:1053)
E/AndroidRuntime(13060):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1974)
E/AndroidRuntime(13060):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
E/AndroidRuntime(13060):    at android.app.ActivityThread.access$600(ActivityThread.java:130)
E/AndroidRuntime(13060):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
E/AndroidRuntime(13060):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(13060):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(13060):    at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime(13060):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(13060):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(13060):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime(13060):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime(13060):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(13060): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load libpacman: findLibrary returned null
E/AndroidRuntime(13060):    at java.lang.Runtime.loadLibrary(Runtime.java:365)
E/AndroidRuntime(13060):    at java.lang.System.loadLibrary(System.java:535)
E/AndroidRuntime(13060):    at com.example.pacman.MainActivity.<clinit>(MainActivity.java:11)
E/AndroidRuntime(13060):    ... 15 more
W/ActivityManager(  315):   Force finishing activity com.example.pacman/.MainActivity

So, system can not find the library, but if unzip APK file - it's in the lib directory. Why not in the libs?

Edit. OK, now i fixed the package names:

jstring Java_com_wiagames_pacman_MainActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
  return env->NewStringUTF("Hello from native code!");
}

Android.mk and MainActivity.java are the same. Package is com.wiagames.pacman everywhere. But I'm getting error:

E/AndroidRuntime(23084): FATAL EXCEPTION: main
E/AndroidRuntime(23084): java.lang.ExceptionInInitializerError
E/AndroidRuntime(23084):    at java.lang.Class.newInstanceImpl(Native Method)
E/AndroidRuntime(23084):    at java.lang.Class.newInstance(Class.java:1319)
E/AndroidRuntime(23084):    at android.app.Instrumentation.newActivity(Instrumentation.java:1053)
E/AndroidRuntime(23084):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1974)
E/AndroidRuntime(23084):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
E/AndroidRuntime(23084):    at android.app.ActivityThread.access$600(ActivityThread.java:130)
E/AndroidRuntime(23084):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
E/AndroidRuntime(23084):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(23084):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(23084):    at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime(23084):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23084):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(23084):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime(23084):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime(23084):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(23084): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load libpacman: findLibrary returned null
E/AndroidRuntime(23084):    at java.lang.Runtime.loadLibrary(Runtime.java:365)
E/AndroidRuntime(23084):    at java.lang.System.loadLibrary(System.java:535)
E/AndroidRuntime(23084):    at com.wiagames.pacman.MainActivity.<clinit>(MainActivity.java:13)
E/AndroidRuntime(23084):    ... 15 more
W/ActivityManager(  315):   Force finishing activity com.wiagames.pacman/.MainActivity

Upvotes: 3

Views: 10190

Answers (3)

kelnos
kelnos

Reputation: 878

The library name you pass to System.loadLibrary() should simply be pacman, not libpacman.

Upvotes: 4

Pavel Zdenek
Pavel Zdenek

Reputation: 7293

Your classname is visibly not NdkFooActivity. Also make sure that your java package is com.mindtherobot.samples.ndkfoo. The name of native function and the Java context from which are you calling it must be in sync. Normally you would produce the native header with javah -jni which works on the already compiled class, not the java sources.

Upvotes: 4

Basbous
Basbous

Reputation: 3925

According to my experiences in NDK,the path of your class in Android App must be the same as

Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction



Java_com_mindtherobot_samples_ndkfoo [package name]
NdkFooActivity [activity or class name]
invokeNativeFunction [function name]

Upvotes: 2

Related Questions