写android以来,一直都是采用MVC的模式,所有的业务逻辑,网络请求等都放在了View中,即Activity或者Fragment中。看了一些mvp文章,很多跨度较大,也因为自己造诣不够,还不能跟上大神门的思路。今天自己初次尝试MVP,准备一步一步慢慢来,这是第一篇-初体验,用我们常用的熟悉的登录业务引入;

介绍

MVC

M:逻辑模型,V:试图模型,C:控制器, 耦合性强,不利于后期维护,适合在一些较小的项目中使用;

MVP

Model: 具体的数据源和数据请求,访问数据库和后台服务器等;

View:负责UI,Activity,Fragment;

Presenter:是View和Model的桥梁,负责接收View发来的指令,并据此调用model中的方法;

  • 释放了View,作为View 来说只需要负责UI。耦合度降低。
  • 引入了Presenter,会导致其越来越臃肿,同样不利于后期的维护,并且,每一个包含网络请求的View都需要对应一个或者多个Presenter。

实现

登录活动(Activity)

很简单,点击登录执行登录过程;

DataModel

首先来看Model层,一般Model层需要和数据库或者后台服务器交互,这里模拟即可。

package com.mypractisedemos.module.mvpdemo;

/**
* <pre>
* Created by fanjiajia on 2019/3/29.
* desc:
*/ public class DataModel { public void login(String userName, String Password, iCallBack<ResultBean> callBack) { ResultBean bean; // 封装返回的bean // 登录验证
if (userName.equals("张三") && Password.equals("123456")) { bean = new ResultBean("200", "登录成功", ""); callBack.callSuccess(bean);
}else {
bean = new ResultBean("110", "登录失败", "");
callBack.callFailure(bean);
}
}
}

这里有个iCallback,故名思义,是结果的回调。看看他的定义;

package com.mypractisedemos.module.mvpdemo;

/**
* <pre>
* Created by fanjiajia on 2019/3/29.
* desc:
*/ public interface iCallBack<ResultBean>{ void callError(ResultBean bean); void callSuccess(ResultBean bean); void callFailure(ResultBean bean); void callException(ResultBean bean);
}

这里有四种情况,成功,失败,异常,和错误。每一个回调都需要有个ResultBean,来看看这个回调对象的定义;

package com.mypractisedemos.module.mvpdemo;

/**
* <pre>
* Created by fanjiajia on 2019/3/29.
* desc: 回调对象
*/ public class ResultBean { private String code; // 状态码 private String msg; // 消息 private String data; // 数据 json格式 public String getCode() {
return code == null ? "" : code;
} public void setCode(String code) {
this.code = code;
} public String getMsg() {
return msg == null ? "" : msg;
} public void setMsg(String msg) {
this.msg = msg;
} public String getData() {
return data == null ? "" : data;
} public void setData(String data) {
this.data = data;
} public ResultBean(String code, String msg, String data) {
this.code = code;
this.msg = msg;
this.data = data;
} @Override
public String toString() {
return "ResultBean{" +
"code='" + code + '\'' +
", msg='" + msg + '\'' +
", data='" + data + '\'' +
'}';
}
}

这个参考了之前学长封装的一个OkHttp3工具的回调对象,用在这里了。

iView

看了Model层,现在看看试图接口定义一个接口,如下:

package com.mypractisedemos.module.mvpdemo;

/**
* <pre>
* Created by fanjiajia on 2019/3/29.
* desc:
*/ public interface iView { void loginSuccess(String resultMsg); // 登录成功回调 void loginFailure(String failureMsg);// 登录失败回调
}

这里很简单,主要是登录活动的回调。

DataPresenter

然后开看看Presenter,之前说了这是model和view的桥梁,当点击登录按钮之后,肯定会调用其中的相应方法。先看定义;

package com.mypractisedemos.module.mvpdemo;

/**
* <pre>
* Created by fanjiajia on 2019/3/29.
* desc:
*/ public class DataPresenter { private iView mView;// 视图View private DataModel mModel;// 数据Model public DataPresenter(iView view) { // 构造
this.mView = view;
this.mModel = new DataModel();
} /**
* 定义View会发起的动作
*/ public void login(String userName, String password) { mModel.login(userName, password, new iCallBack<ResultBean>() {
@Override
public void callError(ResultBean resultBean) { } @Override
public void callSuccess(ResultBean resultBean) {
mView.loginSuccess(resultBean.getMsg());
} @Override
public void callFailure(ResultBean resultBean) {
mView.loginFailure(resultBean.getMsg());
} @Override
public void callException(ResultBean resultBean) { }
});
}
}

这里看到他有两个属性,一个是View,另一个是Model,这就是为什么他是二者的桥梁。这里面的login方法中直接调用model的登录方法,然后通过iCallBack回调。

Activity

最后来看看我们之前操作比较多的View

package com.mypractisedemos.module.mvpdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; import com.jiajia.mypractisedemos.R; import butterknife.BindView;
import butterknife.ButterKnife; public class LoginMvpActivity extends AppCompatActivity implements iView{ // 实现iView接口 @BindView(R.id.et_mvp_login_username)
EditText et_username; // 用户名
@BindView(R.id.et_mvp_login_password)
EditText et_password; // 密码
@BindView(R.id.btn_mvp_login_login)
Button btn_login; // 登录按钮 private DataPresenter mPresenter; // 声明Presenter @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_mvp); ButterKnife.bind(this); // ButterKnift框架的使用 mPresenter = new DataPresenter(this); // 绑定自己的Presenter } public void login(View view) { // 登录按钮的onClick事件 mPresenter.login(String.valueOf(et_username.getText()), String.valueOf(et_password.getText()));
} @Override
public void loginSuccess(String resultMsg) {
Toast.makeText(this, resultMsg, Toast.LENGTH_SHORT).show();
} @Override
public void loginFailure(String failureMsg) {
Toast.makeText(this, failureMsg, Toast.LENGTH_SHORT).show(); }
}

