Android平台MVP开发模式实战入门
2016-06-14 21:10
561 查看
转载请表明出处:http://blog.csdn.net/iwanttohitren/article/details/51674687
上一篇文章,我们使用android开源框架LitePal新建了一个android端数据库userinf.db,本篇我们在已建立的数据库上写一个简单的mvp模式的demo。
在看一下demo的项目结构图:
2,建立bean包,这个包里面主要是放实体类,对应数据库中的表。上一篇文章中已经写了一个实体UserBean,代码如下:
3,建立model包,这个包里主要是完成对数据的操作(我这里展示添删改查),一般先写好接口,然后再写其接口实现,这样的好处就是便于扩展和单元测试。代码如下:
接口IUserModel.java
实现类UserModel.java这里我使用的是开源框架LitePal对数据进行操作,连接上我们上一篇文章中用LitePal新建的数据库,代码实现如下:
4,建立view包,这里实现更新UI的显示内容,新建一个接口IUserView接口,包含操作view的方法,代码如下:
5,建立presenter包,通过view层接口(IUserView)和model层接口(IUserModel)操作view和model,activity可以把所有的逻辑交给presenter操作,这样一来逻辑处理就从activity分离出来了。新建UserPresenter.java,代码如下:
6,最后的工作在MainActivity中完成,实现IUserView,实例化一个UserPresenter,代码如下:
到这里,demo的所有代码已经完成,效果我就不展示了,自己写一写,耍一耍效果好。我把原码已经上传到github了,点击这里去下载
上一篇文章,我们使用android开源框架LitePal新建了一个android端数据库userinf.db,本篇我们在已建立的数据库上写一个简单的mvp模式的demo。
第一步, 了解一下mvp模式
我想从我们了解的mvc模式进行比较解说会好一点,mvp模式:M-Model-模型、V-View-视图、C-Controller-控制器,MVP作为MVC的进化,那么MVP所对应的意义:M-Model-模型、V-View-视图、P-Presenter-表示器。 从MVC和MVP两者结合来看,Controlller/Presenter在MVC/MVP中都起着逻辑控制处理的角色,起着控制各业务流程的作用。而 MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控 View与Model之间的间接交互。在 Android中很重要的一点就是主线程(MainThread)中才能操作UI,所以对View与Model的切断分离是 合理的。此外Presenter与View、Model的交互使用接口定义交互操作可以进一步达到松耦合也可以通过接口更加方便地进行单元测试。下面两张图比较一下mvc和mvp:第二步,实战入门(在上篇文章生成的数据库基础上)
1,明确一下我们的demo需求,我们小软件的示意图如下:在看一下demo的项目结构图:
2,建立bean包,这个包里面主要是放实体类,对应数据库中的表。上一篇文章中已经写了一个实体UserBean,代码如下:
public class UserBean extends DataSupport{ @Column(unique = true,nullable = false) private int mId; @Column(nullable = false) private String mName; @Column(nullable = false) private String mAge; //setter和getter ... }
3,建立model包,这个包里主要是完成对数据的操作(我这里展示添删改查),一般先写好接口,然后再写其接口实现,这样的好处就是便于扩展和单元测试。代码如下:
接口IUserModel.java
public interface IUserModel { //判断改用户是否已经存在 boolean isExist(int id); //通过用户ID获取用户信息 UserBean getUser(int id); //通过用户ID删除用户信息 boolean deleteUser(int id); //通过用户ID修改用户信息 boolean updateUser(UserBean userBean); //保存用户信息 boolean addUser(UserBean userBean); }
实现类UserModel.java这里我使用的是开源框架LitePal对数据进行操作,连接上我们上一篇文章中用LitePal新建的数据库,代码实现如下:
public class UserModel implements IUserModel { @Override public boolean isExist(int id) { /* *UserBean.class相当于定义在那个表中查询,“mid=?” 和 String.valueOf(id)是 *查询的条件,例如 form userbean where mid=2;返回类型为boolean */ boolean flag = DataSupport.isExist(UserBean.class, "mid=?", String.valueOf(id)); return flag; } @Override public UserBean getUser(int id) { /* *这是查询某条用户信息,还可以查询所有的用户信息,如: * List<UserBean> users = DataSupport.findAll(UserBean.class); * 或者进行一些复杂的查询,如: * List<UserBean> userBeans = DataSupport.where("mname like ?", * "张%").order("mid").find(UserBean.class); */ UserBean userBean = DataSupport.find(UserBean.class, id); return userBean; } @Override public boolean deleteUser(int id) { /* *返回值是int类型,表示受影响的行数.当然删除操作也可以像查询操作一样, * 进行全部删除或者复杂删除。 */ int delete = DataSupport.delete(UserBean.class, id); if(delete > 0) return true; return false; } @Override public boolean updateUser(UserBean userBean) { /* *这个是更新某条指定的数据,返回值表示收到影响的行数,也可以更新多条数据,如: * userBean.updateAll("mname=?","张三");返回值也是int类型,表示受影响的行数 */ int update = userBean.update(userBean.getmId()); if(update > 0) return true; return false; } @Override public boolean addUser(UserBean userBean) { /* *新建一个用户信息实体类,保存用户信息 */ UserBean user = new UserBean(); user.setmId(userBean.getmId()); user.setmName(userBean.getmName()); user.setmAge(userBean.getmAge()); boolean flag = user.save(); return flag; } }
4,建立view包,这里实现更新UI的显示内容,新建一个接口IUserView接口,包含操作view的方法,代码如下:
public interface IUserView { //获得用户ID文本框的内容 int getUserId(); //获取输入的用户信息 UserBean getUserInf(); //设置用户信息 void setUserInf(UserBean userBean); }
5,建立presenter包,通过view层接口(IUserView)和model层接口(IUserModel)操作view和model,activity可以把所有的逻辑交给presenter操作,这样一来逻辑处理就从activity分离出来了。新建UserPresenter.java,代码如下:
public class UserPresenter { private IUserModel mUserModel; private IUserView mUserView; public UserPresenter(IUserView userView){ mUserView = userView; mUserModel = new UserModel(); } //保存用户信息 public void saveUser(Context context){ if(mUserModel.isExist(mUserView.getUserId())){ ToastUtil.shortToast(context, "该用户id已存在"); }else { if(mUserModel.addUser(mUserView.getUserInf())){ ToastUtil.shortToast(context, "添加成功"); }else{ ToastUtil.shortToast(context, "添加失败"); } } } //删除用户信息 public void deleteUser(Context context){ if(!mUserModel.isExist(mUserView.getUserId())){ ToastUtil.shortToast(context, "该用户不存在存在"); }else { if(mUserModel.deleteUser(mUserView.getUserId())){ ToastUtil.shortToast(context, "删除成功"); }else{ ToastUtil.shortToast(context, "删除失败"); } } } //修改用户信息 public void updateUser(Context context){ if(!mUserModel.isExist(mUserView.getUserId())){ ToastUtil.shortToast(context, "该用户不存在存在"); }else { if(mUserModel.updateUser(mUserView.getUserInf())){ ToastUtil.shortToast(context, "修改成功"); }else{ ToastUtil.shortToast(context, "修改失败"); } } } //查找用户信息 public void seacherUser(Context context){ if(!mUserModel.isExist(mUserView.getUserId())){ ToastUtil.shortToast(context, "该用户不存在存在"); }else { UserBean user = mUserModel.getUser(mUserView.getUserId()); mUserView.setUserInf(user); } } }
6,最后的工作在MainActivity中完成,实现IUserView,实例化一个UserPresenter,代码如下:
public class MainActivity extends AppCompatActivity implements IUserView, View.OnClickListener { UserPresenter presenter; EditText etId, etName, etAge; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //生成数据库 SQLiteDatabase db = Connector.getDatabase(); //给按钮注册点击事件 findViewById(R.id.bt_add).setOnClickListener(this); findViewById(R.id.bt_delete).setOnClickListener(this); findViewById(R.id.bt_charge).setOnClickListener(this); findViewById(R.id.bt_search).setOnClickListener(this); etId = (EditText) findViewById(R.id.et_id); etName = (EditText) findViewById(R.id.et_name); etAge = (EditText) findViewById(R.id.et_age); //实例化UserPresenter对象,因为MainActivity实现了接口IUserView, //所以可以传入this presenter = new UserPresenter(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.bt_add: presenter.saveUser(this);//这里传入this,是为了显示toast提示窗口 break; case R.id.bt_delete: presenter.deleteUser(this); break; case R.id.bt_charge: presenter.updateUser(this); break; case R.id.bt_search: presenter.seacherUser(this); break; } } @Override public int getUserId() { return Integer.parseInt(etId.getText().toString().trim()); } @Override public UserBean getUserInf() { UserBean bean = new UserBean(); bean.setmId(Integer.parseInt(etId.getText().toString().trim())); bean.setmName(etName.getText().toString().trim()); bean.setmAge(etAge.getText().toString().trim()); return bean; } @Override public void setUserInf(UserBean userBean) { // etId.setText(userBean.getmId()); etName.setText(userBean.getmName()); etAge.setText(userBean.getmAge()); } }
到这里,demo的所有代码已经完成,效果我就不展示了,自己写一写,耍一耍效果好。我把原码已经上传到github了,点击这里去下载
相关文章推荐
- 使用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