На самом деле у меня это работает, просто не правильно. У меня есть обратный вызов (опубликовано в предыдущем вопросе: Невозможно получить значение JNIEnv * в произвольном контексте), который теперь вызывает обратный вызов на уровне 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[]
's, а не с class [B
, что приводит к исключениям класса cast...
Итак, правильно ли, что собственный код возвращает 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);
}
На самом деле у меня это работает, просто нет правильно.
Это противоречие в терминах.
(*env)->CallByteMethodA(env, javaObject, javaCallbackMID, data);
Это не ByteMethod. Это метод VoidMethod.
javaCallbackMID = (*env)->GetMethodID(env, javaClass, "enqueueAudio", "([B)V");
с помощью вызова javaCallbackMID = (*env)->GetMethodID(env, javaClass, "enqueueAudio", "([B)V");
, Я использую его только для вызова метода Java с параметром byte [], который не является тем, что передается в него при вызове ...