序言

每个程序员看到一堆烂代码都有一颗重构的心。烂代码写起来嘴上 笑嘻嘻,心里mmp。特别是有代码洁癖的人。重构不易且行且珍惜,此框架将减少开发时间。如果你们的项目结构跟我的不一样,这也不用担心,你看了我这个,简单修改一下模板,照样能生成你想要的代码。

GitHub项目地址

MVP架构

相信大家对于MVP耳熟能详了,理解的直接往下看,如果概念比较模糊,可以网上查一查理解理解,我这边简单的介绍一下,可以配合下图来理解
- View层: View层也是视图层,只负责对数据的展示,提供友好的界面与用户进行交互。开发中通常将Activity或者Fragment作为View层。
- Model层: Model层也是数据层。它区别于MVC架构中的Model,在这里Model它负责对数据的存取操作,例如对数据库的读写,网络的数据的请求等。
- Presenter层: 是连接View层与Model层的桥梁并对业务逻辑进行处理。在MVP架构中Model与View无法直接进行交互。所以在Presenter层它会从Model层获得所需要的数据,进行一些适当的处理后交由View层进行显示。这样通过Presenter将View与Model进行隔离,使得View和Model之间不存在耦合,同时也将业务逻辑从View中抽离

项目介绍

项目采用MVP架构,使用RxAndroid2+Retrofit开源框架封装,结合Android Studio模板快速生成MVP基础代码。新项目或者重构项目值得拥有。此开发框架是我2017年底重构项目开发的,使用了几个月,项目重构完成了,完美使用,特别省事省时省心

项目结构

DevMvp├─api//URL、接口管理、网络请求封装类├─mvp//项目主体│  ├─base//基础类封装├─bean//实体类│  ├─contract//契约类 用于统一管理view和presenter的接口│  ├─model//M层-数据处理│  ├─presenter//P层-逻辑业务处理│  └─view//V层-页面渲染│      ├─activity├─adapter│      └─fragment...//类似Dialog、PopupWindow也可以放在view下└─utils//工具类└─rxhelper//Rx封装工具

代码详解

1.api-网络请求

Retrofit网络请求封装,项目里面只是对Retrofit网络请求基本参数,需要header、cache等参数,可在网上查查资料,这类文章介绍很多。Retrofit 2.0使用文档
- DevMvpApi -Retrofit初始化

    public static Retrofit createApi() {OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS);httpClientBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));mRetrofit = new Retrofit.Builder().client(httpClientBuilder.build()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).baseUrl(Url.BASE_URL).build();return mRetrofit;}
  • DevMvpService-接口管理
    这边直接使用BookBean对象接收返回值
@GET(Url.BOOK_CLASSIFY)
Observable<BookBean> bookClassify();
2.contract-契约类,v层和p层接口管理
  • CBook-测试契约类
    Contract用于存放mvp三层接口类 放在一起便于管理,不用生成太多的类(因为model没有需要处理的数据,所以没有使用接口,可自行生成实现)
interface IPBook extends IBasePresenter {void pBook();}
interface IVBook extends IBaseView {void vBookSuccess(BookBean bean);void vBookError(String reason);}
3.model-M层
  • BaseModel-M层基类
    网络请求初始化和网络请求取消处理
    public CompositeDisposable mDisposable = new CompositeDisposable();/*** 初始化调用网络请求* @return*/public DevMvpService apiService() {return DevMvpApi.createApi().create(DevMvpService.class);}/*** 取消网络请求*/public void onDestroy() {if (mDisposable != null) {mDisposable.isDisposed();mDisposable.clear();}}
  • MBookImpl-M层数据处理
    由于不需要对数据进行处理,我就直接返回给P层,如果数据可能会从数据库、缓存、网络获取,需要在这里进行处理。
public void mBook(RxObservable rxObservable) {apiService().bookClassify().compose(RxTransformer.switchSchedulers(this)).subscribe(rxObservable);}
4.presenter-P层
  • BasePresenter-P层基类
    连接V层和M层
public class BasePresenter<V extends IBaseView, M extends BaseModel> {protected V mView;protected M mModel;protected Context mContext;public BasePresenter(Context mContext, V mView, M mModel) {this.mView = mView;this.mModel = mModel;this.mContext = mContext;}public void onDestroy() {if (mModel!=null) {mModel.onDestroy();}}
}
  • PBookImpl-P层业务逻辑处理
