Android的怪异AudioTrack崩溃

问题描述:

我是一个Android应用程序开发人员,我在用下面的崩溃报告的麻烦(我得到了那些每天5/6):Android的怪异AudioTrack崩溃

native: pc 00000000000418e0 /system/lib/libc.so (tgkill+12) 
    native: pc 0000000000040d59 /system/lib/libc.so (pthread_kill+32) 
    native: pc 000000000001c7eb /system/lib/libc.so (raise+10) 
    native: pc 000000000001999d /system/lib/libc.so (__libc_android_abort+34) 
    native: pc 0000000000017550 /system/lib/libc.so (abort+4) 
    native: pc 0000000000008d53 /system/lib/libcutils.so (__android_log_assert+86) 
    native: pc 000000000006e2c3 /system/lib/libmedia.so (_ZN7android11ClientProxy13releaseBufferEPNS_5Proxy6BufferE+94) 
    native: pc 000000000006c11d /system/lib/libmedia.so (_ZN7android10AudioTrack13releaseBufferEPKNS0_6BufferE+112) 
    native: pc 000000000006c987 /system/lib/libmedia.so (_ZN7android10AudioTrack18processAudioBufferEv+1350) 
    native: pc 000000000006d7f3 /system/lib/libmedia.so (_ZN7android10AudioTrack16AudioTrackThread10threadLoopEv+194) 
    native: pc 0000000000010079 /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+112) 
    native: pc 000000000004065b /system/lib/libc.so (_ZL15__pthread_startPv+30) 
    native: pc 000000000001a021 /system/lib/libc.so (__start_thread+6) 

的函数调用世界。

这些都是存储在堆中的所有增值经销商:

/* OpenSL ES audio stuff */ 
SLObjectItf engineObject = NULL; 
SLEngineItf engineEngine = NULL; 
SLObjectItf outputMixObject = NULL; 
SLObjectItf playerObject = NULL; 
SLPlayItf playerPlay = NULL; 
SLVolumeItf playerVolume = NULL; 
SLAndroidSimpleBufferQueueItf playerBufferQueue = NULL; 
char  openSLinited = 0; 

int16_t  audioBuffer1[48000]; 
int16_t  audioBuffer2[48000]; 
int16_t *currentAudioBuffer; 

这是我是如何初始化所有机械:

void Java_com_myapp_myappname_MyActivity_jniOpenSLInit(JNIEnv *env, 
                 jobject thiz, 
                 jint freq) 
{ 
    SLresult result; 

    // create engine 
    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 
    assert(SL_RESULT_SUCCESS == result); 

    // realize the engine 
    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 
    assert(SL_RESULT_SUCCESS == result); 

    // get the engine interface, which is needed to create other objects 
    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, 
              &engineEngine); 
    assert(SL_RESULT_SUCCESS == result); 

    // create output mix 
    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 
               0, NULL, NULL); 
    assert(SL_RESULT_SUCCESS == result); 

    // realize the output mix 
    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); 
    assert(SL_RESULT_SUCCESS == result); 

    SLuint32 SLfreq; 
    if (freq == 44100) 
     SLfreq = SL_SAMPLINGRATE_44_1; 
    else 
     SLfreq = SL_SAMPLINGRATE_48; 

    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = 
     {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; 
    SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2, SLfreq, 
            SL_PCMSAMPLEFORMAT_FIXED_16, 
            SL_PCMSAMPLEFORMAT_FIXED_16, 
            SL_SPEAKER_FRONT_LEFT | 
            SL_SPEAKER_FRONT_RIGHT, 
            SL_BYTEORDER_LITTLEENDIAN}; 

    SLDataSource audioSrc = {&loc_bufq, &format_pcm}; 

    /* configure audio sink */ 
    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, 
              outputMixObject}; 
    SLDataSink audioSnk = {&loc_outmix, NULL}; 

    const SLInterfaceID idsAudioPlayer[2] = {SL_IID_BUFFERQUEUE, 
              SL_IID_VOLUME }; 

    const SLboolean reqAudioPlayer[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; 

    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, 
               &audioSrc, 
               &audioSnk, 2, idsAudioPlayer, 
               reqAudioPlayer); 
    assert(SL_RESULT_SUCCESS == result); 

    // realize the player 
    result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); 
    assert(SL_RESULT_SUCCESS == result); 

    // get the play interface 
    result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, 
              &playerPlay); 
    assert(SL_RESULT_SUCCESS == result); 

    // get the volume interface 
    result = (*playerObject)->GetInterface(playerObject, SL_IID_VOLUME, 
              &playerVolume); 
    assert(SL_RESULT_SUCCESS == result); 

    // get the buffer queue interface 
    result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE, 
              &playerBufferQueue); 
    assert(SL_RESULT_SUCCESS == result); 

    // register callback on the buffer queue 
    result = (*playerBufferQueue)->RegisterCallback(playerBufferQueue, 
                audio_player_cb, NULL); 
    assert(SL_RESULT_SUCCESS == result); 

    // done! 
    openSLinited = 1; 
} 

这就是所谓的启动机器。

void openSLStart() 
{ 
    bzero(audioBuffer1, 96000); 
    bzero(audioBuffer2, 96000); 

    if (!openSLinited) 
     return; 

    (*playerBufferQueue)->Enqueue(playerBufferQueue, audioBuffer1, 
            4096 * 4); 
    (*playerBufferQueue)->Enqueue(playerBufferQueue, audioBuffer2, 
            4096 * 4); 

    currentAudioBuffer = audioBuffer1; 

    // set the player's state to playing 
    (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING); 
} 

这是新入队的样品

