再谈实现
说到实现其实这并不是最需要关注的内容,因为上面提供了很全面的接口而我们的模块又是使用的接口所以不管如何实现那些功能并不会对各个模块之间产生大的影响除非功能实现与实际要求相差太多。这里我只详细说一下音频模块的实现。
音频实现
音频模块又可分为音频管理与音频业务逻辑。音频管理就是加载、播放、回收资源等功能,音频业务逻辑主要处理在正确的状态下应该播放什么样的音频。将整个音频管理模块放在Android Service中与业务逻辑完全分离。音频模块涉及以下类与接口:
- AudioService: 音频服务器继承Android Service
- IAudioService: 音频抽象接口包含播放、暂停等事件
- MediaPlayerHolder: 持有MediaPlayer管理MediaPlayer生命同期
- IAudioFlow: 为不同的训练内容提供音频逻辑
-
AudioServiceImpl: 实现IAudioService
基本使用流程是首先通过绑定AudioService的onBind方法返回IAudioService的实现类供IAudioFlow使用,IAudioFlow持有IAudioService实现后加载训练音频然后供ITrainerController使用。在AudioServiceImpl中会维持一个音频优化级队列,
上面提到因为音频都是不在一个文件中的所有需要在使用时将它们连接起来形成一段音频。通过优先级队列结合MediaPlayer播放完成时回调可以将多个音频组合在一起形成需要的音频。由于音频的播放越来越多MediaPlayer的回收利用特别重
要在AudioServiceImpl同样也具备MediaPlayer的回收与利用功能。这个功能实现是通过MediaPlayerHolder来处理的,通过MediaPlayerHolder的静态get方法获取MediaPlayerHolder如果回收池中有空闲的MediaPlayerHolder则拿来用没有时则
新建一个,同样也在一个音频播放完成后调用MediaPlayerHolder的recycle来进行回收利用。模块整合
为减少依赖模块之间的整合需提供管理或帮助类,新建TrainerHelper来创建模块实现类其中包含一个Mode枚举来列举训练模式。public class TrainerHelper { public enum Mode{TEST, TRAINING, EXAM} private static Mode mode; public static void setMode(Mode m){ mode = m; } public static ITrainerController createPresenter(ITrainerView view, Bundle createArgs){ return new TrainerPresenter(view,createArgs); } public static ITrainerModel createTrainerModel(ITrainerController controller){ return = new DefaultTrainerModel(bundle);; } public static IAudioFlow createTrainerAudioFlow(ITrainerController controller){ return new DefaultAudioFlow(controller); } }