/*** Created by Liang_Lu on 2017/12/21.* P层 此类只用于处理业务逻辑 然后把最终的结果回调给V层*/public class PBookImpl extends BasePresenter<CBook.IVBook, MBookImpl> implements CBook.IPBook {public PBookImpl(Context mContext, CBook.IVBook mView) {super(mContext, mView, new MBookImpl());}@Overridepublic void pBook() {mView.showLoading();mModel.mBook(new RxObservable<BookBean>() {@Overridepublic void onSuccess(BookBean bean) {mView.hideLoading();mView.vBookSuccess(bean);}@Overridepublic void onFail(String reason) {mView.hideLoading();mView.vBookError(reason);}});}
}
5.view-V层
  • BaseActivity-V层基类(BaseFragment类似)
    在基类跟P层建立连接,这里可以根据项目需求丰富BaseActivity。这里只把添加基础必备功能。
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity {public Context mContext;public T mPresenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContext = this;if (setContentViewId() != 0) {setContentView(setContentViewId());} else {throw new RuntimeException("layoutResID==-1 have u create your layout?");}createPresenter();ButterKnife.bind(this);initView();}/*** 初始化方法*/protected void initView() {}/*** 获取contentView 资源id*/public abstract int setContentViewId();/*** 创建presenter实例*/public abstract void createPresenter();/*** activity跳转(无参数)** @param className*/public void startActivity(Class<?> className) {Intent intent = new Intent(mContext, className);startActivity(intent);}/*** activity跳转(有参数)** @param className*/public void startActivity(Class<?> className, Bundle bundle) {Intent intent = new Intent(mContext, className);intent.putExtras(bundle);startActivity(intent);}@Overrideprotected void onDestroy() {super.onDestroy();if (mPresenter != null) {mPresenter.onDestroy();//页面销毁 网络请求同销毁}}
}
  • BookActivity-V层页面渲染处理
    V层只需要操作页面控件,网络数据显示到页面上等等。
/*** Created by Liang_Lu on 2017/12/21.* V层 用于数据和页面UI展示(Fragment Dialog 同理)*/
public class BookActivity extends BaseActivity<PBookImpl> implements CBook.IVBook {private TextView mTv;private Button mBtn;@Overrideprotected void initView() {super.initView();mBtn = findViewById(R.id.btn);mTv = findViewById(R.id.tv);mBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mPresenter.pBook();}});}@Overridepublic int setContentViewId() {return R.layout.activity_book;}@Overridepublic void createPresenter() {mPresenter = new PBookImpl(mContext, this);}@Overridepublic void showLoading() {}@Overridepublic void hideLoading() {}@Overridepublic void vBookSuccess(BookBean bean) {mTv.setText("网络请求成功");}@Overridepublic void vBookError(String reason) {mTv.setText(reason);}
}

基础设置模板详解(Fragment类似)

globals.xml.ftl-声明全局变量
<globals><#assign Collection=extractLetters(ActivityClass)>//从输入的title中获取输入字符<#assign collection_name=Collection?lower_case>//获取到的字符转成小写<!-- 这里声明全局变量--><global id="activity_layout" value="${Collection?lower_case}" />//作为activity的layout的命名<global id="ActivityName" value="${Collection}Activity" />//作为activity类名<global id="PresenterName" value="P${Collection}Impl" />//作为presenter类名<global id="ModelName" value="M${Collection}Impl" />//作为model类名<global id="ContractName" value="C${Collection}" />//契约类-contract类名<global id="IViewName" value="IV${Collection}" />//契约类-view层接口名<global id="IPresenterName" value="IP${Collection}" />//契约类-presenter层接口名<global id="packageName" value="com.luliang.devmvp" />//项目包名(此处填写为自己的项目包名)
</globals>
recipe.xml.ftl-文件生成指定目录

PS.这里需要注意一下,这里的根目录(root)是包名的那个目录,此项目例:com.luliang.devmvp

<recipe>
<!--merge 表示需要合并到指定文件的内容 (表示AndroidManifest声明新建的Activity) --><merge from="root/AndroidManifest.xml.ftl"to="${escapeXmlAttribute(manifestOut)}/AndroidManifest.xml" /><!-- instantiate 表示创建文件到指定文件夹   (把需要创建文件的模板放在根目录文件夹下对应文件夹,针对自己的项目修改路径)    --><instantiate from="root/res/layout/activity_main.xml.ftl" to="${escapeXmlAttribute(resOut)}/layout/activity_${activity_layout}.xml" /><instantiate from="root/src/app_package/MvpActivity.java.ftl"to="${escapeXmlAttribute(srcOut)}/mvp/view/activity/${ActivityName}.java" /><instantiate from="root/src/app_package/MvpPresenter.java.ftl"to="${escapeXmlAttribute(srcOut)}/mvp/presenter/${PresenterName}.java" /><instantiate from="root/src/app_package/MvpContract.java.ftl"to="${escapeXmlAttribute(srcOut)}/mvp/contract/${ContractName}.java" /><instantiate from="root/src/app_package/MvpModel.java.ftl"to="${escapeXmlAttribute(srcOut)}/mvp/model/${ModelName}.java" /></recipe>
template.xml-创建模板页面设置

