JNI中C回调java 比较奇怪Bug(望大牛指点)

傲慢的上校
博客专家认证
2014-02-17 05:03:48
在C++代码中,回调Java函数:

void OCDelegate::OnTLSReadEvent(const bolo::BoloBuf* buf) {

int status;
JNIEnv *env;
bool isAttached = false;

status = jniVm->GetEnv((void **) &env, JNI_VERSION_1_6);

if (status < 0) {

status = jniVm->AttachCurrentThread(&env, NULL);
if (status < 0) {
return;
}
isAttached = true;
}



char* charBuf = buf->headPtr();
int length = buf->length();
__android_log_print(ANDROID_LOG_INFO, "@@@@@@@@@@@@@@@@@",
"Jni OnTLSNetworkReturnsData.... on call back ........ the length is : %d", length);
jbyteArray bufArray = env->NewByteArray(length);
if (length > 0) {

/*jbyte* ba = env->GetByteArrayElements(bufArray, JNI_FALSE);
if (NULL != ba) {
memcpy(ba, charBuf, length);
env->ReleaseByteArrayElements(bufArray, ba, 0);
}*/
env->SetByteArrayRegion(bufArray, 0, length, (jbyte*)charBuf);

}

jclass cls = env->GetObjectClass(jniObj);

jmethodID callback = env->GetMethodID(cls, "onTLSReadEvent",
"([B)V");
__android_log_print(ANDROID_LOG_INFO, "@@@@@@@@@@@@@@@@@",
"GetMethodID ok, callback=%p", callback);
env->CallVoidMethod(jniObj, callback, bufArray);
__android_log_print(ANDROID_LOG_INFO, "@@@@@@@@@@@@@@@@@",
"GetMethodID ok, 22222222222222222222");
env->DeleteLocalRef(cls);
env->DeleteLocalRef(bufArray);
__android_log_print(ANDROID_LOG_INFO, "@@@@@@@@@@@@@@@@@",
"GetMethodID ok, 3333333333333333333");
}




C++里面的Log代码均打印!

但是在java代码中。


public void onTLSReadEvent(byte[] array) {

for (int i = 0; i < 3; i++) {
Log.v("@@@@@@@@@@@@@@", " in for.... java get message from C call back" + "1111111111111");
}

Log.v("@@@@@@@@@@@@@@", "java get message from C call back" + "1111111111111");
Log.v("@@@@@@@@@@@@@@", "java get message from C call back" + "$$$$$$$$$$$$$");
Log.v("@@@@@@@@@@@@@@", "java get message from C call back" + "222222222222");
Log.v("@@@@@@@@@@@@@@", "java get message from C call back" + "333333333333333");
// Log.v(tag, "RecvFromTLS:length=" + array.length);
Log.v("@@@@@@@@@@@@@@", "java get message from C call back" + "#############");




出Bug的时候,只打印一句log,且只打印一句:

Log.v("@@@@@@@@@@@@@@", " in for.... java get message from C call back"


正确时的LOG:

02-17 16:47:20.645: I/@@@@@@@@@@@@@@@@@(17650): GetMethodID ok, 22222222222222222222
02-17 16:47:20.645: I/@@@@@@@@@@@@@@@@@(17650): GetMethodID ok, 3333333333333333333
02-17 16:47:20.645: I/@@@@@@@@@@@@@@@@@(17650): Jni OnTLSNetworkReturnsData.... on call back ........ the length is : 116
02-17 16:47:20.645: I/@@@@@@@@@@@@@@@@@(17650): GetMethodID ok, callback=0x6d7e9dd0
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): in for.... java get message from C call back1111111111111
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): in for.... java get message from C call back1111111111111
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): in for.... java get message from C call back1111111111111
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): java get message from C call back1111111111111
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): java get message from C call back$$$$$$$$$$$$$
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): java get message from C call back222222222222
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): java get message from C call back333333333333333
02-17 16:47:20.645: V/@@@@@@@@@@@@@@(17650): java get message from C call back#############

02-17 16:47:20.645: I/jni @@@@@@@ jni .....(17650): Your raw is not null
02-17 16:47:20.645: I/jni @@@@@@@ jni .....(17650): Your param 10101010




(标红部分为java部分log)

当出Bug的时候,会打印一下log:

02-17 17:02:17.192: I/@@@@@@@@@@@@@@@@@(18948): sendToTLS... in the net work modu.... is not null
02-17 17:02:17.472: I/@@@@@@@@@@@@@@@@@(18948): Jni OnTLSNetworkReturnsData.... on call back ........ the length is : 17
02-17 17:02:17.472: I/@@@@@@@@@@@@@@@@@(18948): GetMethodID ok, callback=0x6d7e9dd0
02-17 17:02:17.472: V/@@@@@@@@@@@@@@(18948): in for.... java get message from C call back1111111111111
02-17 17:02:17.472: I/@@@@@@@@@@@@@@@@@(18948): GetMethodID ok, 22222222222222222222
02-17 17:02:17.472: I/@@@@@@@@@@@@@@@@@(18948): GetMethodID ok, 3333333333333333333



在java被回调方法只执行了一行代码,敬请大牛解惑!谢谢!




...全文
497 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
I_See_Sky 2015-05-25
  • 打赏
  • 举报
回复
我也遇到像这样的蛋疼问题,搞了我好久,他也是执行了一行代码,你把那个回调加上static试试
傲慢的上校 2014-02-18
  • 打赏
  • 举报
回复
引用 12 楼 guzhijie1981 的回复:
我的帖子 你看看吧 http://www.eoeandroid.com/thread-281831-1-1.html 或许有帮助
好的,谢谢。。。
傲慢的上校 2014-02-18
  • 打赏
  • 举报
回复
引用 10 楼 iltgcl 的回复:
雖然你的代碼沒有貼全,但可以知道你c++代碼有典型的多線程問題
是的,C++里面是有多个线程,有什么解决方法吗?
sun83819 2014-02-18
  • 打赏
  • 举报
回复
guzhijie1981 2014-02-18
  • 打赏
  • 举报
回复
我的帖子 你看看吧 http://www.eoeandroid.com/thread-281831-1-1.html 或许有帮助
guzhijie1981 2014-02-18
  • 打赏
  • 举报
回复
引用 8 楼 aomandeshangxiao 的回复:
引用 6 楼 guzhijie1981 的回复:
你是不是多次执行结果不同?还是每次都是这样的?
经常性的这样,有时候,刚打开应用,登录什么都都正常,登录也调用OnTLSReadEvent 方法,就没有问题,过一段时间,就会出现这种问题。。。
那就是你开了新线程的问题,JNI 似乎只能在注册的线程下使用对象,如果C++ 开了新线程,那么必须使用全局变量存放你需要callback的对象。另外你需要DetachCurrentThread 新线程。
iltgcl 2014-02-18
  • 打赏
  • 举报
回复
雖然你的代碼沒有貼全,但可以知道你c++代碼有典型的多線程問題
傲慢的上校 2014-02-17
  • 打赏
  • 举报
回复
引用 7 楼 l417584711 的回复:
DeleteLocalRef 去掉试试
试过了,不行。。。
傲慢的上校 2014-02-17
  • 打赏
  • 举报
回复
引用 6 楼 guzhijie1981 的回复:
你是不是多次执行结果不同?还是每次都是这样的?
经常性的这样,有时候,刚打开应用,登录什么都都正常,登录也调用OnTLSReadEvent 方法,就没有问题,过一段时间,就会出现这种问题。。。
aSysBang 2014-02-17
  • 打赏
  • 举报
回复
DeleteLocalRef 去掉试试
guzhijie1981 2014-02-17
  • 打赏
  • 举报
回复
你是不是多次执行结果不同?还是每次都是这样的?
guzhijie1981 2014-02-17
  • 打赏
  • 举报
回复
引用 4 楼 guzhijie1981 的回复:
你没有给参数,调用个毛啊。byte[]的参数呢?
看错了,好久没有搞了,我看看啊
guzhijie1981 2014-02-17
  • 打赏
  • 举报
回复
你没有给参数,调用个毛啊。byte[]的参数呢?
傲慢的上校 2014-02-17
  • 打赏
  • 举报
回复
引用 2 楼 ncepu307 的回复:
简直不可思议。。。。楼主说的出BUG的时候就是指log打印缺失吗?
不是打印缺失,是只执行了java代码中的一句代码,就不往下执行,而是返回到C了。 导致错误。
依然绿茶 2014-02-17
  • 打赏
  • 举报
回复
简直不可思议。。。。楼主说的出BUG的时候就是指log打印缺失吗?

80,471

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