您的位置:首页 > 移动开发 > Android开发

初试Android的MVP框架

2016-04-13 17:10 429 查看
参考博文: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层混乱,不便于管理和维护。

因此就产生了MVP模式,Model-View-presenter.下面一张图清晰的描述了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操作,有哪些,就去实现哪些操作方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android mvp