我想知道我是否需要在音频轨道上调用发布?
例如,在下面的代码中,我在方法中实例化了一个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();
}发布于 2016-02-17 01:00:57
如果不调用release(),就会泄漏Java AudioTrack对象后面的本机内存。AudioTrack并不完全是Java,因此需要调用才能让本机代码释放自己的内存,因为它不会被垃圾收集。
在完成时,您应该始终调用related (),以避免在应用程序中消耗过多内存所带来的问题。
发布于 2016-12-04 19:51:18
这会导致暂时的资源泄漏,但不是永久性的。最终,垃圾收集器将释放所有内存和资源。但是您可能需要调用release()来避免错误,因为“最终”可能还不够快。
我已经在一个Android4.4.2设备上验证了,当流AudioTrack不再在任何地方被引用,并且垃圾收集被运行时,无论是否调用了stop(),它都将最终完成。
在Android的源代码中(我查看了Android),finalize() 调用同一个本机函数。和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,这可能会成为一个问题。在循环中创建和取消引用:
for (...) {
new AudioTrack(...);
}我最终在日志中得到了这个错误:
E/ AudioTrack :初始化AudioTrack E/android.media.AudioTrack:初始化AudioTrack时出错代码-20。E/AudioTrack: AudioFlinger无法创建轨道,状态:-12
垃圾收集没有修复这个问题;它没有运行,因为有足够的普通堆内存可用。release()发布的其他资源耗尽了。此错误没有立即触发垃圾回收。当然,调用release()解决了这个问题。
发布于 2018-12-16 17:04:38
“.(因为那样会停止播放):”如果您使用release(),您必须非常确定所有的事情都已经完成,并且目前没有使用该轨道。play()似乎启动了一个线程。所以
track.play(); // AudioTrack.MODE_STATIC or AudioTrack.MODE_STREAM track.release();
大部分都会失败,开始演奏。
https://stackoverflow.com/questions/35445969
复制相似问题