大数跨境
0
0

【融云分析】融云 SealTalk 优化之路- Android JetPack

【融云分析】融云 SealTalk 优化之路- Android JetPack 融云全球互联网通信云
2019-09-05
0
导读:本文结合融云 SealTalk Demo, 介绍了如何利用新一代的 Android JetPack 组件构建架构清晰,低耦合度 APP 的过程。

内容简介:
本文结合融云 SealTalk Demo, 介绍了如何利用新一代的 Android JetPack 组件构建架构清晰,低耦合度 APP 的过程。融云 SealTalk 支持应用内社交等场景,体验单群聊、聊天室、音视频通话、红包、小视频、动态表情等通讯能力,供大家下载体验。

 
 
| 架构选择
 
融云开源项目 SealTalk 最近进行了重构,旧版 SealTalk 是采用的 MVC 架构,  而新版本我们采用了MVVM 架构。
 
为什么选择 MVVM
 
旧版存在的问题

 
SealTalk 在旧版中采用了 MVC 架构, Activity 和 Fragment 充当了 Controller 层,因此在旧版 SealTalk 中存在以下几点问题。
 
 在 Controller 层(即 Activity 和 Fragment ) 会需要编写大量的异步操作( 网络请求或数据库查询等) 使Activity 和 Fragment 代码逻辑量大,非常臃肿。

在 Activity 和 Fragment 需做大量的异步请求,需对请求做管理操作,确保页面销毁时理清操作,否则可能会造成内存泄漏。

多地方使用相同数据时,当数据( 例如个人信息或好友信息、群信息等, 多个页面都有使用到)有改动, 就必须主动去同步,造成逻辑大量重复并增大了逻辑难度。

 复用性比较差, 耦合度比较高。
 
为什么不选择 MVP


MVP 架构是在 MVC 架构基础上的优化,把 Activity 和 Fragment 的逻辑操作、异步请求等都提取出来, 作为 Presenter 层。而 Activity 和 Fragment 则作为了 View 层负责界面的展示刷新。

Presenter 层通过定义回调接口,把数据的操作返回给 View 层。通过结构图可以看出, View 和 Model 没有直接的交互,  都是通过 Presenter 层进行操作, 实现了 View 层和 Model 层的解耦。
 
假如 SealTalk 选用 MVP 结构,将网络请求和逻辑放到对应的 Presenter 中处理, 减少Activity 和 Fragment 的负担。

通过配合使用 Rxjava 绑定生命周期,也可避免页面销毁造成的内存泄漏问题。但是 Presenter 层和 View 交互是通过定义接口来进行的,这可能意味着需要定义大量接口,灵活性和复用性比较差。并且对于多处使用相同信息这种情况,其和 MVC 模式 一样, 也需主动拉取数据进行同步,并且 Presenter 层还持有了 View 的 this , 耦合度较高。
 
根据 SealTalk 的业务情况,MVP 相对于 MVC 的架构模式会比较好 一些, 但是还是有数据同步等问题没有很好的解决。
 
MVVM 的优势
 

MVVM 分为 View, Model 和 ViewModel 三层。
 
MVVM 最大的特色是双向绑定,并且是以数据来进行驱动。View 层可以通过 ViewModel 和数据绑定,当 Model 发生变化时,ViewModel 则会把最新数据发送给 View, 从而解决同一数据发生改变其他地方需要主动拉取数据的问题。
 
同一个 ViewModel 可以复用到多个 View 中, View 也可以使用多个 ViewModel。并且 ViewModel 只需要关注数据和业务逻辑,不需要和 UI 或者控件打交道。UI 可以更具自己的需求去订阅不同的数据,这就进一步实现了 View 和 ViewModel 的解耦, 并且提高了复用性。
 
选择 MVVM 的另一个重要原因是 Google 官方推出了 Architecture 组件, 给快速搭建 MVVM 提供一套规范,节省了开发成本。
 
Android 官方提供的 MVVM 规范
 
Android JetPack
Android JetPack 是 Google 提供的一套依赖库、工具集和开发指南。主要是为帮助开发者更轻松的编写高质量量的应用程序。
 
其组件都包含在 androidx.* 库中. androidx.* 从平台中分离出来作为单独的库来维护。这意味着 androidx.* 可向后兼容,它可不随着平台而发布,可独立更新升级,这有利于开发者能快速使用上更新的、更稳定的依赖库。
 
使用条件:
AndroidStudio 版本需升级到 3.2 及以上版本
 SDK targetVersion 版本需至少为 26
 
Architecture 组件
Google 在 Android JetPack 整合了之前的 Architecture 组件。Architecture 组件中, 提供了在 Android 开发应用使用 MVVM 的规范。
 
Google推荐的架构图


Activity/Fragment
即为 View 层, 主要是负责数据的展示刷新和交互事件触发。
 
ViewModel
ViewModel 类的设目的是以生命周期意识的方式存储和管理与 UI 相关的数据。

ViewModel 类允许数据在配置更改(如屏幕旋转)中生存。在配置更改期间,ViewModel对象会自动保留,以便它们保存的数据立即可用于下一个 Activity 或 Fragment 实例。

