当前位置: 首页 > 编程笔记 >

完整的Android MVP开发之旅

子车雅珺
2023-03-14
本文向大家介绍完整的Android MVP开发之旅,包括了完整的Android MVP开发之旅的使用技巧和注意事项,需要的朋友参考一下

开发背景
最近是在做一个与健身相关的APP,里面有训练器模块基本功能是按照特点动作的演示和描述来引导用户完成训练。在第一个版本时由于没接触过些类项目与功能花了几周的时间大概1500行代码才完成这个功能,
当时虽然我已经尽量让代码表现的清晰,但是可以想像到当一个Activity中包含这么多代码是什么感觉。自己维护起来都难受。

先谈设计
有了前一次设计经验此次开发使用MVP、模块化、面向接口等概念,将整个训练器分为控制器、数据模型、音频、视图、可训练对象五个模块分别用以下接口表示:

  • ITrainerController
  • ITrainerModel
  • IAudioFlow
  • ITrainerView
  • ITrainable

去掉一些抽象类后接口图如下:

设计以上接口后引入MVP概念使用ITrainerController做为Presenter,ITrainerModel做Model,ITrainerView做View下面介绍主要模块。

控制器
可以用在MVC和MVP中这取决于用哪种开发模式,在我开发的项目控制器用来控制训练器的运行管理训练器的生命周期如训练、暂停、休息、完成等状态协调ITrainerModel、ITrainerView、IAudioFlow等各个模块。
在使用过程中控制器并不止一个这也是抽象出一个接口的原因,ITrainerController接口继承IPresenter接口使其能做为Presenter使用。

数据模型
数据模型中包含大量的ITrainable对象,对内组织数据对外提供数据支持。对数据的组织方式主要分两种:

在训练器中可能是正常的训练或是一次训练测试而训练数据和测试数据又有一些差异但它们的数据都被当做ITrainable,测试数据是不需要保存的只需要从服务器拉取后按要求完成就行而训练是会产生本地记录的。
针对不同数据组织方式提供不同的数据模型这是有必要的。

音频
音频比较多样化像训练过程中包含动作名、时间、单位词、提醒等音频这些音频都是分开的不同的音频文件。Android主要有两种实现方式:

  • SoundPool
  • MediaPlayer

首先说SoundPool优点自然就是免去了加载、管理音频等过程但是它并不适应我们的训练器,主要原因是缺少准备、完成后的一些回调而在训练器运行过程中这些过程必不可少比如在播放完一段预备开始后音频这时我们才能进行正式的训练。
最后是采用MediaPlayer,但是在使用过程又要考虑到音频的集中管理与资源的释放免不了多封装一次。设计时我将全部音频逻辑放在Android Service中Activity通过bind AudioService来使用音频,将音频逻辑放入AudioService这样可以音频完
全独立起来使其能在后台播放并且也可以提高进程优先级。

在设计中AudioService仅仅播放与管理音频和资源并不具备音频播放的逻辑功能。由于不同的训练方式音频的播放逻辑也有不同之处所以在此设计IAudioFlow接口来负责音频逻辑。

训练视图
Android常用Activity作为视图,通过实现ITrainerView接口来完成训练视图的显示。视图中不包含任何业务逻辑代码

再谈实现
说到实现其实这并不是最需要关注的内容,因为上面提供了很全面的接口而我们的模块又是使用的接口所以不管如何实现那些功能并不会对各个模块之间产生大的影响除非功能实现与实际要求相差太多。这里我只详细说一下音频模块的实现。

音频实现
音频模块又可分为音频管理与音频业务逻辑。音频管理就是加载、播放、回收资源等功能,音频业务逻辑主要处理在正确的状态下应该播放什么样的音频。将整个音频管理模块放在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);
  }

}

总结
成功的设计与架构能减少大量的工作时间,利用接口可让开发人员更加注重功能上的实现同时隔离各个模块之间的依赖。下次产品经理再改需求或再整出个训练模式时咱也能从容应对。

由于本人水平有限如有错误,请大家谅解。

 类似资料:
  • 本文向大家介绍iOS开发之TableView实现完整的分割线详解,包括了iOS开发之TableView实现完整的分割线详解的使用技巧和注意事项,需要的朋友参考一下 前言 在我们创建一个tableView的时候,细心的你有没有发现UITableViewCell左侧会有空白。而我们在开发中有这样的需求: 需要一根完整的分割线(去掉烦人的空白部分, 即分割线的宽度 == 屏幕的宽度)。 那么下面我就讲一

  • 前面两节,我们分别看过了如何开发可视化部分和服务器端部分。现在,我们把这两头综合起来,做一个可以在 Kibana 菜单栏上切换使用的,完整的 app。就像 Kibana 5 默认分发的 timelion 和 console 那样。 当然我们这里不会真的特意搞一个很复杂的可视化应用。我们只做一个 Elasticsearch 状态展示页面就好了。这个方式正好可以串联从前到后的请求、展示部分。 app

  • 本文向大家介绍利用node.js开发cli的完整步骤,包括了利用node.js开发cli的完整步骤的使用技巧和注意事项,需要的朋友参考一下 CLI介绍 命令行界面(英语:command-line interface,缩写:CLI),是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行。 目前前端开发中,CLI是常用的工具。前端三大

  • 本文向大家介绍php微信开发之自定义菜单完整流程,包括了php微信开发之自定义菜单完整流程的使用技巧和注意事项,需要的朋友参考一下 一、自定义菜单概述 自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。开启自定义菜单后,公众号界面如图所示: 二、申请自定义菜单 个人订阅号使用微博认证、企业订阅号通过微信认证;可以申请到自定义菜单资格 服务号默认有菜单权限。 三、获得AppId 和

  • 本文向大家介绍Android开发之超强图片工具类BitmapUtil完整实例,包括了Android开发之超强图片工具类BitmapUtil完整实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android开发之超强图片工具类BitmapUtil。分享给大家供大家参考,具体如下: 说明:为了方便大家使用,本人把大家常用的图片处理代码集中到这个类里 使用了LruCache与SoftRefe

  • 本文向大家介绍JavaWeb开发之Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架,包括了JavaWeb开发之Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架的使用技巧和注意事项,需要的朋友参考一下 简单介绍一下,本框架的基本功能点