初试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中提供登录接口:
接口的实现UserBiz
业务逻辑的接口回调OnLoginListener
判断用户是否登录成功,并在Presenter层实现具体的操作,为view返回结果。
3、View层接口
面向界面编程,用户操作登录界面,输入数据,进行登录,需要获取用户名和密码
点击登录按钮,需要弹出和隐藏进度条,返回登录结果成功或失败。
4、View层的具体实现
1、添加对Presenter的依赖
2、实现View层接口的方法(其实acitivity应该放在View包下面)。
5、Presenter执行view操作
对应的view操作,有哪些,就去实现哪些操作方法。
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操作,有哪些,就去实现哪些操作方法。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories