Android NDK:没有找到JNI_OnLoad ...跳过init:但是有JNI_OnLoad

时间:2014-06-15 20:28:04

标签: java android android-ndk java-native-interface

我再次问这个问题,因为我必须这样做。

运行基于NDK的应用程序时出现此错误。

   D dalvikvm:在/data/app-lib/com.venky-1/libme.so 0xa5082228中找不到JNI_OnLoad,跳过init   W dalvikvm:找不到原生Lcom / venky / Home的实现; .getPermission :( Landroid / app / Activity;)我

我经历过

  1. No JNI_OnLoad found in ... skipping init
  2. No JNI_OnLoad found skipping init > Application shutdown
  3. No JNI_Onload() found and VM shutting down
  4. JNI_OnLoad not found
  5. 他们的问题是

    1. 他们没有使用JNI_OnLoad,因为他们使用了JNI特定的命名约定(例如Java_com_venky_Home_start())。因此,这个消息没有意义,因为有另一种选择。
    2. 他们使用的是C ++,并且函数名称是mangling。
    3. 我的情况完全不同。在我的情况下,上述两个都是无效的。我正在使用C文件。所以没有破坏。而且我没有使用JNI类型的函数名称。我使用JNI_OnLoad手动注册函数。 因此,我的结论是“找不到实现”是由于应用程序以某种方式无法找到JNI_OnLoad。但为什么?它存在于C文件中。

      相关的代码部分如下。请询问您是否需要更多。

        

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

1 个答案:

答案 0 :(得分:2)

在@AlexCohn的帮助下,我发现了我的错误。这是多么愚蠢的错误。

  

JNI / Android.mk

  include $(CLEAR_VARS)
  LOCAL_MODULE := me
- LOCAL_SRC_FILE := me.c
+ LOCAL_SRC_FILES := me.c
  include $(BUILD_SHARED_LIBRARY)

因此,me.c没有编译。因此它不包含在构建的共享库中。我至少浪费了几个小时。