fmod 在 Android java_object == null 中崩溃

问题描述 投票:0回答:1

我在 Android 应用程序中使用 fmod 库来过滤声音。 GP 控制台发生崩溃,我无法在我的设备上重现它。这是回溯:

JNI DETECTED ERROR IN APPLICATION: java_object == null
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

backtrace:
  #00  pc 0x000000000005c444  /apex/com.android.runtime/lib64/bionic/libc.so (abort+180)
  #01  pc 0x000000000093091c  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+344)
  #02  pc 0x00000000000160fc  /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_0::__invoke(char const*)+80)
  #03  pc 0x00000000000156d0  /apex/com.android.art/lib64/libbase.so (android::base::LogMessage::~LogMessage()+516)
  #04  pc 0x0000000000442390  /apex/com.android.art/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1696)
  #05  pc 0x0000000000525278  /apex/com.android.art/lib64/libart.so (art::JNI<false>::GetObjectClass(_JNIEnv*, _jobject*)+468)
  #06  pc 0x0000000000005188  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/split_config.arm64_v8a.apk!libexample.so (Common_GetPropertyValue(int)+136) (BuildId: 7264cb4aa1e9a168b62455f5db85b4cf6e74945c)
  #07  pc 0x000000000000623c  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/split_config.arm64_v8a.apk!libexample.so (FMOD_LivePreview(char const*, float)+728) (BuildId: 7264cb4aa1e9a168b62455f5db85b4cf6e74945c)
  #08  pc 0x0000000000005470  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/split_config.arm64_v8a.apk!libexample.so (Java_com_my_package_activitySound_SoundJavaActivity_fmodStartPlay+164) (BuildId: 7264cb4aa1e9a168b62455f5db85b4cf6e74945c)
  #09  pc 0x000000000037412c  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (art_jni_trampoline+124)
  #10  pc 0x0000000000780780  /apex/com.android.art/lib64/libart.so (nterp_helper+5648)
  #11  pc 0x00000000003e3282  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/base.apk (com.my.package.activitySound.SoundJavaActivity.lambda$playSound$7+18)
  #12  pc 0x00000000007800c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #13  pc 0x00000000003e2ef0  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/base.apk (com.my.package.activitySound.SoundJavaActivity.$r8$lambda$AaHEezBg_mfaszt4Iimkszl0fc4)
  #14  pc 0x000000000077f1a4  /apex/com.android.art/lib64/libart.so (nterp_helper+52)
  #15  pc 0x00000000003e28c8  /data/app/~~Z_IFePTytjAkWkrXxToe1w==/com.my.app.package-y8HMT5XoWD5wlTXbflg7-A==/base.apk (com.my.package.activitySound.SoundJavaActivity$$ExternalSyntheticLambda2.run+4)
  #16  pc 0x00000000005f49a4  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor.runWorker+724)
  #17  pc 0x00000000005f22d8  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor$Worker.run+56)
  #18  pc 0x00000000004ccc50  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (java.lang.Thread.run+64)
  #19  pc 0x000000000036d574  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612)
  #20  pc 0x0000000000358bc0  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+132)
  #21  pc 0x0000000000944608  /apex/com.android.art/lib64/libart.so (art::detail::ShortyTraits<(char)86>::Type art::ArtMethod::InvokeInstance<(char)86>(art::Thread*, art::ObjPtr<art::mirror::Object>, art::detail::ShortyTraits<>::Type...)+60)
  #22  pc 0x0000000000625d24  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1344)
  #23  pc 0x00000000006257d4  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallbackWithUffdGc(void*)+8)
  #24  pc 0x00000000000c9fb0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208)
  #25  pc 0x000000000005dd90  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

方法如下:

// Global JavaVM pointer
JavaVM *gJvm = nullptr;

