初试Android的MVP框架

参考博文:http://blog.csdn.net/lmj623565791/article/details/46596109;
git文档https://github.com/konmik/konmik.github.io/wiki
译文http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0425/2782.html
在Android开发中,一直很困惑,也没有类似于Web开发中的MVC模式,如何建立Android的包名。怎么让其他人明白你建立的包的意义。
今天终于了解到一个Android的开发框架了,根据以上的博客写了一个小的登录的Demo,并分享一下我对MVP的理解。
一般的模式
我们常用的Android开发模式,是在Activity中直接操作数据,称之为View-Model模式。
View-model
这种设计模式使得View层和Model层混乱,不便于管理和维护。
因此就产生了MVP模式,Model-View-presenter.下面一张图清晰的描述了MVP的设计思路
MVP
MVP的优点:
1、解决视图层和Model层混乱的业务逻辑
2、减少View层的代码量,视图更新操作可以交给Persenter来完成,更容易排错。
3、减少其他类对View层的依赖,只需要Persenter依赖View。
4、使用Junit测试更容易。
想一想,在Web开发中,我们要先写Model,然后写Dao以及实现,然后提供service层方法,一步步都可以使用Junit来进行测试。Android使用这种框架也可以测试单独的方法了。
下面是我的例子(以用户登录为例子):
1、建包
建包
bean里面存放数据类型 例如 User userName password
biz定义一些业务逻辑以及实现方法 例如:用户的登录判断
presenter具体的执行方法。执行登录,并返回结果
view,定义具体View中要实现的方法,面向用户的操作。例如:用户点击登录,需要获取用户名、密码、显示进度条等操作。
activity具体的View实现类。实现view中定义的方法。
2、业务逻辑
在biz中提供登录接口:

/**
 * Created by admin on 2016/4/13.
 * 用户操作方法的接口
 * 登录
 */
public interface IUserBiz {
    void login(String username,String password,OnLoginListener loginListener);
}

接口的实现UserBiz

public class UserBiz implements IUserBiz {
    @Override
    public void login(String username, String password,OnLoginListener loginListener){
        Log.i("----->","进行登录,访问网络");
        //模拟子线程的耗时操作
            try {
                Log.i("--------->","执行线程,睡眠30秒");
                Thread.sleep(3000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if("lzl".equals(username)&&"psd".equals(password)){
                //执行成功的业务逻辑
                User u = new User();
                u.setUsername(username);
                u.setPassword(password);
                loginListener.loginSuccess(u);
            }else{
                //执行失败的业务逻辑
                loginListener.loginFailed();
            }
    }
}

业务逻辑的接口回调OnLoginListener
判断用户是否登录成功,并在Presenter层实现具体的操作,为view返回结果。

/**
 * Created by admin on 2016/4/13.
 * 对于业务逻辑的监听回调接口。
 * 对登录操作的回调
 * 成功,失败
 */
public interface OnLoginListener {
    void loginSuccess(User user);
    void loginFailed();
}

3、View层接口
面向界面编程,用户操作登录界面,输入数据,进行登录,需要获取用户名和密码
点击登录按钮,需要弹出和隐藏进度条,返回登录结果成功或失败。

/**
 * Created by admin on 2016/4/13.
 * 交互接口类,
 * 通过该接口使得Presenter和View交互
 */
public interface IUserLoginView {
    //需要的数据
    String getUserName();
    String getPassword();
    //产生友好的提示
    void showLoading();
    void hideLoading();
    //对应按钮的交互
    void clearUserName();
    void clearPassword();
    //登录结果反馈
    void toMainActivity(User user);
    void showFailedError();
}

4、View层的具体实现

/**
 *用户登录界面
 */
public class LoginActivity extends Activity implements IUserLoginView,View.OnClickListener{

    // UI references.
    private EditText passwordEt,userNameEt;
    private ProgressBar loginProgress;
    private Button loginBtn,clearBtn;
    private UserLoginPresenter userLoginPresenter = new UserLoginPresenter(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        initView();
    }

    private void initView() {
        passwordEt = (EditText) findViewById(R.id.password_et);
        userNameEt = (EditText) findViewById(R.id.userName_et);
        loginProgress = (ProgressBar) findViewById(R.id.login_progress);
        loginBtn = (Button) findViewById(R.id.login_btn);
        clearBtn = (Button) findViewById(R.id.clear_btn);

        loginBtn.setOnClickListener(this);
        clearBtn.setOnClickListener(this);
    }

    @Override
    public String getUserName() {

        return userNameEt.getText().toString();
    }

    @Override
    public String getPassword() {
        return passwordEt.getText().toString();
    }

    @Override
    public void showLoading() {
       loginProgress.setVisibility(View.VISIBLE);
        Log.i("MainActivity","已经显示进度条了");
    }

    @Override
    public void hideLoading() {
        loginProgress.setVisibility(View.GONE);
    }

    @Override
    public void clearUserName() {
        userNameEt.setText("");
    }

    @Override
    public void clearPassword() {
        passwordEt.setText("");
    }

    @Override
    public void toMainActivity(User user) {
        Intent mIntent = new Intent(this,MainActivity.class);
        Bundle b = new Bundle();
        b.putSerializable("User",user);
        mIntent.putExtras(b);
        startActivity(mIntent);
    }

    @Override
    public void showFailedError() {
        Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.login_btn:
                userLoginPresenter.login();
                break;
            case R.id.clear_btn:
                userLoginPresenter.clear();
                break;
        }
    }
}

1、添加对Presenter的依赖
2、实现View层接口的方法(其实acitivity应该放在View包下面)。
5、Presenter执行view操作

/**
 * Created by admin on 2016/4/13.
 * 用户登录的主持类
 *  该类起到承上启下的作用
 * 1、调用Biz的业务逻辑
 * 2、更新View的操作
 */
public class UserLoginPresenter {
    private IUserBiz userBiz;
    private IUserLoginView userLoginView;
    private Handler mHandler = new Handler();
    public UserLoginPresenter(IUserLoginView userLoginView){
        this.userLoginView = userLoginView;
        this.userBiz = new UserBiz();
    }

    /**
     * 登录操作
     */
    public void login(){
        //进度框
        userLoginView.showLoading();
        Log.i("UserLoginPresenter","显示进度条");
        userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() {
            @Override
            public void loginSuccess(final User user) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        //登录成功..
                        userLoginView.toMainActivity(user);
                        userLoginView.hideLoading();
                    }
                });
            }

            @Override
            public void loginFailed() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        //登录失败...
                        userLoginView.showFailedError();
                        userLoginView.hideLoading();
                    }
                });
            }
        });

    }

    /**
     * 清空操作
     */
    public void clear(){
        userLoginView.clearUserName();
        userLoginView.clearPassword();
    }
}

对应的view操作,有哪些,就去实现哪些操作方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值