Android NDK : No JNI_OnLoad found in ... skipping init : But there is JNI_OnLoad
By help of @AlexCohn, I found out my error. And what a silly stupid error it was.
jni/Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE := me
- LOCAL_SRC_FILE := me.c
+ LOCAL_SRC_FILES := me.c
include $(BUILD_SHARED_LIBRARY)
Because of this, me.c wasn't compiling. Hence it was not included in the built shared library. I had wasted a couple of hours on this at least.
Comments
-
venky almost 2 years
I am asking this question again because I have to.
I am having this error while running a NDK based application.
D dalvikvm: No JNI_OnLoad found in /data/app-lib/com.venky-1/libme.so 0xa5082228, skipping init W dalvikvm: No implementation found for native Lcom/venky/Home;.getPermission:(Landroid/app/Activity;)I
I have been through
- No JNI_OnLoad found in ... skipping init
- No JNI_OnLoad found skipping init > Application shutdown
- No JNI_Onload() found and VM shutting down
- JNI_OnLoad not found
Their problem was either
- They were not using JNI_OnLoad because they used JNI specific naming convention (For example Java_com_venky_Home_start()). Hence this message has no significance as there is an alternative.
- They were using C++ and there was function name mangling.
My case is entirely different. And the above two are invalid in my case. I am using C files. So no mangling. And I am not using JNI kind of function names. I am manually registering the functions using JNI_OnLoad. Hence my conclusion is that "No Implementation Found" is due to the fact that the application is somehow unable to find JNI_OnLoad. But why? It is present in the C file.
Relevant sections of code are as follows. Please ask if you need more.
jni/Android.mk
include $(CLEAR_VARS) LOCAL_MODULE := me LOCAL_SRC_FILE := me.c include $(BUILD_SHARED_LIBRARY)
com/venky/Home.java
package com.venky; import android.app.Activity; import android.os.Bundle; public class Home extends Activity { static { System.loadLibrary("me"); } private native int getPermission(Activity activity); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.home); getPermission(this); } }
jni/me.c
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <android/log.h> #include <jni.h> #define LOG_TAG "com.venky.me" #define LOG_D(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define LOG_F(fn_name) __android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, "Called : " fn_name ) static JavaVM *java_vm; jint JNI_OnLoad(JavaVM *vm, void *reserved) { LOG_F ("JNI_OnLoad"); java_vm = vm; // Get JNI Env for all function calls JNIEnv* env; if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) { LOG_D ("GetEnv failed."); return -1; } // Find the class calling native function jclass NativeUsb = (*env)->FindClass(env, "com/venky/Home"); if (class_home == NULL) { LOG_D ("FindClass failed : No class found."); return -1; } // Register native method for getUsbPermission JNINativeMethod nm[1] = { { "getPermission", "(Landroid/app/Activity;)I", get_permission} }; if ((*env)->RegisterNatives(env, NativeUsb, nm , 1)) { LOG_D ("RegisterNatives Failed."); return -1; } return JNI_VERSION_1_6; } int get_permission (jobject activity) { LOG_F ("get_usb_permission"); }