# MvcBind **Repository Path**: biyouji_admin_admin/MvcBind ## Basic Information - **Project Name**: MvcBind - **Description**: mvc快速开发框架 - **Primary Language**: Android - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2019-08-19 - **Last Updated**: 2023-03-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MvcBind #### 介绍 MvcBind快速开发框架,基于mvc+databinding为基础制作的轻量级快速开发基础框架。目标只有一个:快!上手快,理解快,开发快,维护快。 #### 软件架构 软件架构说明
  框架基于经典的MVC模式,这里为什么不用mvp或者是mvvm呢?后两者笔者也有大量项目实践,实际使用中发现,两者的开发速度都比较慢(较mvc),尤其是mvp,采用了接口解耦,开发中需要写更多的类,声明更多的接口方法,然后再去实现这些方法,开发效率不佳。当然,不可否认的是,就后期维护来说,mvp和mvvm确实优于传统mvc模式,当时这种优势仅存在于mvc写的不规范的情况下,实际上规范化的mvc模式代码,维护并不会比后两者差太多。而且,事实上严格意义上来说,大部分人初学安卓的写法,并不能算是mvc,为什么这么说呢,我们不妨来看看mvc的交互图: ![](https://images.gitee.com/uploads/images/2019/1203/112622_adbb0c26_815942.png) 那么很多人所谓的mvc又是如何写的呢? ~~~java public class TestActivity extends Activity { private TextView mTextView; @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = findViewById(R.id.tv_date); mTextView.setText(System.currentTimeMillis()); } } ~~~   这里只是写个简单的示例,和上图对比可以发现,大部分人所谓的mvc连model模块类都没有,所有的视图、数据、逻辑代码全部堆叠在activity或者fragment中,那么后期维护困难就必然了。就简单来讲,安卓中的mvc也该是由布局(view)、activity(control)、数据类(model)这三者构成才对,事实上你如果这么写了,明显比上述代码更好维护。但是,仅仅这样还是不够的,因为安卓中的布局xml文件职能比较少,很多东西并没有办法在xml中完成,这就造成你不得不写在activity(control)中,这样就又会造成view与control的分工混乱了,那么,如何解决这一问题?
  MvcBind采用吸取mvp的模式核心思想,明确分工,写一个页面时包含三个模块,model(数据类)、control(activity或fragment)、view(布局xml+view类)。这里与传统mvc模式的区别在于view由xml和一个独立的view控制类组成,与mvp的区别在于MvcBind不加入接口解耦机制,mvc三者之间可以直接调用其他方的公共方法。mvp的接口解耦机制过于冗余,而且就效果来说主要还是看使用者的功力,再好的mvp框架到初学者手中也是写的一团糟,所以本库直接去掉了mvp中的接口解耦机制,而保留了mvp基本的模块解耦思想。同时,为了减少模板代码,引入了databinding机制,view类中不需要任何findview代码。
  简单的介绍就说到这里,下面说说MvcBind的快体现在哪里,首先,假如我们需要创建一个activity,使用本框架你只需要: ![](https://images.gitee.com/uploads/images/2019/1203/112622_db46b552_815942.png) ![](https://images.gitee.com/uploads/images/2019/1203/112622_07bda4c1_815942.png) **这两步之后你将会得到:** ![](https://images.gitee.com/uploads/images/2019/1203/112622_42c50f85_815942.png) 如图所示,只需要简单两步你就可以获得mvc三个类和一个布局文件,4个文件中的初始代码展示: ~~~java public class TestActivityControl extends BaseActivity { @Override public void init (Bundle savedInstanceState) { } } public class TestActivityModel extends BaseModel { @Override public void init (IControl control) { } } public class TestActivityView extends BaseView { @Override public void init (IControl control) { mBind.setControl(control); } } ~~~ ~~~xml ~~~   仅仅两步你就可以开始写自己的业务代码,再也不用像写mvp一样去写那么多类和接口,上述功能的实现参考笔者的另一篇文章:[As模板](https://juejin.im/post/59f67d32518825550f53dd72)
  当然,你也大可不必关心上述功能如何实现的,因为本库已经给出模板,位于仓库/工具目录下,只需要复制到as对应目录重启即可,具体使用方法参考使用说明。 #### 安装教程 项目地址:[https://gitee.com/biyouji_admin_admin/MvcBind](https://gitee.com/biyouji_admin_admin/MvcBind) #### 使用说明 基础功能:
1.下载项目源码到本地
2. 配置你的项目根build.gradle文件(参考下载的源码)
3. 导入fastlib到你的项目,并添加为你项目的依赖module
附加功能:
1.activity/fragment模板
  模板位置:源码目录/工具/快速生成类模板
  具体使用说明参考文件夹下的word文档
2.快捷生成bind数据类
  什么是bind数据类?都知道dataBinding需要一个数据实体进行绑定,通常有两种方法,一种是使用ObservableField对字段进行包装,但是这种方法非常麻烦,而且我们的实体通常是来源于json,json解析肯定是无法支持ObservableField类型的,如下: ~~~java public ObservableField name = new ObservableField<>(); ~~~ 还有一种就是实体类继承BaseObservable类,并且需要绑定的字段需要做如下处理: ~~~java private String name; @Bindable public String getName () { return name; } public void setName (String name) { this.name = name; notifyPropertyChanged(BR.name); } ~~~   和第一种写法相比,可能也不便捷,但优势在于json解析出来就可以直接和view进行绑定了,不用再去set一次值。但是大量的字段,重复添加这些东西,还是很浪费时间的,这时候就轮到插件出场了。
  插件目录:源码/工具/DbSetter.jar
  插件安装方法自行百度,不是这里需要介绍的,插件的源码也在工具/DbSetter-master下,如果想对插件作出优化,可以自行修改
  插件使用:
![](https://images.gitee.com/uploads/images/2019/1203/112622_9afb153e_815942.png)   注意,插件不会自动生成继承BaseObservable类的代码,需要自己手动添加,在实体类中使用快捷键alt+insert(AS默认),弹窗菜单第一个就是了,接下来就和系统的setter、gettter自动生成使用是一致的,使用后你将直接得到:
![](https://images.gitee.com/uploads/images/2019/1203/112622_45a951ad_815942.png) 有红色报错的话,可以rebuild一下,如果依然报错就无视掉就行了,不影响运行,这个算是AS自己的bug。 #### 为什么快? 1.上手快
  为什么上手快?因为首先就使用了大家熟知的mvc模式,不需要太多额外的学习成本,本框架最大的学习成本应该是对数据绑定的理解,不过这个相比去吃透mvp、mvvm还是简单很多。
2.理解快
  框架源码简单,没有太多花里胡哨的东西,只要肯花个半天左右的时间来看,就能一目了然整体设计思路。
3.开发快
  基于模板创建activity/fragment和自动生成bind数据类的setter/getter,可以节省大量首次开发时间,千万不要小看这部分创建的时间,一个新项目一般30个activity,10个左右的fragment,如果根据框架创建activity相关类和布局预计5分钟的话一个项目光是写这些模板代码都要近200分钟左右,这么算是比较保守的了,实际时间可能还不止。

  如果你以为开发快仅仅是上面两点就大错特错了,上面不过是冰山一角,下面将详细说明,本库如何实现快速开发:
  **无需再写布局id**,下面的代码,估计大家在各种框架中经常见: ~~~java @Override public int initContentView (Bundle savedInstanceState) { return R.layout.activity_card_goods_list; } ~~~   当然,各种框架的方法名可能有一定出入,但是目的基本都是一样,子类传递布局id给base类进行布局加载,这么做无可厚非,但是写的多了,就很烦这种代码,如果你没有用模板自动生成就更烦,每新增一个页面就要花个2秒的时间写这种没营养的代码,那么本库中如何处理呢?
~~~java public class LoadingFragmentView extends BaseView { @Override public void init (IControl control) { } } ~~~   你会发现没有返回任何布局id,但是运行时页面可以准确加载布局R.layout.fragment_loading,具体原理,这里不细说,有兴趣的直接去看源码,没有几行代码。总体来说这个功能的实现基于两点:

    1.标准化命名,mvc三个模块以及布局的命名有着严格要求,比如上面的LoadingFragmentView他对应的其他文件一定是LoadingFragmentControl、LoadingFragmentModel、R.layout.fragment_loading。当然你大可不必担心命名出错,因为,这些文件都是模板生成的。
    2.反射,有了标准化的命名,我们在基类就可以很容易的通过反射获取类名,再通过类名拼接成布局文件id,然后进行布局加载了!
  **多种功能实例参考** ![](https://images.gitee.com/uploads/images/2019/1203/112623_07a116e1_815942.png)   demo中提供了多种常见场景实例,并且进行了分类和提供了搜索,后续也会持续更新demo,让你成为无情的copy机器,只用关注自己的业务逻辑代码,这些没营养的代码统统写好,拿去黏贴一下就用。
  **多种开发模式切换,你开心就好**
  这里的多种模式是指:
    你不想用mvc,你说我的页面逻辑超级简单,就展示一个数据,生成3个类太傻了,我就想全部写在一个activity里?**没问题!**
~~~java public class ActivityModeFragmentControl extends BaseFragment { @Override public void init (Bundle savedInstanceState) { } } ~~~     页面设计太复杂,或者各种原因,不能或者不想使用databinding?**没问题!**
~~~java public class NoBindingFragmentView extends BaseView { @Override public LayoutBuilder configLayout () { return super.configLayout().setEnableDataBinding(false); } @Override public void init (IControl control) { } } ~~~     既不想不用binding也不想用mvc,只想用最简单的acivity/fragment?**没问题!**
~~~java public class SimpleModeFragmentControl extends BaseFragment { @Override protected BaseView createDefaultView () { return new BaseView() { @Override public void init (IControl control) { } @Override public LayoutBuilder configLayout () { return super.configLayout().setEnableDataBinding(false); } }; } @Override public void init (Bundle savedInstanceState) { } } ~~~   当然了,以上是本库支持的模式,但是通常情况下非常不建议关闭databinding。
#### 项目涉及的三方库(只罗列fastlib的依赖库) 1. [线程池RxTask](https://gitee.com/biyouji/RxTask) 2. [刷新布局SmartRefreshLayout](https://github.com/scwang90/SmartRefreshLayout) 3. [消息总线eventbus](https://github.com/greenrobot/EventBus) 4. [BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper) 5. [Rxjava](https://github.com/ReactiveX/RxJava) 6. [retrofit](https://github.com/square/retrofit) 7. [logger](https://github.com/orhanobut/logger) 8. [fragmentation](https://github.com/YoKeyword/Fragmentation) 9. [rxpermissions](https://github.com/tbruyelle/RxPermissions) 10. [调试工具doraemonkit](https://github.com/didi/DoraemonKit) 11. [弹窗基类BasePopup](https://github.com/razerdp/BasePopup) #### 文档持续更新中。。。