当前位置: 首页 > news >正文

MVVM模块化架构

  1. 原文 我放在Github上啦,Github上会第一时间更新文章
  2. 这次的MVVM不是传统上的,而是需要配合Google的 ViewModel,LiveData使用的。
  3. 严重使用了 Dagger2,轻度依赖了ARouter。

ViewModel

  1. ViewModel 是要交给 Dagger 来管理的,比如:

    class UserActivityVM @Inject constructor(application: Application): BaseViewModel() {}
    复制代码
  2. ViewModel 不知道它是给哪个 View (MVVM中的V)提供服务的,也就是说它不能持有 Activity 实例,甚至不能有Context出现,当然ApplicationContext除外。

  3. ViewModel的生命周期是要比 Activity/Fragment 长的,所有 ViewModel 中的对 View 的更新都使用 LiveData 让 View 订阅更新。

View

  1. 使用 Dagger2 将需要的 ViewModel Inject进来,因为这个是通用操作,可以写在 BaseActivity/BaseFragment中,例如:

    @Inject
    lateinit var factory: ViewModelProvider.Factory
    
    val viewModel: T by lazy {
        val observer = ViewModelProviders.of(this, factory).get((javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>)
        lifecycle.addObserver(observer)
        observer
    }
    复制代码
  2. 在 Activity/Fragment 中订阅 ViewModel 中的 LiveData,以获取需要的数据。比如:

    viewModel.nickName.observe(this, Observer { if (null != it) nickName.text = it })
    复制代码
  3. Activity/Fragment 不能调用 ViewModel中的耗时方法(因为ViewModel的生命周期是比View长的),Activity/Fragment 从 ViewModel 获取的所有数据都只能通过 LiveData 获取,而不能直接调用返回结果。

  4. 番外:在View中使用SimplifyDagger可以少些好几吨 Dagger 代码。

模块化

  1. 一些公用模块,比如 Utils,Resources,Widgets等业务逻辑无关的,可以被其他任何一个模块依赖。
  2. 创建 DaggerModule,用来管理所有业务模块。
  3. 业务模块A,B,C等,互相之间不能有依赖关系,全部被DaggerModule依赖。

模块间通信(api化)

  1. 若模块A想暴露某个功能给其他模块使用,则在_apis_文件夹下写一个 interface,然后在其他地方实现这个 interface,然后交给 dagger:

    @AppScope
    @Binds
    public abstract UserInfo privideUserInfo(UserInfoImpl impl);
    复制代码
  2. _apis_文件夹暴露出去:

    1. gradle脚本

      apply plugin: 'maven-publish'
         
         task sourceJar(type: Jar) {
             from fileTree(dir: "${project.projectDir.absolutePath}/build/intermediates/javac/debug/classes", include: '**/_apis_/**/*.class')
             from fileTree(dir: "${project.projectDir.absolutePath}/build/tmp/kapt3/incrementalData/debug", include: '**/_apis_/**/*.class')
         }
         
         publishing {
             publications {
                 bar(MavenPublication) {
                     groupId 'io.github.hurshi'
                     artifactId project.name
                     version '1.0'
                     artifact(sourceJar)
                 }
             }
             repositories {
                 maven {
                     url "${rootProject.projectDir.absolutePath}/repo"
                 }
             }
         }
      复制代码
    2. shell 脚本

      ../gradlew clean -p ../
      ../gradlew assembleDebug -p ../
      ../gradlew publish -p ../
      复制代码
    3. 在需要使用这个模块的 build.gradle 中添加:

      compileOnly "io.github.hurshi:UserInfo:1.0"
      复制代码
    4. 这样,我们就将_apis_文件夹下的 interface 都暴露出去了,以此完成模块间的通信。

  3. 模块间通信原理:我们写一个 interface,然后把实现这个 interface 的实例Z交给 dagger,当其他模块拿着这个interface 问dagger要实例的时候,dagger 就会把实例Z返回,其实是Dagger在帮你把实例Z从模块A拿到了其他模块。而_apis_相当于把实例Z的"key"拿到了其他模块(interface相当于是实例Z的"key").

转载于:https://juejin.im/post/5bfba0a96fb9a049ab0d49e1

相关文章:

  • EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery
  • 随手记统一监控平台Focus设计解析
  • Centos7 系统启动docker报错 inotify add watch failed
  • 以OpenGL/ES视角介绍gfx-hal(Vulkan) Texture接口使用
  • 阿里云应用高可用服务公测发布
  • JAVA入门到精通-第57讲-SQLserver数据类型
  • 利用keepalived实现高可用nginx(修改正)
  • iPhone XS JavaScript性能飙升背后的秘密
  • Java 基础语法
  • 变频电源是什么,变频电源的基础知识的认识
  • springboot配置Druid数据源
  • 红帽高级总监谈OpenJDK的未来:Java的未来从未如此光明
  • 如何设置计算机IP地址
  • expect接收命令行传递的参数并设置为变量和打印变量的值
  • rsync同步数据---把左边的文件全部拷贝到右边
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Javascript编码规范
  • JS函数式编程 数组部分风格 ES6版
  • js写一个简单的选项卡
  • NSTimer学习笔记
  • Service Worker
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • Windows Containers 大冒险: 容器网络
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 从零开始的无人驾驶 1
  • 老板让我十分钟上手nx-admin
  • 每天10道Java面试题,跟我走,offer有!
  • 时间复杂度与空间复杂度分析
  • 以太坊客户端Geth命令参数详解
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​决定德拉瓦州地区版图的关键历史事件
  • ###STL(标准模板库)
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (003)SlickEdit Unity的补全
  • (第一天)包装对象、作用域、创建对象
  • (二)斐波那契Fabonacci函数
  • (二)丶RabbitMQ的六大核心
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (一)Linux+Windows下安装ffmpeg
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • *2 echo、printf、mkdir命令的应用
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .net CHARTING图表控件下载地址
  • .NET CORE Aws S3 使用
  • .NET MVC 验证码
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .NET中的Exception处理(C#)