转载请注明本文出自JFlex的博客http://blog.csdn.net/jflex/article/details/46456621,请尊重他人的辛勤劳动成果,谢谢!
Android快速开发之appBase——(5).BasePresenter的使用
Presenter是来自MVP中的概念,是用来处理与用户交互的逻辑。在这里更加简单化,Presenter中的方法是根据业务来定义,比如获取消息列表,那么业务常常会这样:先去请求网络,网络正常请求到数据返回并展示在UI层,网络错误没有拿到数据,看看缓存中有没有,然后从缓存中拿到数据并返回并展示在UI层;突然,有一天业务需求发生变化,只允许获取网络,网络错误UI上显示没有消息。如果之前在UI层已经做过数据为空的处理,那么UI层就不用修改任何代码,仅仅只需要修改presenter层,这样就将UI层和业务层区分,并且耦合降低了。
1、概述
BasePresenter仅仅是提取的一个概念,实现的方式有很多种,在这里我采用callback机制,presenter和callback中的方法是对应存在的,比如presenter中getProductsByType(int type),那么这个方法主题中通过异步处理数据,处理完成之后将数据通过callback回传给setProductsByType(Object result)。
类或接口
presenter
callback
方法
getProductsByType(int type)
setProductsByType(Object result)
执行所在线程
非UI线程
UI线程
2、代码
package com.snicesoft.presenter; import android.content.Context; import com.snicesoft.util.NetworkUtil; public class BasePresenter<C extends BasePresenter.Callback> { public interface Callback { } private Context context; protected C callback; public void setCallback(C callback) { this.callback = callback; } public BasePresenter(Context context) { this.context = context; } public boolean isNetConnect() { return NetworkUtil.isConnect(getContext()); } public Context getContext() { return context; } }
代码采用内部接口定义,为了减少代码整体风格不那么臃肿。当然,也可以按照自己的编码风格自定义。
字段说明:context只是为了方便操作一些常用的业务,比如上面提到的网络连接判断。字段都可以按照自己的需求添加,比如这个presenter中需要网络请求,那么可以添加HttpReq模块;再比如需要APICloud云API请求,可以添加APICloudSDK模块。
3、使用范围
常用范围
activity:实现callback接口,定义callback所在presenter的对象字段,在onCreate中初始化。
fragment:实现callback接口,定义callback所在presenter的对象字段,在onCreate中初始化。
原则上,哪里需要就写哪里。
4、示例
WgouPresenter.java
package com.haier.rrmaker.ui.home.fragment.presenter; import android.app.ProgressDialog; import android.content.Context; import com.alibaba.fastjson.JSON; import com.haier.rrmaker.R; import com.haier.rrmaker.http.HttpParams; import com.haier.rrmaker.http.HttpResult; import com.haier.rrmaker.http.response.IndexResponse; import com.lidroid.xutils.exception.HttpException; import com.lidroid.xutils.http.ResponseInfo; import com.lidroid.xutils.http.callback.RequestCallBack; import com.snicesoft.http.HttpReq; import com.snicesoft.presenter.BasePresenter; import com.snicesoft.util.CommonUtils; import com.snicesoft.util.DialogUtil; public class WgouPresenter extends BasePresenter<WgouPresenter.Callback> { public interface Callback extends BasePresenter.Callback { void index(IndexResponse response); } HttpReq httpReq; public void setHttpReq(HttpReq httpReq) { this.httpReq = httpReq; } ProgressDialog progressDialog; public WgouPresenter(Context context) { super(context); progressDialog = DialogUtil.getProgressDialog(context); } protected void showDialog(CharSequence message, boolean... flag) { if (flag != null) { if (flag.length > 0) progressDialog.setCancelable(flag[0]); if (flag.length > 1) progressDialog.setCanceledOnTouchOutside(flag[1]); } progressDialog.setMessage(message); progressDialog.show(); } protected void closeDialog() { if (progressDialog.isShowing()) progressDialog.dismiss(); } public void index() { if (httpReq == null) return; if (isNetConnect()) { showDialog("正在加载"); httpReq.POST(HttpParams.Wgou.Index, null, new RequestCallBack<String>() { @Override public void onFailure(HttpException arg0, String arg1) { closeDialog(); CommonUtils.showToast(getContext(), R.string.net_error_retry); } @Override public void onSuccess(ResponseInfo<String> arg0) { closeDialog(); IndexResponse response = JSON.parseObject( arg0.result, IndexResponse.class); if (HttpResult.isSuccess(response)) { callback.index(response); } else { CommonUtils.showToast(getContext(), "数据返回错误"); } } }); } else { CommonUtils.showToast(getContext(), R.string.net_error); } } }
WgouFragment.java
public class WgouFragment extends AvFragment<WgouHolder, WgouData, HomeActivity> implements WgouPresenter.Callback { WgouPresenter wgouService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); wgouService = new WgouPresenter(fa()); wgouService.setHttpReq(fa().getApp().httpReq()); wgouService.setCallback(this); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); wgouService.index(); } @Override public void index(IndexResponse response) { _holder.index(response); _holder.scrollBottom(); } }
这里简单举例在Fragment中的使用:
1、首先定义Presenter和Callback
类或接口
WgouPresenter
WgouPresenter.Callback
说明
方法
index()
index(IndexResponse response)
获取首页信息
执行所在线程
非UI线程
UI线程
2、WgouFragment实现WgouPresenter.Callback
实现index(IndexResponse response)方法,将返回的数据再此方法绑定到对应的UI上。如果业务在开发之前充分沟通,这块完全可以模拟数据进行测试,后期在线上测试环境调试。
对于WgouPresenter的定义在onCreate初始化。onActivityCreated方法中进行index()请求,这只是做个演示。但是请求顺序一定不能错误:必须在WgouPresenter初始化完毕并且View初始化完毕(也就是Holder初始化完毕)
5、最后
一定要注意规范,否则会导致代码混乱。对于这套规范我写了个简单的代码生成器,生成activity和fragment的时候会将holder、data、presenter全部生成好,省去了自己创建的麻烦。 由于编译环境不同,故不提供jar包,直接上源码。
下载地址