注意: ViewModel 决不能引用视图、生命周期或任何可能包含对活动上下文的引用的类。

如果ViewModel 中需要使用系统 Service 服务等,可以继承扩展 AndroidViewModel  类,此类有一个带有 Application 类型参数的构造方法。
 
 LiveData
LiveData 是一个可观察的数据持有者类。与常规 Observable 不同,LiveData 是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如 Activity,Fragment 或 Service。

此感知确保 LiveData 仅处在其他组件生命周期活跃的状态下进行数据更新(当生命周期处于 STARTED 或 RESUMED 状态,LiveData 会将其视为处于活动状态);非活跃状态时,则不会接受数据;当对象生命周期结束时, LiveData 也会随之结束。

使用 LiveData 有以下几个优点:
 确保 UI 界面显示正确的数据状态

 无内存泄漏
LiveData 的观察者是绑定在对象的生命周期上,当对象销毁,观察者也会随之进行清理。

 可避免发生未因停止的 Activity 导致崩溃
当 Activity 停 止,生命周期处于非活跃状态, LiveData 则不会进行数据返回操作。

 不需要手动去处理生命周期

 总是能更新最新数据
如果生命周期由非活动状态变为活动状态时, LiveData 会接收最新数据。例如,位于后台的活动在返回前台后立即接收最新数据。

 当页面配置发生更改, 仍可获取正确数据(例如屏幕旋转)
 
 共享资源
 
Repository
仓库, 主要是用于各种数据的业务请求操作( 网络请求和数据库查询), 可以把它看作 Model 层的 一部分。
 
Room
Room 是在 Sqlite 之上添加的一个抽象层, 以便实现更加强大的数据库访问,其可直接返回 LiveData, 用于监听数据返回。下面是使用 ViewModel 、 LiveData 和 Room 进行数据库查询操作的示意图。


 
Retrofit
 网络请求框架。它可以返回 LiveData 对象, 用于监听数据返回。

 使用上面的规范可快速搭建 MVVM 架构。
 
新版 SealTalk 架构

SealTalk 2.0 重构了内部逻辑实现,整体代码将更清晰易读。使用 LiveData + ViewModel + Retrofit 2.0 + Room 等框架基于 MVVM 模式进行开发。
 
| 由于 DataBinding 存在调试难, 并要在 XML 编写等问题, 所以经过讨论之后, 决定弃用 DataBinding。

▲新版本架构图


Ativity/Fragment 作为 View 层, 负责界面显示和事件交互。
 
UserInfoViewModel 等为 ViewModel 层,连接 View 和 Model 的桥梁,数据通过 LiveData 返回。ViewModel 可通过调用不同的 Task 来获取不同的数据源。
 
Task 层即为 Repository, 根据不同的接口或数据属性, 分别封装了不同的 Task, 例如关于 User 的数据操作就封装在了 UserTask 中,这样功能模块职能清晰并复用性高。
 
Service Dao 是请求网络数据和数据库数据操作,分别使用了Retrofit 和 Room 的依赖库。
 
由于请求数据操作移到 Task 层,从而解决了旧版 Activity/Fragment 中代码臃肿的问题, 并无需重复编写同一数据类型的请求逻辑,提高了代码复用。
 
由于 LiveData 是依附于 Activity / Fragment 的生命周期的特性, 在Activity 或Fragment 销毁时, 则其不会返回数据并会清理, 所以无需担心其内存泄漏的问题。并且 LiveData 在 Activity/Fragment 重新进入Resume 状态时, 会检测数据有没有更新,有的话会主动把新数据传递给 View, 使用同一数据的地方就无需主动同步数据。


数据请求流程

在新版中也对数据的请求机制做了信息设计处理,请求数据分为三种:

 网络请求需要缓存的
 网络请求且不需要缓存的
 数据库直接查询的
 
需要网络请求并需要缓存的
 

在 Task 层首先会查询数据库,然后返回当前数据库中的缓存数据,此数据用于请求网络时,  页面友好展示。然后再请求服务器,获取最新数据,获取数据成功后会把新数据保存至数据库。最后再进行一次数据库查询, 获取数据库中的最新数据。此机制虽然繁琐,但极大的保证了界面展示的数据与最新数据的一致性。

 网络请求且不需要缓存的
  


Task 直接进行网络请求并返回数据。


数据库直接查询的
 

 
新版架构完美的解决了旧版存在的问题,更多细节可参考新版SealTalk github 源码:
 https://github.com/sealtalk/sealtalk-android


点击阅读原文

立即注册获取更多干货

↓↓


【声明】内容源于网络
0
0
融云全球互联网通信云
领先的全球智能通信云服务商,以通信云 PaaS 和 SaaS 产品,赋能开发者和企业创新。艾瑞权威数据显示,融云 IM 市场份额连续多年稳居第一。
内容 747
粉丝 0
融云全球互联网通信云 领先的全球智能通信云服务商,以通信云 PaaS 和 SaaS 产品,赋能开发者和企业创新。艾瑞权威数据显示,融云 IM 市场份额连续多年稳居第一。
总阅读106
粉丝0
内容747