为啥 AudioFlinger 在没有编程指示的情况下会失败?

Posted

技术标签:

【中文标题】为啥 AudioFlinger 在没有编程指示的情况下会失败?【英文标题】:Why does AudioFlinger fail without programmatic indication?为什么 AudioFlinger 在没有编程指示的情况下会失败? 【发布时间】:2011-03-09 07:56:02 【问题描述】:

我遇到了 SoundPool 崩溃的问题,但没有给出崩溃的程序指示。崩溃后,它不会再播放任何声音,直到重新加载应用程序(通过后退按钮退出然后重新启动是不够的)。 LogCat 给了我这些错误信息:

AudioFlinger: no more track names availlable [sic]
AudioTrack: AudioFlinger could not create track, status: -12
SoundPool: Error creating AudioTrack

然而,尽管有这些错误,SoundPool.play() 仍然返回一个正整数,对于每个新的播放请求都会递增,根据文档,这表明没有错误。其他人为此问题发起了一个问题: http://code.google.com/p/android/issues/detail?id=13453

...但是,没有任何回应。下面的代码是一个极简的 Activity,它始终如一地重现这个问题。只需新建一个Android项目,将LinearLayout的ID设置为main_bg,将TextView的ID设置为main_tv,在res/raw中添加一个名为ding的声音文件。声音文件需要足够长,在第一个声音完成之前点击屏幕四次;我的是 1.7 秒 22050 Hz 单声道 MP3 @ 96kbps。短暂的停顿后,第五次点击会通过 LogCat 生成上面的错误信息。或者,您可以单击多次,直到声音停止播放。

我已经测试了在运行 Android 1.6 的 T-Mobile G1 上出现的错误消息,但它们不会出现在 1.6 模拟器、2.1 模拟器或 2.2 模拟器上。

有谁知道如何解决这个问题,或者 SoundPool 对于 G1 上的同步音效毫无价值?

代码:

public class SoundTestActivity extends Activity implements OnClickListener 
   private  SoundPool mSoundPool; 
   private  HashMap<Integer, Integer> mSoundPoolMap; 
   private  int index = 0;

   @Override
   public void onCreate(Bundle savedInstanceState) 
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      findViewById(R.id.main_bg).setOnClickListener((OnClickListener)this);

      initSounds();
      mSoundPoolMap.put(index, mSoundPool.load(getApplicationContext(), R.raw.ding, 1));
   

   public void initSounds()  
      mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); 
      mSoundPoolMap = new HashMap<Integer, Integer>();           
   

   @Override
   public void onClick(View v) 
      int result = mSoundPool.play(mSoundPoolMap.get(index), 0.99f, 0.99f, 1, 0, 1f);
      ((TextView)findViewById(R.id.main_tv)).setText(Integer.toString(result));
    

【问题讨论】:

【参考方案1】:

只是猜测,但我不喜欢这个外观...

findViewById(R.id.main_bg).setOnClickListener((OnClickListener)this);

当您执行此操作时,会找到并膨胀视图,允许您使用 setOnClickListener() 但它没有分配给任何东西。我猜在某个时候它正在被垃圾收集,这可能会导致您的问题。

你的描述说它是一个线性布局?如果是这样,试试这个...

public class SoundTestActivity extends Activity implements OnClickListener 
    private SoundPool mSoundPool; 
    private HashMap<Integer, Integer> mSoundPoolMap; 
    private int index = 0;
    private LinearLayout ll = null; // ADD THIS!!!

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ll = findViewById(R.id.main_bg); // ASSIGN TO ll
        ll.setOnClickListener((OnClickListener)this); // SET LISTENER

【讨论】:

UI 问题会如何影响 AudioFlinger?并且 main_bg 不会被垃圾收集;它仍然被用户界面的其余部分引用。您突出显示的行很好。

以上是关于为啥 AudioFlinger 在没有编程指示的情况下会失败?的主要内容,如果未能解决你的问题,请参考以下文章

为啥活动指示器在 Xamarin.forms 中不起作用?

如何解决 AudioFlinger 服务器死机!安卓系统出错?

为啥这个 MotionEvent 模拟不起作用?

为啥控制忙指示灯不起作用

Android音频系统之AudioFlinger

为啥在 Windows 和 Linux 机器之间复制 repo 后 Git 会指示更改?