2016-02-17 8 views
3

Мне интересно, нужно ли мне звонить на аудиодорожку?Выпуск AudioTrack

Например, в моем следующем коде я создаю экземпляр AudioTrack в методе и не вызываю release на нем (потому что это прекращает воспроизведение).

Каковы последствия этого?

public void playTone() 
{ 
    float[] output = createTone(); 

    AudioTrack track = new AudioTrack(AudioManager.STREAM_RING, 44100, 
      AudioFormat.CHANNEL_OUT_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, 
      (output.length*4), 
      AudioTrack.MODE_STATIC); 

    short[] result = new short[output.length]; 

    for(int i = 0; i < output.length; i++) 
     result[i] = (short) ((output[i])*32768); 

    track.write(result, 0, output.length); 
    track.play(); 
} 

ответ

1

Если вы не вызываете Release(), вы будете течь родной памяти за объектом Java аудиодорожки. AudioTrack не все полностью Java, поэтому вызов требуется, чтобы позволить собственному коду освобождать свою собственную память, потому что это не будет собирать мусор.

Вы должны всегда вызывать release(), когда это сделано, чтобы избежать проблем, связанных с потреблением слишком большого объема памяти в вашем приложении.

2

Это вызывает временную утечку ресурсов, но не постоянную. В конце концов сборщик мусора выпустит всю память и ресурсы. Но вы можете позвонить release(), чтобы избежать ошибок, потому что «в конечном итоге» может быть недостаточно.

Я проверил на устройстве Android 4.4.2, что когда потоковое AudioTrack больше не ссылается нигде, и выполняется сбор мусора, он будет завершен, независимо от того, был вызван или нет stop().

В исходном коде Android, (я посмотрел на Android N в), finalize()calls the same native function, как release() делает:

static void android_media_AudioTrack_finalize(JNIEnv *env, jobject thiz) { 
    //ALOGV("android_media_AudioTrack_finalize jobject: %x\n", (int)thiz); 
    android_media_AudioTrack_release(env, thiz); 
} 

Так что да, в конце концов, ресурсы будут освобождены без необходимости вызывать release() явно.

Но это может быть проблемой, если слишком много AudioTrack s создаются за короткий период времени. Создание и разыменования их в цикле:

for (...) { 
    new AudioTrack(...); 
} 

В конце концов я получаю эту ошибку в моих журналах:

E/AudioTrack-JNI: Error initializing AudioTrack 
E/android.media.AudioTrack: Error code -20 when initializing AudioTrack. 
E/AudioTrack: AudioFlinger could not create track, status: -12 

сбор мусора не исправить; он не был запущен, потому что было достаточно обычной памяти кучи. Другие ресурсы, типа выпуска release(), закончились. Эта ошибка не вызывала непосредственную сборку мусора. Вызов release(), конечно, устраняет эту проблему.

 Смежные вопросы

  • Нет связанных вопросов^_^