Android MVP框架和简单的使用

几天给大家简单的介绍一下MVP,并且简单的使用和了解MVP的框架和用法。一下是对MVP的简单的概括。
一、MVP介绍
     随着UI创建技术的功能日益增强,UI层也履行着越来越多的职责。为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Model-View-Presenter)模式应运而生。
     在MVP模式里通常包含4个要素:
     (1) View :负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
     (2 ) View interface :需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
     (3) Model :负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
     (4) Presenter :作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。



二、为什么使用MVP模式
     在Android开发中,Activity并不是一个标准的MVC模式中的Controller, 它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。当我们将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理).
     另外,回想一下你在开发Android应用时是如何对代码逻辑进行单元测试的?是否每次都要将应用部署到Android模拟器或真机上,然后通过模拟用户操作进行测试?然而由于Android平台的特性,每次部署都耗费了大量的时间,这直接导致开发效率的降低。而在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的,这说明了什么?说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。

三、MVP与MVC的异同
     MVC模式与MVP模式都作为用来分离UI层与业务层的一种开发模式被应用了很多年。在我们选择一种开发模式时,首先需要了解一下这种模式的利弊:
     无论MVC或是MVP模式都不可避免地存在一个弊端:
           额外的代码复杂度及学习成本。
     这就导致了这两种开发模式也许并不是很小型应用。
     但比起他们的优点,这点弊端基本可以忽略了:
     (1)降低耦合度
     (2)模块职责划分明显
     (3)利于测试驱动开发
     (4)代码复用
     (5)隐藏数据
     (6)代码灵活性

     对于MVP与MVC这两种模式,它们之间也有很大的差异。 有一些程序员选择不使用任何一种模式,有一部分原因也许就是不能区分这两种模式差异 。以下是这两种模式之间最关键的差异:
     
     MVP模式:
  • View不直接与Model交互,而是通过与Presenter交互来与Model间接交互
  • Presenter与View的交互是通过接口来进行的,更有利于添加单元测试
  • 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑     
     MVC模式:
  • View可以与Model直接交互
  • Controller是基于行为的,并且可以被多个View共享
  • 可以负责决定显示哪个View

接下来就简单的实现一个登录注册的功能,:

先看一下建包:model,presenter,view



在model和view中,分别建两个接口,Imodel.class,Iview.class

package model;

import bean.User;

/**
 * Created by 笔片 on 2017/11/1.
 */

public interface Imodel {
    /**
     * 登录
     *
     * @param user
     * @return 约定返回"true"为登录成功,其他为登录失败的错误信息
     */
    String login(User user);
}

Iview:
package view;

/**
 * Created by 笔片 on 2017/11/1.
 */

public interface Iview {
    /**
     * 登录成功
     */
    void onLoginSuccess();

    /**
     * 登录失败
     *
     * @param error
     */
    void onLoginFailed(String error);
}

然后分别建两个类,usermodel,userview,来分别实现这两个接口
package view;

/**
 * Created by 笔片 on 2017/11/1.
 */

public class userview implements Iview{
    @Override
    public void onLoginSuccess() {

    }

    @Override
    public void onLoginFailed(String error) {

    }
}

usermodel:
package model;

import com.bwie.test.mymvptext.API;

import java.io.IOException;
import java.util.HashMap;

import bean.User;
import bean.UserBean;
import okhttp3.Call;
import utils.GsonObjectCallback;
import utils.OkHttp3Utils;

/**
 * Created by 笔片 on 2017/11/1.
 */

public class usermodel implements Imodel{
    String result;

