1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)

下面示例一个小案例:

项目架构:

首先bean层:

User.java

public class User {
private String username;
private String password; public String getUsername() {
return username;
} public String getPassword() {
return password;
} public void setUsername(String username) {
this.username = username;
} public void setPassword(String password) {
this.password = password;
}
}

MainActivity.java

public class MainActivity extends AppCompatActivity implements IUserLoginView{
private EditText musername;
private EditText mpasssword;
private Button mlogin;
private Button mclear;
private ProgressBar mpb;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
} private void initView() {
musername = (EditText) findViewById(R.id.username);
mpasssword = (EditText) findViewById(R.id.password);
mlogin = (Button)findViewById(R.id.login);
mclear = (Button)findViewById(R.id.clear);
mpb = (ProgressBar) findViewById(R.id.pb); mlogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mUserLoginPresenter.login();
}
});
mclear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mUserLoginPresenter.clear();
}
}); } @Override
public String getUsername() {
return musername.getText().toString();
} @Override
public String getPassword() {
return mpasssword.getText().toString();
} @Override
public void clearUsername() {
musername.setText(""); } @Override
public void clearPassword() {
mpasssword.setText(""); } @Override
public void showLoading() {
mpb.setVisibility(View.VISIBLE); } @Override
public void hideLoading() {
mpb.setVisibility(View.GONE); } @Override
public void toMainActivity(User user) {
Toast.makeText(this, user.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
} @Override
public void showFailError() {
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}
}
IUserLoginView.java
public interface IUserLoginView {
//操作的目的
String getUsername();
String getPassword();
void clearUsername();
void clearPassword();
//友好的交互
void showLoading();
void hideLoading();
//操作的结果,对应的反馈
void toMainActivity(User user);
void showFailError(); }
UserLoginPresenter.java
//Model和View的桥梁  login  clear
public class UserLoginPresenter {
private IUserLoginView userLoginView;
private IUserBiz userBiz;
private Handler mHandler = new Handler(); public UserLoginPresenter(IUserLoginView userLoginView){
this.userLoginView = userLoginView;
this.userBiz = new UserBiz();
} public void login()
{
userLoginView.showLoading();
userBiz.login(userLoginView.getUsername(), userLoginView.getPassword(),new OnLoginListener()
{
@Override
public void loginsuccess(final User user)
{
//需要在UI线程执行
mHandler.post(new Runnable()
{
@Override
public void run()
{
userLoginView.toMainActivity(user);
userLoginView.hideLoading();
}
}); } @Override
public void loginfail()
{
//需要在UI线程执行
mHandler.post(new Runnable()
{
@Override
public void run()
{
userLoginView.showFailError();
userLoginView.hideLoading();
}
}); }
});
} public void clear()
{
userLoginView.clearUsername();
userLoginView.clearPassword();
}
}
IUserBiz.java
public interface IUserBiz {
public void login(String username,String password,OnLoginListener loginListener);
}
UserBiz.java
public class UserBiz implements  IUserBiz {

    @Override
public void login(final String username,final String password, final OnLoginListener loginListener) {
new Thread(){
@Override
public void run() {
try
{
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
} if("name".equals(username)&&"pwd".equals(password)){
User user = new User();
user.setUsername(username);
user.setPassword(password);
loginListener.loginsuccess(user);
}else{
loginListener.loginfail();
} }
}.start();
}
}

OnLoginListener.java

public interface OnLoginListener {
void loginsuccess(User user);
void loginfail();
}

Android开发学习--MVP模式入门的更多相关文章

  1. Android开发学习--ViewPager使用入门

    ViewPager已经有了滑动的功能 activity_main.xml <?xml version="1.0" encoding="utf-8"?> ...

  2. Android开发学习总结(一)——搭建最新版本的Android开发环境

    Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...

  3. Android开发学习之路-RecyclerView滑动删除和拖动排序

    Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...

  4. Android菜鸟的成长笔记(1)——Android开发环境搭建从入门到精通

    原文:Android菜鸟的成长笔记(1)--Android开发环境搭建从入门到精通 今天在博客中看到好多Android的初学者对Android的开发环境的搭建不熟悉而导致不能进行学习,所以我决定自己写 ...

  5. Android开发学习之路--Activity之初体验

    环境也搭建好了,android系统也基本了解了,那么接下来就可以开始学习android开发了,相信这么学下去肯定可以把android开发学习好的,再加上时而再温故下linux下的知识,看看androi ...

  6. Android开发学习之路--MAC下Android Studio开发环境搭建

    自从毕业开始到现在还没有系统地学习android应用的开发,之前一直都是做些底层的驱动,以及linux上的c开发.虽然写过几个简单的app,也对android4.0.3的源代码做过部分的分析,也算入门 ...

  7. Android开发学习路线的七个阶段和步骤

    Android开发学习路线的七个阶段和步骤           Android学习参考路线     第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环. 2.String和St ...

  8. Android开发学习路线图

    Android开发学习方法: Android是一个比较庞大的体系,从底层的Linux内核到上层的应用层,各部分的内容跨度也比较大.因此,一个好的学习方法对我们学习Android开发很重要. 在此建议, ...

  9. android开发学习笔记000

    使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...

随机推荐

  1. 【转载】HTTP协议与WEB本质

    当你在浏览器地址栏敲入"http://www.csdn.net/",然后猛按回车,呈现在你面前的,将是csdn的首页了(这真是废话,你会认为这是理所当然的).作为一个开发者,尤其是 ...

  2. A + B Problem II(杭电1002)

    /*A + B Problem II Problem Description I have a very simple problem for you. Given two integers A an ...

  3. Navicat for MySQL中文破解版免费下载

    不知道用过MySQL workbench数据库的朋友或站长有没有都遇到过这样的问题? 就是用ssh的连接方式连接数据库的时候,第一次可以连接的上,但是第二次就不行了,以后再用workbench就再也连 ...

  4. python 【第二篇】python基本数据类型

    python数据类型 python的数据类型和大多数编程语言一样,有int,float,long,string但是python有三个特殊的数据类型:列表,元组,字典 如果不知道你的数据类型有什么方法: ...

  5. 另外几种Java集合框架具体解释续

    另外几种Java集合框架具体解释续 作者:chszs,未经博主同意不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs fastutil库优于Trove库的 ...

  6. 【扩展知识2】函数strlen()和非函数sizeof的使用

    [扩展知识2]函数strlen()和非函数sizeof的使用 [扩展文件夹] strlen函数 sizeof ( 1 )函数strlen() 原型:size_tstrlen ( const char ...

  7. 运行tomcat6w.exe ,提示 指定的服务未安装 unable to open the service 'tomcat6'

    错误:运行tomcat6w.exe ,提示 指定的服务未安装 unable to open the service 'tomcat6'(我用的是官网下载的解压版) 解决方法: 打开命令行提示符窗口=& ...

  8. accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递(看一下QWidget::mousePressEvent的实现,最为典型。如果希望忽略事件,只要调用父类的响应函数即可)

    QEvent的accept()和ignore()一般不会用到,因为不如直接调用QWidget类的事件处理函数直接,而且作用是一样的,见下面的例子. 推荐直接调用QWidget的事件处理函数.而不是调用 ...

  9. ABAP WEBRFC

    通过WEBRFC实现在网页下载SMW0上传的文件 FUNCTION zhr_download_test. *"---------------------------------------- ...

  10. solr 7.2.1 单机及伪集群启动

    1.solr的下载: 下载地址:solr官网:http://lucene.apache.org/solr进入官网点击download或者点击链接https://lucene.apache.org/so ...