我编写了一个本地方法,可以从套接字接收数据,然后回写到ByteArray,它是来自Java的输入参数。该套接字在BlueZ中创建并通过dBus消息传输到我的程序中。我使用单独的线程来完成整个过程。JNI投票问题
感谢Cerber对我以前的GetPrimitiveArrayCritical()问题的建议。现在,该程序可以运行没有错误。
但是,新问题是因为我使用Poll来等待POLLIN事件,如果有传入数据可供读取,理论上会有POLLIN事件,并且我可以执行套接字读取。
不幸POLLIN事件不断被触发,但我无法读取任何数据! 但是,当我在BlueZ的代码中完成同样的过程时,这种奇怪的行为没有发生。 我确定插座是正确的。
这件作品的我的本机代码是这样的:
struct socket_loop_native_data {
pthread_mutex_t thread_mutex;
pthread_t thread;
struct pollfd *pollData;
JavaVM *vm;
int envVer;
jobject me;
jbyteArray javaBuffer;
int bufferSize;
jbyte *nativeBuffer;
char *beginOfBuffer;
char *endOfBuffer;
int decodedDataSize;
bool running;
};
typedef socket_loop_native_data native_data_t;
static jfieldID field_mNativeDataSocket;
static inline native_data_t *get_native_data(JNIEnv *env, jobject object) {
return (native_data_t *)(env->GetIntField(object, field_mNativeDataSocket));
}
native_data_t *get_SocketLoop_native_data(JNIEnv *env, jobject object) {
return get_native_data(env, object);
}
JNIEXPORT void JNICALL Java_android_classInitNativeSocket(JNIEnv* env, jclass clazz) {
field_mNativeDataSocket = env->GetFieldID(clazz, "mNativeDataSocket", "I");
}
JNIEXPORT void JNICALL Java_android_initializeNativeDataNativeSocket(JNIEnv* env, jobject object) {
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
LOGD("%s: out of memory!", __FUNCTION__);
return;
}
memset(nat, 0, sizeof(native_data_t));
pthread_mutex_init(&(nat->thread_mutex), NULL);
env->SetIntField(object, field_mNativeDataSocket, (jint)nat);
}
JNIEXPORT jboolean JNICALL Java_android_startSocketLoopNative(JNIEnv *env, jobject object, jint sock, jbyteArray buffer, jint size) {
jboolean result = JNI_FALSE;
socket_loop_native_data *nat = get_native_data(env, object);
pthread_mutex_lock(&(nat->thread_mutex));
nat->running = false;
if (nat->pollData) {
LOGD("trying to start SocketLoop a second time!");
pthread_mutex_unlock(&(nat->thread_mutex));
return JNI_FALSE;
}
nat->pollData = (struct pollfd *)malloc(sizeof(struct pollfd));
if (!nat->pollData) {
LOGD("out of memory error starting SocketLoop!");
goto done;
}
memset(nat->pollData, 0, sizeof(struct pollfd));
nat->pollData[0].fd = sock;
nat->pollData[0].events = POLLIN;
env->GetJavaVM(&(nat->vm));
nat->envVer = env->GetVersion();
nat->me = env->NewGlobalRef(object);
nat->javaBuffer = (jbyteArray)(env->NewGlobalRef(buffer));
nat->bufferSize = (int)size;
nat->decodedDataSize = 0;
pthread_create(&(nat->thread), NULL, socketLoopMain, nat);
result = JNI_TRUE;
done:
if (JNI_FALSE == result) {
if (nat->me) env->DeleteGlobalRef(nat->me);
nat->me = NULL;
if (nat->pollData) free(nat->pollData);
nat->pollData = NULL;
}
pthread_mutex_unlock(&(nat->thread_mutex));
return result;
}
static void *socketLoopMain(void *ptr) {
native_data_t *nat = (native_data_t *)ptr;
JNIEnv *env;
JavaVMAttachArgs args;
char name[] = "SocketLoop";
args.version = nat->envVer;
args.name = name;
args.group = NULL;
nat->vm->AttachCurrentThread(&env, &args);
/* For poll result */
int ret = 0;
/* For receiving pollin data */
int rlen;
char *buffer = (char *)calloc(1, 65536);
...
while ((nat->running)) {
if ((ret = poll(nat->pollData, 1, -1)) < 0){
LOGD("In socketLoopMain() : The socket poll error !!!");
goto close;
}
if ((nat->pollData[0].revents & POLLIN)){
...
rlen = read(nat->pollData[0].fd, buffer, 65536);
LOGD("In socketLoopMain() : Read bytes = %d", rlen);
...
}
else if ((nat->pollData[0].revents & POLLOUT)){
LOGD("In socketLoopMain() : The socket poll revents [POLLOUT] !!! DO NOTHING");
continue;
}
else if ((nat->pollData[0].revents & POLLERR)){
LOGD("In socketLoopMain() : The socket poll revents [POLLERR] !!!");
goto close;
}
else if ((nat->pollData[0].revents & POLLHUP)){
LOGD("In socketLoopMain() : The socket poll revents [POLLHUP] !!!");
goto close;
}
else if ((nat->pollData[0].revents & POLLRDHUP) || (nat->pollData[0].revents & POLLNVAL)){
LOGD("In socketLoopMain() : The socket poll revents [POLLRDHUP][POLLNVAL] !!!");
goto close;
}
}
...
}
除了第一POLLIN,我无法读取套接字的任何数据,RLEN始终为0
我建立整个本地代码通过在Android源代码根目录中使用命令“make libxxx”而不是“ndk-build”来共享lib。
任何建议将不胜感激!
感谢您的回复 –