void audio_player_cb(SLAndroidSimpleBufferQueueItf bq, void *context) 
{ 
    if (!openSLinited) 
     return; 

    assert(bq == playerBufferQueue); 
    assert(NULL == context); 

    // switch between audio buffer 1 and 2 
    if (currentAudioBuffer == audioBuffer1) 
     currentAudioBuffer = audioBuffer2; 
    else 
     currentAudioBuffer = audioBuffer1; 

    // this function read samples (4096 16 bit samples) from an internal buffer 
    sound_read_samples(4096, currentAudioBuffer); 

    // feed openSL machine 
    (*playerBufferQueue)->Enqueue(playerBufferQueue, currentAudioBuffer, 
            4096 * 2); 
} 

最后的回调,这是OpenSL是如何终止

void Java_com_myfirm_myappname_MyActivity_jniOpenSLTerm(JNIEnv *env, 
                 jobject thiz) 
{ 
    // shutdown every created object 
    if (playerObject) 
    { 
     // stop the player 
     SLresult result = (*playerPlay)->SetPlayState(playerPlay, 
                 SL_PLAYSTATE_STOPPED); 

     if (SL_RESULT_SUCCESS == result) 
      utils_log("Player succesfully stopped"); 

     (*playerObject)->Destroy(playerObject); 
     playerObject = NULL; 
     playerPlay = NULL; 
    } 

    if (outputMixObject) 
    { 
     (*outputMixObject)->Destroy(outputMixObject); 
     outputMixObject = NULL; 
    } 

    if (engineObject) 
    { 
     (*engineObject)->Destroy(engineObject); 
     engineObject = NULL; 
    } 

    openSLinited = 0; 

    utils_log("OpenSLTerm complete"); 
} 

我不能在我的手机和模拟器再现。它只是从来没有崩溃这种方式。

我跑出了有关如何解决这个问题的想法。有人可以帮我摆脱这个崩溃吗?

更新10月8日

我试过的建议删除日志。崩溃仍然存在。

问题影响的Android 6.0,7.0和7.1(至少,我得到了不同版本的报道)

更新10月9日

按照要求通过阿姆贾德汗:

这是生成库的Android.mk

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

LOCAL_MODULE := libmyapp-jni 
LOCAL_SRC_FILES := src.c src2.c src3.c 
LOCAL_LDLIBS := -llog -landroid -ljnigraphics -lGLESv2 -lOpenSLES 
LOCAL_CFLAGS += -O3 -DNDEBUG 

include $(BUILD_SHARED_LIBRARY) 

并且这是命令跑来构建l (所有ABI都生成)

/cygdrive/c/Android/ndk/ndk-build.cmd NDK_DEBUG=0 APP_BUILD_SCRIPT=./Android.mk NDK_PROJECT_PATH=. 

在此先感谢您。

+0

由于得到这个错误的牛轧糖和高版本,从本机.so文件删除所有日志尝试,我们在本地使用日志,以便文件也产生此故障Play商店中。 (utils_log)这种方法,你可以把[断言()]代码 –

+0

我试图删除日志...崩溃再次发生。它似乎影响Android 6,7.0和7.1。我真的失去了 –

+0

你可以添加你的Android.mk代码和ABI将支持 –

我看到了崩溃,它和我的崩溃是一样的,这是由于android日志产生的,最近我上传了apk并找到了相同的跟踪。

native: pc 0000000000048793 /system/lib/libc.so (pthread_kill+34) 
    native: pc 000000000001d5d5 /system/lib/libc.so (raise+10) 
    native: pc 0000000000019111 /system/lib/libc.so (__libc_android_abort+34) 
    native: pc 0000000000017174 /system/lib/libc.so (abort+4) 
    native: pc 000000000000c481 /system/lib/libcutils.so (__android_log_assert+112) 
    native: pc 0000000000025595 /system/lib/libhwui.so 
    native: pc 00000000000270d1 /system/lib/libhwui.so 
    native: pc 000000000002b959 /system/lib/libhwui.so (_ZN7android10uirenderer12renderthread12RenderThread10threadLoopEv+80) 
    native: pc 000000000000e35d /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140) 
    native: pc 000000000006830b /system/lib/libandroid_runtime.so (_ZN7android14AndroidRuntime15javaThreadShellEPv+102) 
    native: pc 0000000000048263 /system/lib/libc.so (_ZL15__pthread_startPv+22) 
    native: pc 0000000000019b5d /system/lib/libc.so (__start_thread+6) 

这个回溯是我最近的更新,所以我在我的本地文件中进行android日志打印。

__android_log_print(ANDROID_LOG_ERROR, "TRACKERS", "%s", Str); 

我用日志来检查时,我上传我得到了回溯打印我的数据,因此,我已删除了所有来自本地日志和从本地调用Java函数。

然后,之后我做了干净的构建和上传,因此在最新的版本是不是直到产生现在超过5构建上传

Android相关的日志支持

包含应用程序可以使用各种定义将日志消息从本机代码发送到内核。有关这些定义的更多信息,请参阅中的注释。

您可以编写自己的包装宏来访问此功能。如果你想执行日志记录,你的本地模块应该链接到/system/lib/liblog.so。

LOCAL_LDLIBS:通过在你的Android.mk文件中的以下行实现此链接= -llog

在这里,你也会找到办法容易找出错误本土

+0

我已经完全删除所有的日志。崩溃仍然存在。 –

+0

您是否正在尝试构建64位体系结构的文件,或者是否使用64位体系结构的外部库? –

+0

我已经为每个架构构建了这个库。在32位或64位都崩溃的事件 –