java - 从 JNI 返回一个 byte[] 到 Java

标签 java android java-native-interface android-ndk

事实上我有这个工作,只是不正确。我有一个回调(在上一个问题中发布:Unable to get JNIEnv* value in arbitrary context),它现在调用 Java 层中的回调...唯一的问题是回调返回的数据类型。在我的 Java 代码中,调试时,我看到回调传递给 Java 的类型是 class [B 类型,而不是 byte[] 类型期待。

Java 回调所做的唯一一件事就是将它放在一个队列中,但是当我需要处理该队列时,问题就出现了。

Java 中的回调:

public void enqueueAudio(byte[] audioData){
    if(audioData != null){
        mWriteQueue.offer(audioData);
    }
}

队列的处理:

private void writeToFile(String file){
    int totalNumOfBytes = 0;
    byte[] dataFromQueue = new byte[0];
    byte[] temp;
    for(byte[] data : mWriteQueue){
        temp = dataFromQueue;
        dataFromQueue = new byte[temp.length + data.length];
        System.arraycopy(temp, 0, dataFromQueue, 0, temp.length);
        System.arraycopy(data, 0, dataFromQueue, temp.length, data.length);
        totalNumOfBytes += data.length;
    }
    // Write the total byte[] to the specified file.
    mFileHandler.write(file, dataFromQueue);
    updateUI("Number of bytes written to " + file + " : " + totalNumOfBytes + "\n");
}

如您所见,我假设队列中充满了 byte[],而不是 class [B,从而导致类转换异常...

那么, native 代码返回 class [B 而不是 byte[] 是否正确?

为了完整起见,这里是C中的方法:

void recorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context){
    SLresult result;
    JNIEnv* env;
    jbyteArray data;
    (*javaVM)->AttachCurrentThread(javaVM, &env, NULL);
    if(env == NULL){
        LOG_ERROR("Could not get JNIEnv*");
        return;
    }
    data = (*env)->NewByteArray(env, MAX_PACKET_SIZE);
    if(data == NULL){
        LOG_ERROR("No memory could be allocated for buffer");
        return;
    }
    (*env)->SetByteArrayRegion(env, data, 0, MAX_PACKET_SIZE, recorderBuffer);
    (*env)->CallByteMethodA(env, javaObject, javaCallbackMID, data);
    (*env)->DeleteLocalRef(env, data);
    result = (*bq)->Enqueue(bq, recorderBuffer,
                            RECORDER_FRAMES * sizeof(jbyte));
    checkError(result, "Unable to enqueue new buffer");
    (*javaVM)->DetachCurrentThread(javaVM);
}

最佳答案

In fact I have this working, just not correctly.

这在术语上是矛盾的。

  (*env)->CallByteMethodA(env, javaObject, javaCallbackMID, data);

它不是字节方法。这是一个 VoidMethod。

关于java - 从 JNI 返回一个 byte[] 到 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6014667/

相关文章:

java - Spring data jpa 在非常具体的场景中抛出 TransientObjectException

java - MongoDB聚合Java API不返回结果

android - 轮换 Activity 时如何不破坏ViewModel

android - 可以将渐进式 Web 应用程序注册为 Android 中的共享选项吗?

java - 将 Java boolean 数组转换为 C++ boolean 数组

java - 用于日志分析的模式匹配

java - Java有没有通过多次调用一个函数来填充一个List的方法?

android - 显示 infowindow android map

c++ - 从 jvm.dll 获取 FindClass 函数指针

android - 为 Android NDK 交叉编译 C 库