当前位置: 首页 > 面试题库 >

Android ndk:使用jni从c ++调用Java方法的问题

法景明
2023-03-14
问题内容

我尝试在Android NDK上工作,我的第一个测试不是很确定,我需要帮助,因为我看不到错误在哪里。

以下代码可以毫无问题地进行编译,但是当在模拟器上运行时,该程序将返回SIGSEGV信号,并且在logcat中不会显式写入任何错误。但是,将显示一条警告,指出未找到Java类。经过一天的研究,这个问题看起来一切正确。

这是我的Java代码:JNITestActivity.java

package com.test.jnitest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class JNITestActivity extends Activity {

    private static String LIB_NAME = "JNItest";

    static {
        System.loadLibrary(LIB_NAME);
    }

    public static native void javaCallJNI();

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

        Log.i("onCreate", "Native function begining");
        javaCallJNI();
        Log.i("onCreate", "Native function ending");
    }

    void callFromCPP() {
        Log.i("callFromCPP", "JNI can call JAVA !");
        return ;
    }

}

这是我的C ++代码:testjni.cpp

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

#define  LOG_TAG    "testjni"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

extern "C" {
    JNIEXPORT void JNICALL Java_com_test_jnitest_JNITestActivity_javaCallJNI(JNIEnv* env, jobject obj);
};

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
        return -1;

    LOGI("JNI INIT");

    return JNI_VERSION_1_6;
}

JNIEXPORT void JNICALL Java_com_test_jnitest_JNITestActivity_javaCallJNI(JNIEnv* env, jobject obj)
{
    LOGI("JNI work !");

    jclass clazz = env->FindClass("com/test/jnitest/JNITestActivity");
    if (clazz == 0) {
        LOGI("FindClass error");
        return;
    }
    jmethodID javamethod = env->GetMethodID(clazz, "callFromCPP", "()V");
    if (javamethod == 0) {
        LOGI("GetMethodID error");
        return;
    }
    env->CallVoidMethod(obj, javamethod);
}

这是我的Makefile:Android.mk

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

LOCAL_MODULE := libJNItest
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

LOCAL_SRC_FILES := \
         src/testjni.cpp

include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)

和logcat错误:

INFO/testjni(9387): JNI INIT
07-05 15:35:16.993: INFO/onCreate(9387): Native function begining
07-05 15:35:16.993: INFO/testjni(9387): JNI work !
07-05 15:35:17.003: WARN/dalvikvm(9387): JNI WARNING: can't call Lcom/test/jnitest/JNITestActivity;.callFromCPP on instance of Ljava/lang/Class;
07-05 15:35:17.003: INFO/dalvikvm(9387): "main" prio=5 tid=1 RUNNABLE
07-05 15:35:17.018: INFO/dalvikvm(9387):   | group="main" sCount=0 dsCount=0 obj=0x4001f1a8 self=0xce48
07-05 15:35:17.018: INFO/dalvikvm(9387):   | sysTid=9387 nice=0 sched=0/0 cgrp=default handle=-1345006528
07-05 15:35:17.023: INFO/dalvikvm(9387):   | schedstat=( 219631994 557413541 53 )
07-05 15:35:17.023: INFO/dalvikvm(9387):   at com.test.jnitest.JNITestActivity.javaCallJNI(Native Method)
07-05 15:35:17.023: INFO/dalvikvm(9387):   at com.test.jnitest.JNITestActivity.onCreate(JNITestActivity.java:23)
07-05 15:35:17.023: INFO/dalvikvm(9387):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-05 15:35:17.048: INFO/dalvikvm(9387):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread.access$1500(ActivityThread.java:117)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.os.Handler.dispatchMessage(Handler.java:99)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.os.Looper.loop(Looper.java:123)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at android.app.ActivityThread.main(ActivityThread.java:3683)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at java.lang.reflect.Method.invokeNative(Native Method)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at java.lang.reflect.Method.invoke(Method.java:507)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-05 15:35:17.053: INFO/dalvikvm(9387):   at dalvik.system.NativeStart.main(Native Method)
07-05 15:35:17.053: ERROR/dalvikvm(9387): VM aborting
07-05 15:35:17.163: INFO/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
07-05 15:35:17.163: INFO/DEBUG(31): Build fingerprint: 'generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys'
07-05 15:35:17.163: INFO/DEBUG(31): pid: 9387, tid: 9387  >>> com.test.jnitest <<<
07-05 15:35:17.173: INFO/DEBUG(31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadd00d
07-05 15:35:17.173: INFO/DEBUG(31):  r0 fffffec4  r1 deadd00d  r2 00000026  r3 00000000
07-05 15:35:17.183: INFO/DEBUG(31):  r4 800a45c0  r5 40517438  r6 41ad8ad0  r7 40517438
07-05 15:35:17.183: INFO/DEBUG(31):  r8 befc3428  r9 418fccdc  10 418fccc8  fp 42598bb8
07-05 15:35:17.193: INFO/DEBUG(31):  ip 800a4720  sp befc3398  lr afd19375  pc 80045a4a  cpsr 20000030
07-05 15:35:17.453: INFO/DEBUG(31):          #00  pc 00045a4a  /system/lib/libdvm.so
07-05 15:35:17.453: INFO/DEBUG(31):          #01  pc 00037748  /system/lib/libdvm.so
07-05 15:35:17.463: INFO/DEBUG(31):          #02  pc 0003dc44  /system/lib/libdvm.so
07-05 15:35:17.473: INFO/DEBUG(31):          #03  pc 0003fa9c  /system/lib/libdvm.so
07-05 15:35:17.473: INFO/DEBUG(31):          #04  pc 000003f2  /data/data/com.test.jnitest/lib/libJNItest.so
07-05 15:35:17.473: INFO/DEBUG(31):          #05  pc 00000440  /data/data/com.test.jnitest/lib/libJNItest.so
07-05 15:35:17.473: INFO/DEBUG(31):          #06  pc 00017d74  /system/lib/libdvm.so
07-05 15:35:17.483: INFO/DEBUG(31):          #07  pc 00048ecc  /system/lib/libdvm.so
07-05 15:35:17.493: INFO/DEBUG(31):          #08  pc 00041a86  /system/lib/libdvm.so
07-05 15:35:17.493: INFO/DEBUG(31):          #09  pc 0004e624  /system/lib/libdvm.so
07-05 15:35:17.503: INFO/DEBUG(31):          #10  pc 0001cfd4  /system/lib/libdvm.so
07-05 15:35:17.503: INFO/DEBUG(31):          #11  pc 000220dc  /system/lib/libdvm.so
07-05 15:35:17.503: INFO/DEBUG(31):          #12  pc 00020fd0  /system/lib/libdvm.so
07-05 15:35:17.523: INFO/DEBUG(31):          #13  pc 0005f5de  /system/lib/libdvm.so
07-05 15:35:17.523: INFO/DEBUG(31):          #14  pc 00066fce  /system/lib/libdvm.so
07-05 15:35:17.523: INFO/DEBUG(31):          #15  pc 0001cfd4  /system/lib/libdvm.so
07-05 15:35:17.533: INFO/DEBUG(31):          #16  pc 000220dc  /system/lib/libdvm.so
07-05 15:35:17.543: INFO/DEBUG(31):          #17  pc 00020fd0  /system/lib/libdvm.so
07-05 15:35:17.543: INFO/DEBUG(31):          #18  pc 0005f430  /system/lib/libdvm.so
07-05 15:35:17.553: INFO/DEBUG(31):          #19  pc 0004b9a8  /system/lib/libdvm.so
07-05 15:35:17.553: INFO/DEBUG(31):          #20  pc 0003ebb0  /system/lib/libdvm.so
07-05 15:35:17.563: INFO/DEBUG(31):          #21  pc 000314ac  /system/lib/libandroid_runtime.so
07-05 15:35:17.573: INFO/DEBUG(31):          #22  pc 000322c6  /system/lib/libandroid_runtime.so
07-05 15:35:17.573: INFO/DEBUG(31):          #23  pc 00008ca2  /system/bin/app_process
07-05 15:35:17.573: INFO/DEBUG(31):          #24  pc 00014db8  /system/lib/libc.so
07-05 15:35:17.573: INFO/DEBUG(31): code around pc:
07-05 15:35:17.583: INFO/DEBUG(31): 80045a28 447a4479 ed0cf7d1 20004c09 ee34f7d1 
07-05 15:35:17.583: INFO/DEBUG(31): 80045a38 447c4808 6bdb5823 d0002b00 49064798 
07-05 15:35:17.593: INFO/DEBUG(31): 80045a48 700a2226 eea0f7d1 000436b7 00045275 
07-05 15:35:17.593: INFO/DEBUG(31): 80045a58 0005eb82 fffffec4 deadd00d b510b40e 
07-05 15:35:17.604: INFO/DEBUG(31): 80045a68 4c0a4b09 447bb083 aa05591b 6b5bca02 
07-05 15:35:17.604: INFO/DEBUG(31): code around lr:
07-05 15:35:17.633: INFO/DEBUG(31): afd19354 b0834a0d 589c447b 26009001 686768a5 
07-05 15:35:17.633: INFO/DEBUG(31): afd19364 220ce008 2b005eab 1c28d003 47889901 
07-05 15:35:17.633: INFO/DEBUG(31): afd19374 35544306 d5f43f01 2c006824 b003d1ee 
07-05 15:35:17.633: INFO/DEBUG(31): afd19384 bdf01c30 000281a8 ffffff88 1c0fb5f0 
07-05 15:35:17.643: INFO/DEBUG(31): afd19394 43551c3d a904b087 1c16ac01 604d9004 
07-05 15:35:17.643: INFO/DEBUG(31): stack:
07-05 15:35:17.643: INFO/DEBUG(31):     befc3358  00000015  
07-05 15:35:17.643: INFO/DEBUG(31):     befc335c  afd18407  /system/lib/libc.so
07-05 15:35:17.653: INFO/DEBUG(31):     befc3360  afd4270c  /system/lib/libc.so
07-05 15:35:17.653: INFO/DEBUG(31):     befc3364  afd426b8  /system/lib/libc.so
07-05 15:35:17.653: INFO/DEBUG(31):     befc3368  00000000  
07-05 15:35:17.653: INFO/DEBUG(31):     befc336c  afd19375  /system/lib/libc.so
07-05 15:35:17.653: INFO/DEBUG(31):     befc3370  0000ce48  [heap]
07-05 15:35:17.663: INFO/DEBUG(31):     befc3374  afd183d9  /system/lib/libc.so
07-05 15:35:17.663: INFO/DEBUG(31):     befc3378  40517438  /dev/ashmem/dalvik-heap (deleted)
07-05 15:35:17.673: INFO/DEBUG(31):     befc337c  0005eb82  [heap]
07-05 15:35:17.673: INFO/DEBUG(31):     befc3380  40517438  /dev/ashmem/dalvik-heap (deleted)
07-05 15:35:17.673: INFO/DEBUG(31):     befc3384  41ad8ad0  /dev/ashmem/dalvik-LinearAlloc (deleted)
07-05 15:35:17.673: INFO/DEBUG(31):     befc3388  40517438  /dev/ashmem/dalvik-heap (deleted)
07-05 15:35:17.673: INFO/DEBUG(31):     befc338c  afd18437  /system/lib/libc.so
07-05 15:35:17.673: INFO/DEBUG(31):     befc3390  df002777  
07-05 15:35:17.673: INFO/DEBUG(31):     befc3394  e3a070ad  
07-05 15:35:17.673: INFO/DEBUG(31): #00 befc3398  40009328  /dev/ashmem/dalvik-heap (deleted)
07-05 15:35:17.683: INFO/DEBUG(31):     befc339c  8003774d  /system/lib/libdvm.so
07-05 15:35:17.683: INFO/DEBUG(31): #01 befc33a0  40009328  /dev/ashmem/dalvik-heap (deleted)
07-05 15:35:17.693: INFO/DEBUG(31):     befc33a4  8003dc49  /system/lib/libdvm.so
07-05 15:35:19.693: DEBUG/Zygote(33): Process 9387 terminated by signal (11)
07-05 15:35:19.713: INFO/ActivityManager(74): Process com.test.jnitest (pid 9387) has died.

谢谢克里斯托夫。


问题答案:

经过一天的失误后,我终于找到了解决问题的方法:

该函数javaCallJNI()在Java中被声明为静态本机,但是静态方法无法调用非静态方法…

要解决此问题,只需替换:

public static native void javaCallJNI();

通过

public native void javaCallJNI();

在JNITestActivity.java中

感谢您的帮助,很快就会看到;)



 类似资料:
  • 我正在制作一个库应用程序,该应用程序使用谷歌断路器检测android中的本机崩溃。每当我的主端发生本机崩溃时,断路器都会调用以下回调。从这个回调中,我需要使用JNI在java类中调用一个静态val方法。 这是我的java方法: 在Android5.0之前,这一功能一直运行良好。但在Lollipop中,我无法调用我的java方法,因为我无法在Logcat控制台上看到“内部句柄异常”日志。 以下是我在

  • 问题内容: 因此,我正在编写一个使用大型c 库的Android应用。我可以正常工作,以便Java应用程序可以调用c 委托方法,但是我发现自己希望自己可以将来自c 的消息记录到Android日志中。从Java上这很容易,但是我不知道如何从c 调用Java方法。我的搜索找到了从c 打开jvm的方法,这根本不是我想要做的。理想情况下,我想将日志方法指针传递给c ,然后可以在需要时使用它。当然,Java不

  • 我的C代码无法找到Java中的公共静态函数调用。它成功地找到了类,没有错误。 我试图将结果返回给回调方法。“5”稍后将被更复杂的内容取代。 我在StackOverflow上似乎也有类似的问题,但是到目前为止没有任何变化似乎有所帮助。也许我有逻辑错误? 我的JNI(更新#2): 此代码包含在此函数中调用的方法中: 我的Java(更新#1): 签名检查: javap-s-pcecutils 公共静态响

  • 我有一个Java应用程序,它合并了一些大文件。Java应用程序不在我的控制之下。Java应用程序的结果以大约90MB的大字符串返回给我的C程序,我在其中的一些算法中使用它。我多次调用execute方法。我的问题是,每次调用Java应用程序时,它都会保留更多内存,但不会释放内存。从这个垃圾收集和JNI调用问题中,我想到手动调用垃圾收集器,但它不会释放内存。有没有办法解决这个问题? 这是我的C程序

  • 在尝试从cpp类调用java中的函数以在memmory中保存布尔值时,出现以下错误。我正在使用一个名为MyAdapter的类。cpp调用MyAdapterJni函数。cpp。我用MyAdapterJni编写了以下函数。清洁石油产品 我在myManager中有以下功能。java类 我在我的logcat上得到以下日志 12-14 12:06:32.024: W/dalvikvm(9575):异常Lja

  • 问题内容: 我创建了一个C ++类,应该通过以下方式调用:http : //docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#wp9502。 我没有使其正常工作,所以我遵循了:http : //www.coderanch.com/t/525082/CPP/create-JVM-native-code- c