一、架构模式-MVP

当前项目采用的是MVP(Model-View-Presenter)架构模式,改善了原版本简易MVP的架构方式(原MVP架构其实是VP架构——Presenter层承担了Model的工作)。


二、Project-模块化

为了各个功能模块之间解耦、便于团队协作开发及后期维护,本次新版将原有的双Module架构升级为更加细致的多Module架构,各Module命名及释义如下:

  • app
    App入口,一般只包含Application、SplashActivityMainActivity
  • base
    标准基础库,新项目可以直接使用进行开发,不涉及项目中的相关业务,一般只包含能够在各个项目中直接通用的基础类。
    如:相关的Base类、基础的Log类等。
  • common
    公共资源库,base库的补充。部分工具类、UI组件等根据项目需求抽取集成,但不会涉及到具体的业务逻辑。
    如:公用的Util类、自定义的各种控件、常量类等。
  • component-xxx
    部件/成分库(也叫Project组成部分),提供基础的功能实现,但不涉及具体的业务。
    如:网络请求(component-net)、视频播放(component-video)等等。
  • module-xxx
    业务功能库,提供完整的业务功能实现及对应的UI效果展示。
    如:我的(module-mine)、推拿(module-mass)等。

Android Project组件化架构图

三、屏幕(分辨率适配)

依据实际的UI设计图,我们以sw-375dp为基准进行屏幕的适配工作,相应适配文件存放于base->res/values、values-swxxxdp/measure.xml内。
在实际开发中根据UI设计图尺寸直接设置对应控件的尺寸即可(@dimen/common_measure_xxxdp),具体使用示例如下:

// 在需要使用地方添加对应的尺寸
android:layout_height="@dimen/common_measure_xxxdp"

四、项目中三方库使用规范及示例

  • Java 8
    项目原则上是基于Java 8,我们使用到的部分库(ButterKnife、Retrofit、ARouter等)中也使用了Java 8的特性(比较常见的是Lambda表达式),为了确保能够正常的编译使用,我们必须在对应Module/build.gradle文件中手动添加Java 8支持,具体如下:
    android {
        ...
        compileOptions {
          sourceCompatibility JavaVersion.VERSION_1_8
          targetCompatibility JavaVersion.VERSION_1_8
        }
        ...
    }
    
  • ButterKnife
    • 概述
      一个专注于Android系统的View依赖注入框架,省去了findViewById、setOnClickListener等重复代码,简化代码、提高开发效率。
    • 使用规范
      这里我们使用的是ButterKnife-10.2.3版本,区别于app中使用的R.id.xxx映射方式,在Module/Library中需要通过R2.id.xxx去映射对应的控件。
    • 示例
          @BindView(R2.id.mine_iv_icon)
          RoundImageView mIvIcon;
      
    • 注意事项
      在使用该库的每个类的build.gradle文件中要添加如下配置:
      apply plugin: 'com.android.library'
      apply plugin: 'com.jakewharton.butterknife'
      
          dependencies {
              ...
              annotationProcessor rootProject.ext.dependencies['butterknife-compiler']
              ...
          }
      
  • ARouter
    • 概述
      一款阿里开源的路由框架,是一个帮助Android进行模块化、组件化开发的开源库。它支持模块间的路由、通信、解耦。
    • 使用规范
      在开发过程中,当我们对要进行跳转的页面上添加支持路由的注解时,我们需要遵循以下规则:
      路径需要注意的是至少需要有两级,/xx/xx,我们以/moduleName/className为基准进行对应的命名
    • 使用示例
          @Route(path = "/mine/mineActivity")
          public class MineActivity{
          ...
          }
          ```
      
    • 注意事项
      在使用该库的每个类的build.gradle文件中要添加如下配置:
      android {
          ...
          defaultConfig {
              ...
              // ARouter--每个使用到路由的Module必须加
              javaCompileOptions {
                  annotationProcessorOptions {
                      arguments = [AROUTER_MODULE_NAME: project.getName()]
                  }
              }
              ...
          }
          ...
      }
      dependencies {
          // ARouter--每个使用到路由的Module必须加
          annotationProcessor rootProject.ext.dependencies['arouter-compiler']
      }
      

五、数据存储

  • SQLite
    一个轻量级的数据库。数据库操作Helper类,放置在common中,相关的常量Key类也可以放置在common,其它具体的表操作由各个Module自行维护。
  • SharedPreferences
    一个轻量级的存储类,解决在开发过程中我们需要保存一些简单的、轻量的数据。如:用户设置、一些开关/判断的标记等,这些需要保存的数据往往可能只是一两个字符,这种数据我们使用SharedPreferences保存即可。
    放置在common中,相关的常量Key类也可以放置在common.
  • Native Files
    当我们在开发过程涉及到一些需要缓存的文件时,很多应用采取的策略是到SD卡的根目录上创建自己的文件夹然后保存到对应的文件路径下(之前的泰邦设计也是这样做的),虽然达到了缓存文件的目的,但它并不被Android所推荐——当应用卸载后,这些被创建的文件夹仍然存在,造成手机内多出了不少的垃圾文件,这样是极不友好的。
    Android建议我们在缓存文件时使用应用专属(这里又分内部存储与外部存储,建议是尽可能使用外部存储进行缓存)的缓存路径进行文件的缓存,当应用被卸载后,这些数据也会随之而消失,从而规避了上述问题。
    关于应用专属内、外部存储的更多了解,建议阅读以下文章或自行了解后再进行相关的操作:
    彻底搞懂Android文件存储---内部存储,外部存储以及各种存储路径解惑
    Android文件缓存目录
    重点关注:getExternalCacheDir、getExternalFilesDir

六、Other

未完待续...