从C ++调用java代码:exception java.lang.NoSuchMethodError

时间:2015-03-10 09:34:39

标签: java android c++ android-ndk

我试图从JNI C ++函数调用一些java代码,我得到一个异常:java.lang.NoSuchMethodError

调用java代码的C ++代码是从另一个本机库调用的回调函数。 当我使用中描述的设置时,此代码工作正常 here

基本上是一个使用JNI并且JNI正在调用其他地方编译的本机库的APK。

但后来我想在AOSP中编译我的所有代码,所以我把我的本机库代码,JNI和APK代码放在vendor / MyCode / MyApp中。它编译了从java工作调用的精细本机方法,但是从JNI调用的java代码现在崩溃了。

以下是我想从JNI调用的方法的java代码:

package com.android.mycode.myapp;

import android.app.Activity;

public class MainActivity extends Activity implements OnClickListener
{
    private native int powerOn();

    ...

public void ndefRead(int tech, int protocol, byte[] ndef)
{
    Log.d(tag, "ndefRead()");
    Message msg = mHandler.obtainMessage();
    msg.what = MSG_NDEF_READ_RECEIVED;
    msg.obj = ndef;
    msg.arg1 = tech;
    msg.arg2 = protocol;
    mHandler.sendMessage(msg);
}

...
}

我注册java数据的JNI代码:

JNIEXPORT jint JNICALL
Java_com_android_mycode_myapp_MainActivity_powerOn(JNIEnv * env, jobject obj)
{
    LOGD("calling powerOn()"); //Or ANDROID_LOG_INFO, ...

    env->GetJavaVM(&javaVM);
    jclass cls = env->GetObjectClass(obj);
    activityClass = (jclass) env->NewGlobalRef(cls);
    activityObj = env->NewGlobalRef(obj);
    ...
    return status;
}

调用java代码的回调函数的JNI代码:

void EventCallback(UINT8 event, tEVT_CBACK_DATA* eventData)
{
LOGD("EventCallback() - event: 0x%x", event);

switch (event)
{
    case NDEF_READ_EVT:
    {
        LOGD("EventCallback() - NDEF_READ_EVT - data length: 0x%x", eventData->ndefReadEvt.length);

        JNIEnv *env;
        javaVM->AttachCurrentThread(&env, NULL);

        jmethodID ndefReadID = env->GetMethodID(activityClass, "ndefRead", "(II[B)V");
        if (ndefReadID == 0)
        {
            LOGD("Function ndefRead() not found");
            return;
        }

        jbyteArray result = env->NewByteArray(eventData->ndefReadEvt.length);
        if (result != NULL)
        {
            env->SetByteArrayRegion(result, 0, eventData->ndefReadEvt.length, (jbyte *) eventData->ndefReadEvt.p_ndef);
        }

        env->CallVoidMethod(activityObj, ndefReadID, eventData->ndefReadEvt.tech, eventData->ndefReadEvt.protocol, result);
        javaVM->DetachCurrentThread();
    }
        break;
}

JNI的makefile如下所示:

LOCAL_MODULE    := libinterface
LOCAL_SRC_FILES := interface.cpp
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := libnfc-nci

执行此代码时,我收到以下异常/错误消息:

Pending exception java.lang.NoSuchMethodError thrown by 'unknown throw location'
java.lang.NoSuchMethodError: no non-static method "Lcom/android/mycode/myapp/MainActivity;.ndefRead(II[B)V"

我已经看过这个网站上报告的其他几个这类问题,但是找不到与我类似的东西。如果有人有想法,我将不胜感激。

编辑添加ndefRead()函数和JNI的makefile的代码。

1 个答案:

答案 0 :(得分:0)

这些错误通常是由make文件或错误的文件命名引起的。

我没有看到任何static { System.loadLibrary("your-c-module"); },如android MK中所定义,例如:

#android.mk

include $(CLEAR_VARS)

LOCAL_MODULE    := your-c-module
LOCAL_SRC_FILES := main.cpp
LOCAL_STATIC_LIBRARIES += fancy-library
LOCAL_LDLIBS +=  -llog -ldl

此外,我不知道您是否将其过滤掉了,但如果您的c函数为Java_com_android_st_nfcnintendothread_MainActivity_powerOn,那么您的包名称应为:com.android.st.nfcnintendothread并且它是' s功能:MainActivity.powerOn

我只是在这里吐痰,希望你能在上面找到有用的东西。