从java backgroundThread调用它时Jni崩溃,从主线程开始工作

时间:2015-08-11 10:20:18

标签: java android multithreading java-native-interface

嗨我试图抓住camerapreview帧并在java后台线程中转换它们从它调用jni方法。 在uithread中运行该代码有效。 来源是here

我将本机引用存储在ByteBuffer中,当从jni调用INIT()方法时它会获取init

爪哇:

didReceiveLocalNotification

JNI:

private ByteBuffer nativeHandler = null;
private synchronized static native ByteBuffer INIT();

当让它在ui线程上运行时,它可以工作

JNIEXPORT jobject JNICALL Java_troop_com_imageconverter_ImageProcessorWrapper_INIT(JNIEnv *env, jobject thiz)
{
    ImageProcessor* rgbContainer = new ImageProcessor();
    jobject g = env->NewDirectByteBuffer(rgbContainer, 0);
    return g;
}

现在将它放在一个java线程中,它会在imageProcessor.ApplyHPF()

上崩溃
public void onPreviewFrame(byte[] data, Camera camera)
    {
        camera.setPreviewCallback(null);
        ImageProcessorWrapper imageProcessor = new ImageProcessorWrapper();
        imageProcessor.ProcessFrame(data.clone(), w, h);
        imageProcessor.ApplyHPF();

    }

某种方式第二次调用找不到本机存储的像素数组。 A / libc:致命信号11(SIGSEGV),代码1,故障地址0xa16a8000 in tid 9781(Thread-2246)

private void ProcessOnce(final byte[] _data)
    {
        new Thread() {
            @Override
            public void run() {
                byte[] data = _data.clone();
                try {
                    final ImageProcessorWrapper imageProcessor = new ImageProcessorWrapper();

                    if (data != null)
                    {
                        imageProcessor.ProcessFrame(data, w, h);
                        imageProcessor.ApplyHPF(); // that call crash

                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    camera.setPreviewCallback(null);
                    doWork = false;

                }
            }
        }.start();
    }

Imageprocessor:

JNIEXPORT void JNICALL Java_troop_com_imageconverter_ImageProcessorWrapper_YUVtoRGB(JNIEnv *env, jobject thiz,jobject handler, jbyteArray yuv420sp, jint width, jint height)
{
    jbyte* yuv = (jbyte*) env->GetByteArrayElements(yuv420sp,NULL);
    int size = env->GetArrayLength(yuv420sp);
    jint* nativeyuv = new jint[size];
    ImageProcessor* rgbContainer = (ImageProcessor*)env->GetDirectBufferAddress(handler);
    memcpy(nativeyuv,yuv, size);
    env->ReleaseByteArrayElements(yuv420sp, yuv, 0);
    rgbContainer->YuvToRgb(nativeyuv, width, height);
}


JNIEXPORT void    JNICALL Java_troop_com_imageconverter_ImageProcessorWrapper_ApplyHighPassFilter(JNIEnv *env, jobject thiz,jobject handler)
{
    ImageProcessor* rgbContainer = (ImageProcessor*)env->GetDirectBufferAddress(handler);

    rgbContainer->applyFocusPeak();
}

我的问题是,当从java线程调用它时,如何获得存储本机ImageProcessor的内存区域的vailid引用? 我读到的关于JniEnv的内容总是返回它运行的线程的上下文。因此,两个方法的jnienv应该相等,因为它是从同一个线程调用的。

0 个答案:

没有答案