Android NDK: How to solve "E/NdkMediaExtractor: setDataSource(path) must be called from Java thread"

361 Views Asked by At

I am trying to use Androids NDKMediaExtractor in C++ code like this:

const char *storageFile = "/storage/emulated/0/mytestfile.mp3";
AMediaExtractor *extractor = AMediaExtractor_new();
media_status_t amresult = AMediaExtractor_setDataSource(extractor, storageFile);

This fails with the error message E/NdkMediaExtractor: setDataSource(path) must be called from Java thread.

Searching online did not bring me any hints how I can solve this, what I did find though was the source code, the responsible part looks like this:

EXPORT
media_status_t AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) {
    ALOGV("setDataSource(%s)", location);
    // TODO: add header support
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jobject service = NULL;
    if (env == NULL) {
        ALOGE("setDataSource(path) must be called from Java thread");
        env->ExceptionClear();
        return AMEDIA_ERROR_UNSUPPORTED;
    }

    // rest of method omitted for brevity
}

I hand in a JNIEnv when I call my native methods from Java/Kotlin, but NDKMediaExtractordoes not seem to know about it. How can I solve this?

1

There are 1 best solutions below

1
boompsy On

you cant just pass JNIenv* between threads you should get it(every time in a native thread) by calling AttachCurrentThread(before calling any jni methods)in the current native thread so that it can be managed as java Thread.Once you do this it should be working. i.e

 JNIEnv* env;
virtualMachine->AttachCurrentThread(&env,NULL);

you should obtain env by calling AttachCurrentThread and now your native thread is managed as Java thread after attaching.So should resolve ur error.