    @Override
    public String login(User user) {
        HashMap<String,String> map = new HashMap<>();
        map.put("mobile",user.getUsername());
        map.put("password",user.getPassword());
        OkHttp3Utils.getInstance().doPost(API.LOGIN, map, new GsonObjectCallback<UserBean>() {
            @Override
            public String onUi(UserBean userBean) {
                String code = userBean.getCode();
                if (code.equals("0")){
                    result = "true";
                }else {
                    result = "fales";
                }
                return code;
            }

            @Override
            public void onFailed(Call call, IOException e) {

            }
        });
        return result;
    }
}
这其中,用到了Okhttp来请求网络数据,所以导入一些OkHttp的相关内容,我这里边是导入了一个依赖,各种办法都可以,不知道的人可以去 http://blog.csdn.net/pentablet/article/details/78273444看看,这里边有队OkHttp的详细介绍和代码,咋们继续,这里的User类,是网络接口实体类,自己找一个借口,自己封装就可以,就不粘贴了,然后自己再建一个Api类,里边用来存放网络接口。
Api.class:"LOGIN"是我的接口,
package com.bwie.test.mymvptext;

/**
 * Created by 笔片 on 2017/11/1.
 */

public class API {
    public static final String LOGIN = "http://120.27.23.105/user/login";
}

由于是要实现登录功能,所以用户要输入用户和密码,同时,我们也要获取输入的内容,与网络接口进行比较,所以,要建一个UserBean的实体类,来存放用户名和密码:
UserBean.class:
package bean;

/**
 * Created by 笔片 on 2017/11/1.
 */

public class User {
    private String username;
    private String password;

    @Override
    public String toString() {
        return "User{" +
                "password='" + password + '\'' +
                ", username='" + username + '\'' +
                '}';
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public User(String password, String username) {

        this.password = password;
        this.username = username;
    }
}

在presenter包中建 UserPresenter类:

UserPresenter.class:
package presenter;

import android.os.Handler;
import android.os.Looper;

import bean.User;
import model.Imodel;
import model.usermodel;
import view.Iview;

/**
 * Created by 笔片 on 2017/11/1.
 */

public class UserPresenter {
    private final Iview userView;
    private final Imodel userModel;

    public UserPresenter(Iview userView) {
        this.userView = userView;
        this.userModel = new usermodel();
    }

    /**
     * 登录
     */
    public void Login(final User user) {

        final String res = userModel.login(user);

        if ("true".equals(res)) {
            userView.onLoginSuccess();


        } else {
            userView.onLoginFailed(res);
        }
    }

}

最后就剩下主函数了:
MainActivity.class:
package com.bwie.test.mymvptext;

import android.app.ProgressDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import bean.User;
import presenter.UserPresenter;
import view.Iview;

public class MainActivity extends AppCompatActivity implements Iview , View.OnClickListener{
    private UserPresenter userPresenter;
    private EditText etUserName;
    private EditText etPassword;
    private ProgressDialog loginProgreess;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etUserName = (EditText) findViewById(R.id.username);
        etPassword = (EditText) findViewById(R.id.password);
        findViewById(R.id.button).setOnClickListener(this);
        userPresenter = new UserPresenter(this);

    }

    @Override
    public void onLoginSuccess() {
        loginProgreess.dismiss();
        Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLoginFailed(String error) {
        loginProgreess.dismiss();
        Toast.makeText(MainActivity.this, "====", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View view) {
        String username = etUserName.getText().toString().trim();
        String password = etPassword.getText().toString().trim();


        loginProgreess = ProgressDialog.show(this, "登录", "正在登录...");
        userPresenter.Login(new User(password,username));
    }
}

最后布局文件也很简单:

activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.bwie.test.mymvptext.MainActivity">

    <EditText
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="63dp"
        android:ems="10"
        android:hint="请输入用户名"
        android:inputType="textPersonName" />

    <EditText
        android:id="@+id/password"
        android:hint="请输入密码"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@+id/username"
        android:layout_alignRight="@+id/username"
        android:layout_below="@+id/username"
        android:layout_marginTop="62dp"
        android:ems="10"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="85dp"
        android:text="Button" />
</RelativeLayout>


好了,这就是简单的MVP的介绍与简单的登录功能。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值