android的Live架构
MVC、MVP、MVVM的选择
一开始我们在这几种框架上的选择上就没花太多的心思,因为他们都只是为了实现清晰的分层逻辑,差异化的地方无非是讲UI逻辑、交互逻辑、数据绑定逻辑、业务逻辑堆放在那一层的问题。UI逻辑我们定义为UI控件长什么样,放在那里的逻辑。交互逻辑指的是跟用户互动所需要的逻辑。数据绑定逻辑指数据怎么呈现在界面上的逻辑。业务逻辑指的是因为当前业务不同,跟UI无关的一些程序控制逻辑。
只是看起来很美好的MVC
Live1.0架构上看,MVC的架构能够帮助我们进行良好的分层。Activity(或者Fragment)承担了粘合剂的作用,数据请求后的结果也放在里面。控件的交互交互逻辑虽然收敛在对应的Controller里面了,但是Controller之间的交互逻辑需要放在Fragment中,通过Fragment来调用其他Controller的接口。Live业务是一个典型的业务逻辑简单,UI逻辑、交互逻辑多的场景。各种控件之间的交互很频繁,很快的作为粘合剂的Fragment就不可控地膨胀到2000多行。这时候,添加新的功能或者做修改已有的功能,已经显得很吃力,特别各个组件中因为数据、状态而耦合在一起。在交互复杂的情况下,Activity中因为组件交互的接口越开越多,另外接口也有自己特定的业务名称,除了作者别人改动起来很吃力。这时候,我们又意识到交互逻辑必须要细分为组件自身的交互逻辑,以及组件之间的交互逻辑。
另一方面,粘合剂Fragment中装载的数据是几乎每一个Controller都需要的,往往就在初始化的时候将数据注入进Controller中,来完成数据绑定的逻辑。一不小心,数据绑定的逻辑就从Controller中跑到Fragment了。
开发流程
Live1.0架构中,开发一个组件,需要实现View、Controller、Model,另外Controller还需要在粘合剂Fragment中找到对应的回调实现响应的逻辑,跟其他组件互动的部分需要持有其他组建的View(或Controller).
Live2.0架构
Live2.0架构主要想解决三个问题:
- 每个组件能够独立地变化,状态可以被收敛在组件中。
- 用最少量的、统一的接口来解耦组件间的交互,数据的绑定。
- 交互逻辑、数据请求、业务逻辑、UI逻辑可以复用。
模块化
很自然地,我们就想到可以通过模块化、事件通知机制来解决以上的问题。关键的问题在于如何解决Acitivity中存在大量粘合剂代码。传统的MVC框架只解决了分层的问题,并没有指明模块化的方式。另外我们希望模块化不要造成使用上的难度,接口应该统一、简单易学。玩弄过Google官方出的架构Demo,然而他View、Present的接口也是强业务相关的,并不能实现接口的统一化。
我们最后构想的方案是:既然所有的View在onCreateView的时候都要绑定特定的交互逻辑,onDestroy的时候都要进行销毁,那么每个Controller中实现Fragment的生命周期函数回调就是一件很自然的事情。所以最终的解决方案是Fragment只做生命周期函数的分发,所有的Controller实现Fragment的生命周期回调。
调整后,Fragment彻底变成一个生命周期分发的空壳,每一个View对应一个ViewController,View的绑定交互逻辑、交互逻辑都单独地在Controller中变化.
public class TMVerticalVideoFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = View.inflate(this.getActivity(), R.layout.fragment_vertical, null);
for (LiveFragmentInterface item :
mViewControllerInterfaceMap.values()) {
item.onCreateView(inflater, container, savedInstanceState);
}
return mRootView;
}
@Override
public void onPause() {
for (LiveFragmentInterface item :
mViewControllerInterfaceMap.values()) {
item.onPause();
}
super.onPause();
}
//省略onViewCreated()、onStop()、onResume()等一大波生命周期函数...
@Override
public void onDestroy() {
super.onDestroy();
for (LiveFragmentInterface item :
mViewControllerInterfaceMap.values()) {
item.onDestroy();
}
}
}
事件分发
之前提到,Live业务的各个组件间的交互逻辑频繁(注意:这里说的不是组件自身的交互逻辑,而是组件与组件间因自身状态变化,而需要控制其他组件同时进行变化的组件间交互。我数了一下一共有26种组件间交互)。显然,这些交互逻辑并不复杂,但是常变。使用事件分发就是最好的选择,接口就不允许常常变化。因此我们实现了简单的事件总线来解耦组件间的交互。
数据绑定
Live业务的数据只依赖少量的Mtop接口,但是这些数据却需要共享给各个组件。我们希望每个组件不要关注数据请求的细节,在数据来的时候,只关注自己需要的数据。另外,Live业务有多个数据源(N个Mtop、配置中心数据、PowerMessage).然而并不是所有的组件都需要关注这么些数据。
解决方案:我们认为数据的请求和处理过程同用户的交互一样,是一种特殊的交互逻辑,数据请求的成功与失败回调也是一种事件通知。数据的绑定固化成特定的接口,对数据感兴趣的Controller只需要实现对应的数据接口,就可以接收到对应的数据。所有Controller中数据绑定的逻辑也固化在特定的数据回调接口中。
/**
* MinSk数据读取Controller
* Created by kaihuan on 16/8/18.
*/
public class MinSkConfigurationController implements LiveFragmentInterface {
public static final String TAG = "live.MinSkConfigurationController";
protected IGetController mFragment;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
JSONObject refreshConfigJson = TMConfigCenterManager.getInstance().getConfigDataObject(getConfigName());
if (refreshConfigJson ==null ){
return;
}
//分发数据
Map<String, LiveFragmentInterface> viewControllerInterfaceMap = mFragment.getViewControllerInterfaceMap();
if (viewControllerInterfaceMap != null) {
for (LiveFragmentInterface item : viewControllerInterfaceMap.values()) {
if (item != null && item instanceof IMinskDataListener) {
((IMinskDataListener) item).onMinskData(getConfigName(),refreshConfigJson);
}
}
}
}
@NonNull
protected String getConfigName() {
return LiveVerticalConstants.MINSK_CONFIG_KEY;
}
// 省略一大波生命周期回到函数..
@Override
public void onFragemntCreated(Fragment fragment) {
this.mFragment = (IGetController) fragment;
}
}
开发流程
Live2.0架构中,开发一个特定的组件就只需要实现自己的View、Controller、Model,在自己的Fragment生命周期回调、数据回调中实现自己的逻辑、改变自己的状态。对组件中需要联动的部分,只需要发送事件通知别人改变。
从切身的体会来说,Live2.0架构简化了开发成本,在View产生的方法,在特定的回到生命周期回调函数中只专心地做自己业务相关的部分,而不需要考虑别人的状态变化。在开发过程中,甚至都见不到别人一丝丝的代码.
双十一我们需要实现三个不同的Live间,由于逻辑的切割足够细,代码方面近乎达到100%的复用。对开发、测试同学来说,工作量至少减少2~3倍。
android的Live架构的更多相关文章
- [转]Android App整体架构设计的思考
1. 架构设计的目的 对程序进行架构设计的原因,归根到底是为了提高生产力.通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点, ...
- Android入门(二):Android的系统架构
android的系统架构和其操作系统一样,采用了分层的架构.从架构图看,android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和linux核心层. 从技术方面看,An ...
- Android系统的架构
android的系统架构和其操作系统一样,采用了分层的架构.从架构图看,android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和linux核心层. 1.应用程序 Andr ...
- fir.im Weekly - iOS/Android 应用程序架构解析
假如问你一个iOS or Android app的架构,你会从哪些方面来说呢? 本期 fir.im Weekly 收集了关于 iOS/Android 开发资源,也加入了一些关于 Web 前端方面的分 ...
- Android 控件架构及View、ViewGroup的测量
附录:示例代码地址 控件在Android开发的过程中是必不可少的,无论是我们在使用系统控件还是自定义的控件.下面我们将讲解一下Android的控件架构,以及如何实现自定义控件. 1.Android控件 ...
- Android 的系统架构
Android 的系统架构 Android其本质就是在标准的Linux系统上增加了Java虚拟机Dalvik,并在Dalvik虚拟机上搭建了一个JAVA的application framework,所 ...
- Android App的架构设计:从VM、MVC、MVP到MVVM
随着Android应用开发规模的扩大,客户端业务逻辑也越来越复杂,已然不是简单的数据展示了.如同后端开发遇到瓶颈时采用的组件拆分思想,客户端也需要进行架构设计,拆分视图和数据,解除模块之间的耦合,提高 ...
- Android系统四层架构分享
Android系统四层架构 个人网站:http://www.51pansou.com Android视频下载:Android视频 Android源码下载:Android源码 如果把Android系统看 ...
- Android的系统架构
转自Android的系统架构 从上图中可以看出,Android系统架构为四层结构,从上层到下层分别是应用程序层.应用程序框架层.系统运行库层以及Linux内核层,分别介绍如下: 1)应用程序层 ...
- 实时Android语音对讲系统架构
本文属于Android局域网内的语音对讲项目系列,<通过UDP广播实现Android局域网Peer Discovering>实现了局域网内的广播及多播通信,本文将重点说明系统架构,音频信号 ...
随机推荐
- centos7+ansible自动化工具使用
一.基础介绍 ========================================================================================== 1. ...
- Date对象和正则对象
1.Date对象 创建 var date1 = new Date(); var date2 = new Date(12983798123);//填一个毫秒值,应该是距离1970年1月1日.....多少 ...
- python 字典操作方法详解
字典是一种通过名字或者关键字引用的得数据结构,key 类型需要时被哈希,其键可以是数字.字符串.元组,这种结构类型也称之为映射.字典类型是Python中唯一內建的映射类型. 注意,浮点数比较很不精确, ...
- Spring 当 @PathVariable 遇上 【. # /】等特殊字符
@PathVariable注解应该不是新鲜东西了Spring3.0就开始有了 URL中通过加占位符把参数传向后台 举个栗子,如下比较要说的内容比较简单就大概齐的写一下 画面侧 $.ajax({ typ ...
- ------- 软件调试——还原 QQ 过滤驱动对关键内核设施所做的修改 -------
-------------------------------------------------------------------------------- 在前一篇博文中,我们已经处理完最棘手的 ...
- ubuntu+mono+PetaPoco+Oracle+.net 程序部署
前言:将windows 下开发的 .net 控制台程序(连接Oracle数据库)部署到 ubuntu 下步骤记录 2017-09-19 实验所用机器为虚拟机Ubuntu16.04 amd64 安装 ...
- Facebook发布React 16 专利条款改为MIT开源协议
9 月 26 日,用于构建 UI 的 JavaScript 库 React 16 的最新版本上线. Facebook 最终在现有的两种 React 版本中选择了出现 bug 概率最少的一款.这次版本更 ...
- 生成模型(generative model)与判别模型(discriminative model)的区别
监督学习可以分为生成方法与判别方法,所学到的模型可以分为生成模型与判别模型. 生成模型 生成模型由数据学习联合概率分布\(P(X,Y)\),然后求出条件概率分布\(P(Y|X)\)作为预测的模型,即生 ...
- Maven中避开测试环节
两种方法 修改pom文件 添加<skipTests>true</skipTests>标签 <plugin> <groupId>org.apache.ma ...
- [SCOI2009][bzoj1025]游戏
[SCOI2009][bzoj1025]游戏 标签: DP 置换 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题解 很套路的题目 ...