2017-09-25 33 views
7

Tôi là một nhà phát triển Android App và tôi đang gặp rắc rối với báo cáo tai nạn sau (tôi đã nhận 5/6 của những người mỗi ngày):AudioTrack lạ Android tai nạn

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) 

Các chức năng được gọi trong JNI thế giới.

Đó là tất cả các vars lưu trữ trong các đống:

/* 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; 

Đây là cách tôi đã khởi tạo tất cả các máy móc thiết bị:

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; 
} 

này được gọi để khởi động máy móc.

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); 
} 

Đây là callback mà enqueue mẫu mới

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); 
} 

Và cuối cùng, đây là cách OpenSL bị chấm dứt

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"); 
} 

tôi không thể tái tạo trên điện thoại của tôi và trên giả lập. .. Nó không bao giờ bị treo theo cách này.

Tôi đã hết các ý tưởng về cách khắc phục sự cố này. Ai đó có thể giúp tôi để thoát khỏi vụ tai nạn này?

cập nhật ngày 08 Tháng Mười

tôi đã cố gắng để loại bỏ các bản ghi theo đề nghị. Sụp đổ vẫn xảy ra.

Vấn đề ảnh hưởng đến Android 6.0, 7.0 và 7.1 (ít nhất, tôi đã không có báo cáo cho các phiên bản khác nhau)

cập nhật 09 tháng 10

Theo yêu cầu của Amjad Khan:

Đây là Android.mk tạo thư viện

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) 

và đây là lệnh chạy để xây dựng ibrary (tất cả ABI được tạo)

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

Cảm ơn bạn trước.

+0

Do gặp lỗi này trong Nougat và phiên bản cao hơn, hãy thử xóa tất cả nhật ký khỏi tệp .so gốc của bạn, chúng tôi đang sử dụng nhật ký gốc để tệp này cũng tạo ra sự cố này trong cửa hàng playstore. (utils_log) phương pháp này và u có thể đặt [khẳng định()] mã –

+0

Tôi đã cố gắng để loại bỏ các bản ghi ... Các vụ tai nạn occours một lần nữa. Dường như nó ảnh hưởng đến Android 6, 7.0 và 7.1. Tôi thực sự bị mất –

+0

Bạn có thể thêm mã Android.mk của mình và ABI sẽ hỗ trợ –

Trả lời

1

Tôi đã thấy sự cố giống như sự cố của tôi được tạo do nhật ký Android, gần đây tôi đã tải lên apk và tìm thấy cùng một dấu vết.

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) 

Backtrace này là bản cập nhật gần đây của tôi vì vậy tôi đã thực hiện in nhật ký android trong tệp gốc của mình.

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

Tôi đã in dữ liệu của tôi sử dụng các bản ghi để kiểm tra khi tôi tải lên tôi đã backtrace rằng, Vì vậy, tôi đã gỡ bỏ tất cả các bản ghi từ nguồn gốc và chức năng java được gọi là từ nguồn gốc.

Sau đó, Sau khi tôi đã làm sạch sẽ xây dựng và tải lên, vì vậy trong phiên bản mới nhất nó không phải được tạo ra cho đến bây giờ hơn 5 build tải lên

Android cụ thể hỗ trợ đăng nhập

chứa các định nghĩa khác nhau mà một ứng dụng có thể sử dụng để gửi thông điệp tường trình tới hạt nhân từ mã gốc. Để biết thêm thông tin về các định nghĩa này, hãy xem các bình luận trong.

Bạn có thể viết macro trình bao bọc của riêng mình để truy cập chức năng này. Nếu bạn muốn thực hiện ghi nhật ký, mô-đun gốc của bạn nên liên kết đến /system/lib/liblog.so. Thực hiện liên kết này bằng cách đưa dòng sau trong file Android.mk của bạn:

LOCAL_LDLIBS: = -llog

Và đây u sẽ tìm ra cách để dễ dàng tìm ra các lỗi có nguồn gốc

+0

Tôi đã xóa hoàn toàn TẤT CẢ nhật ký. Tai nạn vẫn xảy ra. –

+0

Bạn đang cố gắng xây dựng các tập tin như vậy cho kiến ​​trúc 64bit hoặc bạn r bằng cách sử dụng thư viện bên ngoài cho kiến ​​trúc 64bit? –

+0

Tôi đã xây dựng thư viện cho mọi kiến ​​trúc. Sự cố xảy ra ở cả 32 hoặc 64 bit –