AudioFocus是自Android 2.3建立起来的一个新的机制。这套新机制的目的在于统一协调多个回放实例之间的交互。
我们知道,手机的多媒体功能越来越强大,听音乐、看视频、听收音机已经成为这台小小的设备的重要功能。加上手机本身的闹铃、信息通知以及电话铃声等,一台手机中有很多情况需要播放音频。我们称每一次音频播放为一次回放实例。这就需要我们能够对这些回放实例的并发情况做好协调,否则就会出现多个音频不合理地同时播放的恼人结果。
在2.3以前,Android并没有一套统一的管理机制。每个音频回放实例只能通过发送广播的方式告知其他人自己的播放状态。这不仅造成了广播满天飞的情况,而且可扩展性与一致性非常差,基本上只能在同一厂商的应用之间使用。好在,Android 2.3对AudioFocus的引入大大地改善了这个状况。
AudioFocus的含义可以和Windows的窗口焦点机制做类比,只不过我们的焦点对象是音频的回放实例。在同一时间,只能有一个音频回放实例拥有焦点。每个回放实例开始播放前,必须向AudioService申请获取AudioFocus,只有申请成功才允许开始回放。在回放实例播放结束后,要求释放AudioFocus。在回放实例播放的过程中,AudioFocus有可能被其他回放实例抢走,这时,被抢走AudioFocus的回放实例需要根据情况采取暂停、静音或降低音量的操作,以突出拥有AudioFocus的回放实例的播放。当AudioFocus被还回来时,回放实例可以恢复被抢走之前的状态,继续播放。
总体上来说,AudioFocus是一个没有优先级概念的抢占式的机制。在一般情况下后一个申请者都能从前一个申请者的手中获取AudioFocus。不过只有一个例外,就是通话。通话作为手机的首要功能,同时也是一种音频的播放过程,所以从来电铃声开始到通话结束这个过程,Telephony相关的模块也会申请AudioFocus,但是它的优先级是最高的。Telephony可以从所有人手中抢走AudioFocus,但是任何人无法从它手中将其夺回。这在后面的代码分析中可以看到。
值得一提的是,AudioFocus机制完全是一个建议性而不是强制性的机制。也就是说,上述的行为是建议回放实例遵守,而不是强制的。所以,市面上仍有一些带有音频播放功能的应用没有采用这套机制。