这里我们的activity实现iView接口,并实现相应的方法即可!

分析

最后看看我的结构,果然是小白,因为把所有的东西都放在这个包下,没有层次感,因为是第一次尝试,只关注了实现思路本身。后面再进行分类。



这里没有做内存泄漏的处理,来看看为何会导致内存泄漏,在activity中我们mPresenter = new DataPresenter(this); // 绑定自己的Presenter,注意,这里的this,然后在DataPresenter中this.mView = view;,这就说明了,Presenter持有了View的引用,而View(Activity)如果被切换,导致销毁,但是Presenter持有其强引用,导致无法被GC回收,因此导致这个Activity泄漏。下一篇再谈;

GitHub: MVP-初体验(一)

最后

小白拙见!

此致,敬礼!

小白用Android MVP-初体验(一)的更多相关文章

  1. Android RecyclerView初体验

    很早之前就听说过RecyclerView这个组件了,但一直很忙没时间学习.趁着周末,就花了一天时间来学习RecyclerView. 准备工作 在Android Studio里新建一个Android项目 ...

  2. Android wear 初体验

    近期一直在研究android wear SDK,整体感受来说就是和现有的android 其它的开发SDK还是有非常多新的东西.比如手机终端与手表端的通信机制,手表端的UI规范.可是从开发本身来讲,还是 ...

  3. Android JNI初体验

    欢迎转载,转载请注明出处:http://www.cnblogs.com/lanrenxinxin/p/4696991.html 开始接触Android JNI层面的内容,推荐一本不错的入门级的书< ...

  4. Android程序初体验

    第一个程序的实现的最终功能是: 点击"正确"或者"错误"会得到一个是否正确的提示. 直接上效果图.     此次涉及代码编写的文件有4个: package co ...

  5. Android开发初体验

    本文通过开发一个应用来学习Android基本概念及构成应用的UI组件. 开发的应用名叫GeoQuiz,它能给出一道道地理知识问题.用户点击true或false按钮回答问题,应用即时做出反馈 第一步请先 ...

  6. .net程序员的android studio 初体验 (环境设置2022年10月)

      很久以前用DevExtreme写的一个Hybird APP要添加蓝牙打印功能,但是用来打包APP的phonegap被adobe关闭了,所以,只能自己用cordova去打包安卓APP,不得已,研究了 ...

  7. Android Studio 初体验

    Google在I/O */

  8. Android开发学习之路--百度地图之初体验

    手机都有gps和网络,通过gps或者网络可以定位到自己,然后通过百度,腾讯啊之类的地图可以显示我们的地理位置.这里学习下百度地图的使用.首先就是要申请开发者了,这个详细就不多讲了.http://dev ...

  9. 免费WiFi初体验——个小白的WiFi旅程

    说来羞愧,真正接触到WiFi还是在毕业后,此前自己封闭在一个人的世界,再加上外在学校的包围,我还成了个"山里"的孩子. 去年毕业了,也算是个90后,可自觉得心态过于成熟.了解外界太 ...

随机推荐

  1. CSS3 过渡、变形和动画

    一.我们来给按钮增加一个悬停效果:#content a:hover {border: 1px solid #000000;color: #000000;text-shadow: 0px 1px whi ...

  2. 001---CBV和restful规范

    CBV 和 restful规范 知识点准备: django的view FBV:基于函数的视图 CBV:基于类的视图 urls.py from django.urls import path from ...

  3. 记数据结构MOOC-二叉树

    主要的学习内容 在本章中,主要学习了二叉树的实现以及各种遍历的方法.着重介绍了前序.中序.后序三种遍历方法的递归实现,同时也描述了前序中序遍历的迭代方法. 教材的主要内容 教材是以哈夫曼编码树为主要脉 ...

  4. 关于NODEJS性能测试和优缺点总结

    最近公司开发了一套新产品,采用nodejs前端+Java后端框架,为完全的前后端分离结构,以下为相关信息. 软件及功能: 软件 功能 Nginx 负责反向代理和负载均衡 Nodejs 前端代码 JDK ...

  5. vim 中文乱码问题

    编辑~/.vimrc文件,加上如下几行: set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936   set termencoding=utf ...

  6. javaWeb项目-文件下载的消息头和编码问题

    一.问题: 做web项目经常提到的一个需求就是页面的文件下载,那么下载的时候在后台为什么要设置响应消息头?为什么这样设置? 二.解决: 1.例子 //设置响应的消息头response.setConte ...

  7. STM8在IAR中Printf的整形长度问题

    //ld是32位的 printf("up_intval:%ld\r\n",device_set.upload_tem); //d是16位的 printf("up_intv ...

  8. mybatis mapper空指针异常的问题

    发现是因为mysql表名不能为  x_x_x 这样的形式,最多只能有一个下划线,不能有多个,否则会找不到数据,进而导致空指针异常 上面的被推翻了,发现原来是因为没有注入mapper才导致空指针异常! ...

  9. 小计Tomcat的调优思路

    描述 最近在补充自己的短板,刚好整理到Tomcat调优这块,基本上面试必问,于是就花了点时间去搜集一下tomcat调优 都调了些什么,先记录一下调优手段,更多详细的原理和实现以后用到时候再来补充记录, ...

  10. python-全栈开发-前方高能-内置函数

    python_day_14 13. 前方高能-内置函数 ⼀. 本节主要内容: 1. 内置函数 什么是内置函数? 就是python给你提供的. 拿来直接⽤的函数, 比如print., input等等. ...