这里主要设置模板名称、分类、生成模板需要填写的信息等等

<template
    format="5"revision="5"name="Mvp Activity"minApi="9"minBuildApi="14"description="Creates a new mvp activity"><category value="Activity" /><formfactor value="Mobile" /><!--parameter 标签表示创建时需要输入的属性 --><parameter
        id="ActivityClass"name="Activity ClassName"type="string"constraints="nonempty"default="name" /><!--复选框属性--><parameter
        id="isTitleBar"name="是否需要titleBar"type="boolean"default="false"help="选中即添加默认TitleBar" /><thumbs><!-- 模板预览图片 --><thumb>template_blank_activity.png</thumb></thumbs><globals file="globals.xml.ftl" /><execute file="recipe.xml.ftl" />
</template>

Mvp基础代码生成设置详解

文件的名称对应-文件生成指定目录文件(recipe.xml.ftl)里面的名称。

MvpActivity.java.ftl-类基础文件代码生成设置

MvpContract.java.ftl、MvpModel.java.ftl、MvpPresenter.java.ftl几个文件类似,就不一一列出来
${ContractName} 等,对应全局变量文件(globals.xml.ftl)的变量。

package ${packageName}.mvp.view.activity;import ${packageName}.R;
import ${packageName}.mvp.base.BaseActivity;
import ${packageName}.mvp.contract.${ContractName};
import ${packageName}.mvp.presenter.${PresenterName};
import android.os.Bundle;
/*** Created by Liang_Lu on 2017/12/21.* @author LuLiang* @github https://github.com/LiangLuDev*/public class ${ActivityName} extends BaseActivity<${PresenterName}> implements ${ContractName}.${IViewName}{@Overrideprotected void initView() {super.initView();}@Overridepublic int setContentViewId() {return R.layout.activity_${activity_layout};}@Overridepublic void createPresenter() {mPresenter = new ${PresenterName}(mContext, this);}@Overridepublic void showLoading() {}@Overridepublic void hideLoading() {}
}
activity_main.xml.ftl-布局基础文件代码生成设置
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">
<!-- 根据template文件的parameter属性判断是否需要添加 --><#if isTitleBar><include layout="@layout/toolbar_layout"/></#if>
</LinearLayout>
AndroidManifest.xml.ftl-Activity声明文件设置

PS.声明只针对于Activity,Fragment不需要此文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ><application><activity android:name=".mvp.view.activity.${ActivityName}"/></application>
</manifest>

一键生成MVP基础代码

  • copy项目下的MvpActivity文件夹到Android Studio安装目录 例:C:\Android\Android Studio 3.0 release\plugins\android\lib\templates\activities文件夹下.
  • MvpFragment 的路径是 C:\Android\Android Studio 3.0 release\plugins\android\lib\templates\other
  • 重启Android Studio。
  • 重启Android Studio之后,选中包名路径


- 生成MvpActivity基础代码(MvpFragment可选中Fragment里面生成)

依赖库使用

将所有依赖的版本控制提取到根目录下的config.gradle做统一管理
- supportVersion : “26.1.0”
- retrofit : “2.2.0”,
- rxjava : “2.0.1”,
- rxandroid : “2.0.1”,
- okhttp3 : “3.4.1”,
- constraint_layout: “1.0.2”,
- rxjava2_adapter : “1.0.0”,
- logging : “3.4.0-RC1”,
- butterknife : “8.8.1”,

意见反馈

如果遇到问题或者好的优化建议,请反馈到:927195249@qq.com 或者LiangLuDev@gmail.com

如果觉得还行的话,赞一下吧! 谢谢啦!

