当我的UDP程序调用我的JNI函数CallVoidMethod时,我的程序崩溃了。我无法从logcat解密问题。任何帮助将不胜感激。
我的代码片段:
JNI功能:
jmethodID constructID, methodID;
JNIEnv* env;
jclass clazz;
JavaVM *g_jm;
int downLoad_speed_test_start(JNIEnv * envl, jobject thiz, int serverport) {
jobject obj;
struct sockaddr_in servAddr, clientAddr;
int slen = sizeof(clientAddr);
char buf[512];
int socket_ovdp;
if ((socket_ovdp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
__android_log_print(ANDROID_LOG_DEBUG, "MY_TAG",
"\nSocket() unsuccessful\n");
else
__android_log_print(ANDROID_LOG_DEBUG, "MY_TAG",
"\nServer: Socket() successful\n");
bzero(&servAddr, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(serverport);
inet_addr("127.0.0.1");
clazz=env->GetObjectClass(thiz);
constructID = env->GetMethodID(clazz, "<init>","()V");
methodID = env->GetMethodID(clazz,"jniCall","(I)V");
obj=env->NewObject(clazz,constructID);
JavaVM *jm;
env->GetJavaVM(&jm);
if (bind(socket_ovdp, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1)
__android_log_print(ANDROID_LOG_DEBUG, "MY_TAG",
"\nServer : bind() failed!\n");
else
{
__android_log_print(ANDROID_LOG_DEBUG, "MY_TAG",
"\nServer : bind() successful\n");
}
while (true) {
if (recvfrom(socket_ovdp, buf, 512, 0, (struct sockaddr*) &clientAddr,
&slen) == -1)
__android_log_print(ANDROID_LOG_DEBUG, "MY_TAG",
"\nRecvfrom() did not work\n");
else
{
//handle message
__android_log_print(ANDROID_LOG_DEBUG, "MY_TAG", "\nReceived: %s\n\n",
buf);
int newbuf = 5;
env->CallVoidMethod(obj,methodID,newbuf);
}
}
return 0;
}
处理程序的Java函数:
void jniCall(int arg)
{
Message m = mHandler.obtainMessage();
m.arg1=arg;
mHandler.sendMessageDelayed(m, 10/* ms */);
}
public Handler mHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg){
try{
chatbox.setText("Got it!");
}catch(Exception e){
Log.i("MYLOG", "Message was not handled.");
}
//chatbox.setText(chatbox.getText() + "Got it!");
}
};
我的logcat:
08-20 18:09:26.200: W/dalvikvm(3521): JNI WARNING: threadid=15 using env from threadid=16
08-20 18:09:26.200: W/dalvikvm(3521): in Lcom/WifiSpeedTest2/WifiSpeedTestActivity;.ovt_downLoad_speed_test_start:(I)I (CallVoidMethodV)
08-20 18:09:26.210: I/dalvikvm(3521): "Thread-154" prio=5 tid=15 NATIVE
08-20 18:09:26.210: I/dalvikvm(3521): | group="main" sCount=0 dsCount=0 obj=0x40d332f8 self=0x2a1b96f0
08-20 18:09:26.221: I/dalvikvm(3521): | sysTid=3555 nice=0 sched=0/0 cgrp=apps handle=706079760
08-20 18:09:26.221: I/dalvikvm(3521): | state=R schedstat=( 7136784 37413210 12 ) utm=0 stm=0 core=0
08-20 18:09:26.250: I/Thread:(3521): connected lost
08-20 18:09:26.380: I/dalvikvm(3521): #00 pc 000012a0 /system/lib/libcorkscrew.so (unwind_backtrace_thread+27)
08-20 18:09:26.411: I/dalvikvm(3521): #01 pc 0005faa8 /system/lib/libdvm.so (dvmDumpNativeStack(DebugOutputTarget const*, int)+35)
08-20 18:09:26.411: I/dalvikvm(3521): #02 pc 00053914 /system/lib/libdvm.so (dvmDumpThreadEx(DebugOutputTarget const*, Thread*, bool)+303)
08-20 18:09:26.420: I/dalvikvm(3521): #03 pc 000539ae /system/lib/libdvm.so (dvmDumpThread(Thread*, bool)+25)
08-20 18:09:26.420: I/dalvikvm(3521): #04 pc 00038aba /system/lib/libdvm.so
08-20 18:09:26.430: I/dalvikvm(3521): #05 pc 0003fc24 /system/lib/libdvm.so
08-20 18:09:26.430: I/dalvikvm(3521): #06 pc 0000150c /data/app-lib/com.WifiSpeedTest2-2/libwifiSpeedTest2.so (_JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, ...)+60)
08-20 18:09:26.430: I/dalvikvm(3521): #07 pc 00001c18 /data/app-lib/com.WifiSpeedTest2-2/libwifiSpeedTest2.so (ovt_downLoad_speed_test_start(_JNIEnv*, _jobject*, int)+956)
08-20 18:09:26.430: I/dalvikvm(3521): #08 pc 00001e64 /data/app-lib/com.WifiSpeedTest2-2/libwifiSpeedTest2.so (ovt_downLoad_speed_test_start_jni(_JNIEnv*, _jobject*, int)+72)
08-20 18:09:26.441: I/dalvikvm(3521): #09 pc 0001e290 /system/lib/libdvm.so (dvmPlatformInvoke+112)
08-20 18:09:26.470: I/dalvikvm(3521): #10 pc 0004d1f8 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+391)
08-20 18:09:26.470: I/dalvikvm(3521): #11 pc 00038b44 /system/lib/libdvm.so (dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+7)
08-20 18:09:26.470: I/dalvikvm(3521): #12 pc 000276a0 /system/lib/libdvm.so
08-20 18:09:26.470: I/dalvikvm(3521): #13 pc 0002b540 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
08-20 18:09:26.470: I/dalvikvm(3521): #14 pc 0005f9d4 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+271)
08-20 18:09:26.470: I/dalvikvm(3521): #15 pc 0005f9fe /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+19)
08-20 18:09:26.470: I/dalvikvm(3521): #16 pc 00054576 /system/lib/libdvm.so
08-20 18:09:26.481: I/dalvikvm(3521): #17 pc 0000e3b8 /system/lib/libc.so (__thread_entry+72)
08-20 18:09:26.481: I/dalvikvm(3521): #18 pc 0000dab0 /system/lib/libc.so (pthread_create+160)
08-20 18:09:26.481: I/dalvikvm(3521): at com.WifiSpeedTest2.WifiSpeedTestActivity.ovt_downLoad_speed_test_start(Native Method)
08-20 18:09:26.491: I/dalvikvm(3521): at com.WifiSpeedTest2.WifiSpeedTestActivity$receiveVideoThread.run(WifiSpeedTestActivity.java:96)
08-20 18:09:26.500: E/dalvikvm(3521): VM aborting
08-20 18:09:26.500: A/libc(3521): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 3555 (Thread-154)
编辑:添加OnLoad和其他功能
int downLoad_speed_test_start_jni(JNIEnv * envl, jobject thiz,
int serverport) {
env = envl;
//env->GetJavaVM(&g_jm);
downLoad_speed_test_start(env, thiz, serverport);
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
jint result = -1;
g_jm = vm;
// catched_jvm = vm;
LOGE("JNI_OnLoad\n");
static const char* const strClassName =
"com/WifiSpeedTest2/WifiSpeedTestActivity";
//static const char* const strClassName = "com/MultPkg/Mult";
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed\n");
return result;
}
if (env == NULL) {
LOGE("ERROR: env is NULL\n");
return result;
}
/* find the class handle */
clazz = env->FindClass(strClassName);
if (clazz == NULL) {
LOGE("Can't find class %s\n", strClassName);
return result;
}
// fields.clazz = (jclass) env->NewGlobalRef(clazz);
/* register all the methods */
if (env->RegisterNatives(clazz, gMethods,
sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
{
LOGE("Failed registering methods for %s\n", strClassName);
return result;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
__android_log_print(ANDROID_LOG_DEBUG, "MY_TAG",
"\nJNI OnLoad worked.\n");
return result;
}
答案 0 :(得分:6)
JNI WARNING: threadid=15 using env from threadid=16
您在线程之间共享JNIEnv
。不要这样做 - JNIEnv
是特定于线程的。
使用传入的内容作为从Java代码调用的本机方法的第一个参数,或者在全局中保存JavaVM
并使用GetEnv call获取JNIEnv
。
另请参阅JNI Tips页面。
答案 1 :(得分:2)
如果您想使用JNIEnv
,则必须在线程中调用AttachCurrentThread()
以将自身附加到VM并获取JNI接口指针。这是Oracle's JNI reference