我正在尝试从JNI C++函数调用一些Java代码,但是我遇到了一个异常:java.lang.NoSuchMethodError。
调用Java代码的C++代码是从另一个本地库调用的回调函数。当我使用这里描述的设置时,这段代码运行得非常好:
基本上,一个APK使用了JNI,并且该JNI正在调用在其他地方编译的本地库)。
但是,我想将所有代码编译到AOSP中,因此我将我的本地库、JNI和APK代码放在vendor/MyCode/MyApp中。它可以编译,从Java调用的本地方法正常工作,但现在从JNI调用的Java代码全部崩溃了。
这是我想从JNI调用的方法的Java代码:
回调函数的JNI代码,其中调用了Java代码:
JNI的makefile如下所示:
调用Java代码的C++代码是从另一个本地库调用的回调函数。当我使用这里描述的设置时,这段代码运行得非常好:
基本上,一个APK使用了JNI,并且该JNI正在调用在其他地方编译的本地库)。
但是,我想将所有代码编译到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);
}
...
}
这是我的JNI代码,其中我注册了Java数据:
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;
}
回调函数的JNI代码,其中调用了Java代码:
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。
activityClass
是否可以在该线程上使用?我快速查看了JNI文档,但对我来说并不清楚。 - Richard CrittenEventCallback
的调用来自哪里 -AttachCurrentThread
本质上是 NOP(无操作)如果线程已经附加到 VM,则在先前附加到AttachCurrentThread
的线程上调用DetachCurrentThread
可能会导致问题。 - Michaelpackage com.android.mycode.myapp;
与Java_com_android_st_nfcnintendothread_MainActivity_powerOn
- Selvin