1

Android MVP模式实战

 2 years ago
source link: http://www.androidchina.net/6882.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Android MVP模式实战 – Android开发中文站

一、什么是MVP

在网上找了些资料,整理如下:

MVP是模型(Model)、视图(View)、主持人(Presenter)的缩写,分别代表项目中3个不同的模块。

模型(Model):负责处理数据的加载或者存储,比如从网络或本地数据库获取数据等;

视图(View):负责界面数据的展示,与用户进行交互;

主持人(Presenter):相当于协调者,是模型与视图之间的桥梁,将模型与视图分离开来。

如下图所示,View与Model并不直接交互,而是使用Presenter作为View与Model之间的桥梁。其中Presenter中同时持有Viwe层以及Model层的Interface的引用,而View层持有Presenter层Interface的引用。当View层某个界面需要展示某些数据的时候,首先会调用Presenter层的某个接口,然后Presenter层会调用Model层请求数据,当Model层数据加载成功之后会调用Presenter层的回调方法通知Presenter层数据加载完毕,最后Presenter层再调用View层的接口将加载后的数据展示给用户。这就是MVP模式的整个核心过程。

在MVP模式里通常包含4个要素:
(1)View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
(2)View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
(3)Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
(4)Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

二、MVP模式的使用

上面一张简单的MVP模式的UML图,从图中可以看出,使用MVP,至少需要经历以下步骤:

1.创建IPresenter接口,把所有业务逻辑的接口都放在这里,并创建它的实现PresenterCompl(在这里可以方便地查看业务功能,由于接口可以有多种实现所以也方便写单元测试)
2.创建IView接口,把所有视图逻辑的接口都放在这里,其实现类是当前的Activity/Fragment
3.由UML图可以看出,Activity里包含了一个IPresenter,而PresenterCompl里又包含了一个IView并且依赖了Model。Activity里只保留对IPresenter的调用,其它工作全部留到PresenterCompl中实现
4.Model并不是必须有的,但是一定会有View和Presenter

三、一个简单的MVP示例

实现一个简单的用户登录

效果如下:

先来看看Java文件的目录结构:

1.Baen包

UserBean

package com.example.mvpe.bean;

/**
 * Created by fendo on 2017/4/29.
 */

public class UserBean {
    private  String username;
    private  String userpwd;

    public UserBean() {
    }

    public UserBean(String username, String userpwd) {
        this.username = username;
        this.userpwd = userpwd;
    }

    public String getUsername() {
        return username;
    }

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

    public String getUserpwd() {
        return userpwd;
    }

    public void setUserpwd(String userpwd) {
        this.userpwd = userpwd;
    }
}

2.Model包

IUserModel类

package com.example.mvpe.model;

import com.example.mvpe.bean.UserBean;

/**
 * Created by fendo on 2017/4/29.
 */

public interface IUserModel {

    void setSid(int cid);
    UserBean load(int sid);
    void setUsername(String username);
    void setUserpwd(String userpwd);
}

UserModelimp类

package com.example.mvpe.model;

import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;

import com.example.mvpe.bean.UserBean;

/**
 * Created by fendo on 2017/4/29.
 */

public class UserModelimp implements IUserModel{

    private static final String ACTIVITY_TAG="UserModelimp";
    private  String username;
    private  String userpwd;
    private  int sid;
    private SparseArray su=new SparseArray();

    @Override
    public void setSid(int cid) {
        sid=cid;
    }

    @Override
    public UserBean load(int sidy) {
        sid=sidy;
        UserBean ub=su.get(sid,new UserBean("not found",
                "not found"));
        return ub;
    }


    @Override
    public void setUsername(String usernamey) {
        username=usernamey;
    }

    @Override
    public void setUserpwd(String userpwdy) {
        userpwd=userpwdy;
        UserBean usb=new UserBean(username,userpwd);
        System.out.print(username+"----"+userpwd+"----"+sid);
        Log.d(UserModelimp.ACTIVITY_TAG, "Start_OK"+username+"----"+userpwd+"----"+sid);
        su.append(sid,usb);
    }
}

3.persenter包

UserPersenter类

package com.example.mvpe.presenter;

import android.util.Log;
import android.view.View;

import com.example.mvpe.bean.UserBean;
import com.example.mvpe.model.IUserModel;
import com.example.mvpe.model.UserModelimp;
import com.example.mvpe.view.IUserView;



/**
 * Created by fendo on 2017/4/29.
 */

public class UserPersenter {

    private static final String ACTIVITY_TAG="UserPersenter";

    private IUserView iUserView;
    private IUserModel iUserModel;

    public  UserPersenter(IUserView view){
        iUserView=view;
        iUserModel=new UserModelimp();
    }

    public void saveuser(int sid,String username,String userpwd){
        iUserModel.setSid(sid);
        iUserModel.setUsername(username);
        iUserModel.setUserpwd(userpwd);
    }

    public void loaduser(int sid){
        UserBean usb=iUserModel.load(sid);
        Log.d(ACTIVITY_TAG, "loaduser: "+usb.getUsername());
        iUserView.setUsername(usb.getUsername());
        iUserView.setUserpwd(usb.getUserpwd());
    }

}

4.view包

IUserView类

package com.example.mvpe.view;

import com.example.mvpe.bean.UserBean;

/**
 * Created by fendo on 2017/4/29.
 */

public interface IUserView {

    int getID();

    void setUsername(String username);
    void setUserpwd(String userpwd);

    String getUserpwd();
    String getUsername();
}

UserActivity类

package com.example.mvpe.view;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.example.mvpe.R;
import com.example.mvpe.presenter.UserPersenter;
import android.view.View.OnClickListener;
import android.widget.Toast;

/**
 * Created by fendo on 2017/4/29.
 */

public class UserActivity extends Activity implements OnClickListener,IUserView{

    private EditText userid;
    private EditText username;
    private EditText userpwd;
    private Button read;
    private Button write;
    private UserPersenter usp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        usp=new UserPersenter(this);
        setContentView(R.layout.activity_main);
        findviewbyid();
        read.setOnClickListener(this);
        write.setOnClickListener(this);
    }



    public void findviewbyid(){
        userid= (EditText) findViewById(R.id.userid);
        username= (EditText) findViewById(R.id.usertext);
        userpwd= (EditText) findViewById(R.id.userpwd);
        read= (Button) findViewById(R.id.read);
        write= (Button) findViewById(R.id.write);
    }

    @Override
    public int getID() {
        return Integer.parseInt(userid.getText().toString());
    }

    @Override
    public void setUsername(String usernamcc) {
        username.setText(usernamcc);
    }

    @Override
    public void setUserpwd(String userpw) {
      userpwd.setText(userpw);
    }

    @Override
    public String getUserpwd() {
        return userpwd.getText().toString();
    }

    @Override
    public String getUsername() {
        return username.getText().toString();
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.read :
                usp.loaduser(getID());
                Toast.makeText(getApplicationContext(), "点击了读"+getID(), Toast.LENGTH_SHORT).show();

                break;
            case R.id.write:
                usp.saveuser(getID(),getUsername(),getUserpwd());
                Toast.makeText(getApplicationContext(), "点击了存"+getID()+"--"+getUsername()+"--"+getUserpwd(), Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

可以看到View只负责处理与用户进行交互,并把数据相关的逻辑操作都扔给了Presenter去做。而Presenter调用Model处理完数据之后,再通过IUserView更新View显示的信息。

完整代码:http://download.csdn.net/detail/u011781521/9829343

转载请注明:Android开发中文站 » Android MVP模式实战


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK