«

Android快速开发之appBase——(5).BasePresenter的使用

时间:2024-3-2 18:40     作者:韩俊     分类: Android


转载请注明本文出自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包,直接上源码。

下载地址

标签: android

热门推荐