【Android】一键生成MVP代码-DevMvp快速开发框架相关推荐

  1. android studio mvpplugin,MVPHelper Android Studio 插件,一键生成 MVP 代码接口以及实现类。 @codeKK Android开源站...

    一款适用于 Intellij IDEA 和 Android Studio 的插件, 可用于为 MVP 架构生成接口以及实现类, 解放双手. 欢迎 Issue Report, 欢迎 Feature Re ...

  2. Android一键生成包含.dex的Jar及动态加载方案

    Android一键生成包含.dex的Jar及动态加载方案 背景:谈到动态加载相信很多小伙伴都会想到 热更新 及 动态加载dex 的技术,最近也因为项目重构的需求,折腾了下这方面的技术点,以前研究过但时 ...

  3. 可以一键生成crud的php框架,关于Laravel+vue+admin一键生成CRUD代码

    下面由Laravel框架教程栏目给大家介绍Laravel+vue+admin 一键生成CRUD代码,希望对需要的朋友有所帮助! Laravue Laravel+vue+admin 实现了JWT鉴权,动 ...

  4. 现在android开发都会用到那些快速开发框架或者第三库?Android百大框架分享,附完整项目

    一.榜单介绍 排行榜包括四大类: 单一框架:仅提供路由.网络层.UI层.通信层或其他单一功能的框架 混合开发框架:提供开发hybrid app.h5与webview结合能力.web app能力的框架 ...

  5. Yapi接口一键生成Java代码

    文章目录 一.简介 1. 这是什么 2. 有啥用 3. 为什么要用 二.快速开始 1.下载 2.配置 3.运行 三.版本说明 v1.0.0 v1.0.1 四.Github项目地址 一.简介 1. 这是 ...

  6. Fiddler抓包一键生成调用代码

    首先我们的需求场景是 用Fiddler抓到某个接口调用后,用代码来模拟调用,一般我们写代码会有3个步骤: 1设置http请求相关的参数:header,method,url,cookie等 2设置pos ...

  7. vscode 一键生成vue代码

    1安装vetur插件,识别vue文件安装完成之后点击重新加载 2文件–>首选项–>用户片段–>点击新建代码片段–取名vue.json 确定 3粘贴以下代码 {"Print ...

  8. 真爱!微软宣布新开源网站,由 Jekyll 一键生成,代码所见即所得

    来源 | Microsoft 编辑 | 小匀 转自 | 新智元 近日,微软上线了一个新的开源网站.这不是微软唯一的开源网站,但却代表了新的起点.网友表示:这次真的拥抱开源了!从「恨」到「爱」,微软与开 ...

  9. linux c语 curl代码_偷懒必备工具——一键生成爬虫代码

    我们在构建网络请求的时候,不可避免地要添加请求头(headers),以mdn学习区为例(https://developer.mozilla.org/zh-CN/docs/learn),我们的请求头是这 ...

最新文章

  1. JS 获取指定时间的时间戳(兼容各个浏览器)
  2. .net程序员转战android第一篇---环境部署
  3. unity小工具 创建常用文件夹
  4. HDU3939(毕达哥拉斯三元组的解)
  5. javascript操作符之new 也疯狂 (2)
  6. 2020牛客多校第1场I-1 or 2一般图最大匹配带花树
  7. 第2课 贝贝的图形(vhist)-2019-07-11《聪明人的游戏-提高篇》
  8. 【技术文档】jeecg3.7-maven搭建环境入门 - 老版本
  9. 要来了!国内安卓统一推送标准将于3月开启测试
  10. win7计算机未连接网络连接,解决win7能上网但是网络图标显示未连接的方法-win7之家...
  11. poj 1511 Invitation Cards spfa比基础题难一些!!练练手挺好
  12. atitit。gui 界面皮肤以及换肤总结 java .net c++
  13. 机器学习之MCMC算法
  14. chm混淆+qq白利用免杀360主动防御
  15. 推荐一款开源的电子书格式转换工具
  16. 广州艺术博物院走进春睡画院旧址“云赏画”
  17. 靠卖艺还债:罗永浩的冬天来了!
  18. xp,linux双系统,如何在XP下安装linux实现双系统!
  19. meterpreter使用
  20. web前端 打地鼠小游戏

热门文章

  1. 百度糯米O2O移动自动化测试实践
  2. Minifilter 拦截FileMapping IO事件
  3. 推荐系统自己实践-----基于用户的推荐
  4. SQL语句中不等号(!=,)
  5. jdk1.8 Hotspot虚拟机参数通用配置
  6. PAT 基础练习题 7-1 厘米换算英尺英寸 (15 分)
  7. 覆盖安装windows解决windows权限、文件异常等疑难杂症
  8. python绘制概率密度曲线_python添加概率密度曲线-女性时尚流行美容健康娱乐mv-ida网...
  9. article标准用法
  10. 我的世界服务器雪球回城无限雪球,我的世界如何用命令方块做回城雪球 | 手游网游页游攻略大全...