jobject gMainActivityObject = nullptr;
    void
    Java_com_baby_hearth_monitor_activityEdit_EditJavaActivity_fmodStartPlay(JNIEnv *env, jobject thiz,
                                                                             jstring index, jfloat f) {
    //    Log
    
        soundShouldStop = false;
        if (gMainActivityObject) {
            printf("Deleting old global reference for gMainActivityObject\n");
            env->DeleteGlobalRef(gMainActivityObject);
        }
        gMainActivityObject = env->NewGlobalRef(thiz);
        printf("gMainActivityObject set with a new global reference\n");
    
        const char *nativeString = env->GetStringUTFChars(index, nullptr);
        FMOD_LivePreview(nativeString, f);
        env->ReleaseStringUTFChars(index, nativeString);
    }

    int FMOD_LivePreview(const char *fileName, float f) {
        FMOD::System *system = 0;
        FMOD::Sound *sound = 0;
        FMOD::Channel *channel = 0;
        FMOD::ChannelGroup *mastergroup = 0;
        FMOD::DSP *dsplowpass = 0;
        FMOD::DSP *dsppitch = 0;
        FMOD::DSP *dspnormalize = 0;
    
        unsigned int version;
        void *extradriverdata = 0;
    
        unsigned int currentPosition = 0;
        unsigned int startFrom = 0;
        unsigned int endsTo = 0;
        unsigned int lenms = 0;
    
    
        Common_Init(&extradriverdata);
    
        /*
         Create a System object and initialize
         */
        result = FMOD::System_Create(&system);
        ERRCHECK(result);
    
        result = system->getVersion(&version);
        ERRCHECK(result);
    
        if (version < FMOD_VERSION) {
            Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version,
                         FMOD_VERSION);
        }
    
        result = system->init(32, FMOD_INIT_NORMAL, extradriverdata);
        ERRCHECK(result);
    
        result = system->getMasterChannelGroup(&mastergroup);
        ERRCHECK(result);
    
    
        result = system->createSound(Common_MediaPath(fileName), FMOD_DEFAULT, 0, &sound);
        ERRCHECK(result);
    
        /*
         Create some effects to play with
         */
        result = system->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &dsplowpass);
        ERRCHECK(result);
    
        result = system->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, &dsppitch);
        ERRCHECK(result);
        result = system->createDSPByType(FMOD_DSP_TYPE_NORMALIZE, &dspnormalize);
        ERRCHECK(result);
    
        /*
         Add them to the master channel group.  Each time an effect is added (to position 0) it pushes the others down the list.
         */
        result = mastergroup->addDSP(0, dsplowpass);
        ERRCHECK(result);
    
        result = mastergroup->addDSP(0, dsppitch);
        ERRCHECK(result);
        result = mastergroup->addDSP(0, dspnormalize);
        ERRCHECK(result);
    
        /*
         By default, bypass all effects.  This means let the original signal go through without processing.
         It will sound 'dry' until effects are enabled by the user.
         */
        result = dsplowpass->setBypass(true);
        ERRCHECK(result);
    
        result = dsppitch->setBypass(true);
        ERRCHECK(result);
        result = dspnormalize->setBypass(true);
        ERRCHECK(result);
    
        /*
         Main loop
         */
        bool soundStarted = false;
        Common_ShouldPlay();
        do {
            if (!soundStarted) {
                channel->stop();
                sound->setDefaults(f, 0);
            }
    
            channel->setLoopCount(10000);
    
    
            channel->setMode(FMOD_LOOP_NORMAL);
    
    
            channel->setFrequency(f);
    
            float pitch = Common_GetPropertyValue(0);
            float cutoff = Common_GetPropertyValue(1);
            float maxAmp = Common_GetPropertyValue(2);
            float threshold = Common_GetPropertyValue(3);
    
            dsppitch->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, pitch);
            dsppitch->setBypass(false);
            dsplowpass->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, cutoff);
            dsplowpass->setBypass(false);
            dspnormalize->setParameterFloat(FMOD_DSP_NORMALIZE_MAXAMP, maxAmp);
            dspnormalize->setBypass(false);
            dspnormalize->setParameterFloat(FMOD_DSP_NORMALIZE_THRESHOLD, threshold);
            dspnormalize->setBypass(false);
    
            if (!soundStarted) {
                soundStarted = true;
                system->playSound(sound, 0, false, &channel);
                sound->getLength(&lenms, FMOD_TIMEUNIT_MS);
                Common_SoundStarted(lenms);
            }
    
            result = system->update();
    
            sound->getLength(&lenms, FMOD_TIMEUNIT_MS);
            startFrom = 0.0; // lenms * Common_GetStartPosition();
            endsTo = lenms; // * Common_GetEndPosition();
    
            channel->getPosition(&currentPosition, FMOD_TIMEUNIT_MS);
    
            if (currentPosition > 0) {
                if (currentPosition <= startFrom) {
                    currentPosition = startFrom;
                    result = channel->setPosition(currentPosition, FMOD_TIMEUNIT_MS);
                    ERRCHECK(result);
                }
    
                if (currentPosition >= endsTo) {
                    channel->setPosition(startFrom, FMOD_TIMEUNIT_MS);
                    currentPosition = startFrom;
    
                    if (!Common_SoundLoopActive()) {
                        Common_Stop();
                    }
                }
            }
            bool isPlaying;
            channel->isPlaying(&isPlaying);
    
            if (!isPlaying) {
                Common_Stop();
            }
    
            Common_UpdateCurrentTime(float(currentPosition) / float(lenms));
            Common_Sleep(1);
        } while (!Common_SoundShouldStop());
    
        /*
         Shut down
         */
    
        Common_SoundStoped();
    
        result = mastergroup->removeDSP(dsplowpass);
        ERRCHECK(result);
    
        result = mastergroup->removeDSP(dsppitch);
        ERRCHECK(result);
        result = mastergroup->removeDSP(dspnormalize);
        ERRCHECK(result);
    
        result = dsplowpass->release();
        ERRCHECK(result);
    
        result = dsppitch->release();
        ERRCHECK(result);
        result = dspnormalize->release();
        ERRCHECK(result);
    
        result = sound->release();
        ERRCHECK(result);
        result = system->close();
        ERRCHECK(result);
        result = system->release();
        ERRCHECK(result);
    
        Common_Close();
    
        return 0;
    }

    float Common_GetPropertyValue(int propertyIndex) {
    
        JNIEnv *gJNIEnv = getJNIEnv();
        jclass mainActivityClass = gJNIEnv->GetObjectClass(gMainActivityObject);
    
        gJNIEnv = getJNIEnv(); // Ensure valid JNIEnv
    
        float defaultValue = 1.0f;
        if (!gJNIEnv || !gMainActivityObject) {
            printf("JNI ERROR: Invalid JNIEnv or gMainActivityObject\n");
            return defaultValue; // Default value if invalid
        }
    
        if (!mainActivityClass) {
            printf("JNI ERROR: Failed to get class from gMainActivityObject\n");
            if (gJNIEnv->ExceptionCheck()) {
                gJNIEnv->ExceptionDescribe();
                gJNIEnv->ExceptionClear();
            }
            return defaultValue; // Default value if invalid
        }
    
        jmethodID methodID = gJNIEnv->GetMethodID(mainActivityClass, "fmodGetPropertyValue", "(I)F");
        if (!methodID) {
            printf("JNI ERROR: Failed to get method ID for fmodGetPropertyValue\n");
            gJNIEnv->DeleteLocalRef(mainActivityClass);
            return defaultValue; // Default value if method not found
        }
    
        float result = gJNIEnv->CallFloatMethod(gMainActivityObject, methodID, propertyIndex);
        if (gJNIEnv->ExceptionCheck()) {
            gJNIEnv->ExceptionDescribe();
            gJNIEnv->ExceptionClear();
            result = defaultValue; // Default value if exception occurs
        }
    
        gJNIEnv->DeleteLocalRef(mainActivityClass);
        return result;
    }
android c++ java-native-interface fmod
1个回答
0
投票

堆栈跟踪再清楚不过了:

gMainActivityObject
null
,但无论如何你都在调用GetObjectClass。将该调用移至
if (!gMainActivityObject)
复选框下。

© www.soinside.com 2019 - 2024. All rights reserved.