接口回调封装

  

  在开发的过程中,关于对请求回调数据的处理以及消息提示,我发现了两个问题:

  1.别人都怎么做的我不知道,但是我看到的,很多人在写网络请求的时候,不管是自己直接写的,或者还是直接使用第三方网络框架,在拿到数据的时候,一般都是自己根据返回的数据中,使用约定好的key去解析自己需要的数据,直接使用或者转换成javaBean、数组。话说,这样很麻烦不是吗,每一次请求数据就要去解析一次,不同的页面,那得重复写多少代码,而且看起来也比较乱。

  2.很多时候 ,数据请求成功或者失败,总要给用户一个简短的提示。提示什么样的文案和什么情况下需要提示,这也是个比较麻烦的问题。

  为此,我对请求回调进行了封装,代码结构清晰了很多,而且也比较好用,主要做到了以下功能:

  1.如果返回的数据是javaBean或者数组Array,只需要在请求时,在请求时的CallBack传递对应的数据类型和JavaBean.class,这样数据成功回调后,就可以把返回的Object 对象直接转换成对应的 JavaBean.class 实体对象或者 Array 对象。当然,如果返回的只是简单的数据类型的话,什么都不需要设置就可以了,直接使用返回的 String data 即可。

  2.不管回调成功还是失败,统一弹出提示的话,直接在请求时的CallBack中传递个Context 对象;不需要提示则不传;想自己定制提示内容,则不传,并在CallBack 中对应的 onSuccess、onFailure方法中,弹出自己想要的内容。

  废话不多说了,直接上代码~

  一、消息提不提示的问题,我以获取验证码接口为例。

1.不主动弹出提示消息提示。

a.发起请求

ApiClient.getVerificationCode(phone,new VerificationCodeCallback());

b.数据回调

// 获取验证码回调
    public class VerificationCodeCallback extends ApiUiCallback {

        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);

        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (resultCode == 0) {
                // TODO
            }
        }
    }

想自己定制提示内容,在CallBack 中对应的 onSuccess、onFailure方法中,弹出自己想要的内容即可。

2.主动弹出提示消息提示。

a.发起请求

ApiClient.getVerificationCode(phone,new VerificationCodeCallback(this));

b.数据回调

// 获取验证码回调
    public class VerificationCodeCallback extends ApiUiCallback {
        public VerificationCodeCallback(Context context) {
            super(context);
        }

        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);

        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (resultCode == 0) {
                // TODO
            }
        }
    }

主动弹出的话,需要在回调类中 实现构造方法 VerificationCodeCallback(Context context),并在使用的时候传递个Context。

 二、数据返回Array或者 单一 JavaBean 问题

  方法说明:

setOutClass()中传递的是数组中的数据实体类。
setResponseTypeEnum()中传递的是数据的类型 单个JavaBean 还是 Array

1. 返回 Array

a.发起请求

        ApiClient.openCityList(new OpenCityListCallback().setOutClass(String.class).setResponseTypeEnum(ResponseTypeEnum.JSON_ORIGINAL_RESULT_ARRAY));

b.数据回调

public class OpenCityListCallback extends ApiUiCallback {
        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);
            showToast(R.string.network_anomaly);
        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (outDo instanceof List) {
                List<String> list = (List<String>) outDo;
                // TODO
            } else {
                showToast(resultInfo);
            }
        }

    }

2. 返回 单一 JavaBean 

a.发起请求

        ApiClient.checkNewVersion(new CheckNewVersionCallback().setResponseTypeEnum(ResponseTypeEnum.JSON_ORIGINAL_RESULT_BEAN).setOutClass(UpdateInfo.class));

b.数据回调

public class CheckNewVersionCallback extends ApiUiCallback {
        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);

        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (resultCode == 0) {
                if (outDo instanceof UpdateInfo) {
                    updateInfo = (UpdateInfo) outDo;
                    // TODO
                }
            }
        }
    }

  二话不说上源码!!!!

1. 主要的目录结构

2.  ApiConstant.class

/**
 * Created by ding on 2016/9/26
 */
public class ApiConstant {

    /**
     * 字符集:UTF-8
     */
    public static final String CHARSET_UTF8 = "UTF-8";
    /**
     * 默认字符集
     */
    public static final String DEFUALT_CHARSET = CHARSET_UTF8;
}

3.  ResponseTypeEnum.class

/**
 * 返回数据类型常量
 * Created by ding on 2016/9/26.
 */
public enum ResponseTypeEnum {

    /**
     * JSON格式字符串;
     * 基本类型按JSON格式原样输出;
     * data内容封装到Result对象的data属性,再输出JSON格式字符串;
     * data是普通JavaBean;
     */
    JSON_ORIGINAL_RESULT_BEAN("json_orig_result", true, false),
    /**
     * JSON格式字符串;
     * 基本类型按JSON格式原样输出;
     * data内容封装到Result对象的data属性,再输出JSON格式字符串;
     * data是JsonArray集合;
     */
    JSON_ORIGINAL_RESULT_ARRAY("json_orig_result", true, true),

    /**
     * 原生字符串;
     */
    STRING("string", false, false);

    private String rtType;//返回数据类型
    private boolean isJson;//返回数据是否JSON格式
    private boolean isArray;//返回数据是否JSON集合

    private ResponseTypeEnum(String rtType, boolean isJson, boolean isArray) {
        this.rtType = rtType;
        this.isJson = isJson;
        this.isArray = isArray;
    }

    public String getRtType() {
        return rtType;
    }

    public boolean isArray() {
        return isArray;
    }

    public boolean isJson() {
        return isJson;
    }
}

4.  ApiConvert.class

/**
 * Created by ding on 2016/9/26
 *convert层转换工具类
 * 提供jsonData 和outputDo的转换方法
 */
public class ApiConvert {

    private static final String TAG = "api.ApiConvert";

    /**
     * 将json格式的byte数组数据转换为业务JavaBean实例对象
     *
     * @param jsonData JSON格式的String字符串
     * @param outClass 业务JavaBean的类信息
     * @return Object outClass对应的业务JavaBean实例对象
     */
    public static Object jsonToOutputDO(String jsonData, ResponseTypeEnum responseType, Class<?> outClass) {
        if ((outClass == null) || TextUtils.isEmpty(jsonData)) {
            LogUtil.LogE(ApiConvert.class, "outClass is null or jsonData is blank.");
            return null;
        }

        try {
            if ((responseType != null) && responseType.isJson()) {
                if (responseType.isArray()) {
                    return JSON.parseArray(jsonData, outClass);
                } else {
                    return JSON.parseObject(jsonData, outClass);
                }
            } else {
                return jsonData;
            }
        } catch (Throwable e) {
            LogUtil.LogE(ApiConvert.class, "[jsonToOutputDO]invoke JSON.parseObject error.");
        }
        return null;
    }

}

5.  ApiUiCallback.class

/**
 * Created by ding on 2016/9/26.
 */
public abstract class ApiUiCallback extends RequestCallBack<String> {

    protected Context mContext = null;
    private ResponseTypeEnum responseTypeEnum = null;
    private Class<?> outClass = null;
    private String reqContent;//

    public ApiUiCallback() {
        this.mContext = null;
    }

    public ApiUiCallback(Context context) {
        this.mContext = context;
    }

    public ApiUiCallback(int rate) {
        super(rate);
        this.mContext = null;
    }

    public ApiUiCallback(Object userTag) {
        super(userTag);
        this.mContext = null;
    }

    public ApiUiCallback(int rate, Object userTag) {
        super(rate, userTag);
        this.mContext = null;
    }

    public ApiUiCallback setResponseTypeEnum(ResponseTypeEnum responseTypeEnum) {
        this.responseTypeEnum = responseTypeEnum;
        return this;
    }

    public ApiUiCallback setOutClass(Class<?> outClass) {
        this.outClass = outClass;
        return this;
    }

    public ApiUiCallback setReqContent(String reqContent) {
        this.reqContent = reqContent;
        return this;
    }

    public String getReqContent() {
        return reqContent;
    }

    @Override
    public void onSuccess(ResponseInfo<String> responseInfo) {
        String json = CommonUtil.fromtoJson(responseInfo.result);
        LogUtil.LogE(ApiUiCallback.class, "ApiUiCallback--->onSuccess");
        if (null != json) {
            JSONObject object = JSON.parseObject(json,
                    JSONObject.class);
            int resultCode = object.getInteger("resultCode");
            String resultInfo = object.getString("resultInfo");
            String jsonData = object.getString("data");
            if (mContext != null) {
                ToastTools.showToast(mContext, resultInfo);
            }
            Object outDO = ApiConvert.jsonToOutputDO(jsonData, responseTypeEnum, outClass);
            onSuccess(jsonData, resultCode, resultInfo, outDO);
        }
    }

    public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {

    }

    @Override
    public void onFailure(HttpException e, String s) {
        LogUtil.LogE(ApiUiCallback.class, "ApiUiCallback--->onFailure");
        if (mContext != null) {
            ToastTools.showToast(mContext, "请求失败");
        }
    }
}
时间: 2024-09-29 02:50:17

接口回调封装的相关文章

Android实战之 万能的接口回调

转载请标明原地址:http://blog.csdn.net/gaolei1201/article/details/47084111 前言:本人也算是自学"成才",呵呵,大学时尽管学的计算机,可是对软件开发却并不感兴趣. 毕业后看同学们或培训Android或培训IOS 4个月后都非常快找到了不错的工作.令我感到非常诧异,也非常羡慕!于是我做出了人生中重要的一个决定.開始学习Android.因为本人比較穷,所以选择自学. 学习的过程实为不易,从刚開始的一无所知时的苦苦挣扎,到学有所得后的应

Android 中的接口回调

http://blog.csdn.net/wangjinyu501/article/details/22052187 在Android中到处可见接口回调机制,尤其是UI事件处理方面.举一个最常见的例子button点击事件,button有一个点击方法onClick(),我们知道onclick()是一个回调方法,当用户点击button就执行这个方法.在源码中是这样定义的: //这个是View的一个回调接口 /** * Interface definition for a callback to be

Android实战之接口回调

由于自己以前也困于抽象.接口等"吓人"的东西,网上又缺乏在项目中实战运用的讲解,下面我就斗胆把自己的理解和大家交流一下下. 本人也算是自学"成才",呵呵,大学时虽然学的计算机,但是对软件开发却并不感兴趣.毕业后看同学们或培训Android或培训IOS 4个月后都很快找到了不错的工作,令我感到很诧异,也很羡煞!于是我做出了人生中重要的一个决定,开始学习Android,由于本人比较穷,所以选择自学.学习的过程实为不易,从刚开始的一无所知时的苦苦挣扎,到学有所得后的应对有

Android 接口回调机制详解

在使用接口回调的时候发现了一个经常犯的错误,就是回调函数里面的实现有可能是用多线程或者是异步任务去做的,这就会导致我们期望函数回调完毕去返回一个主函数的结果,实际发现是行不通的,因为如果回调是多线程的话你是无法和主函数同步的,也就是返回的数据是错误的,这是非常隐秘的一个错误.那有什么好的方法去实现数据的线性传递呢?先介绍下回调机制原理. 回调函数 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数

谈谈-Android中的接口回调技术

Android中的接口回调技术有很多应用的场景,最常见的:Activity(人机交互的端口)的UI界面中定义了Button,点击该Button时,执行某个逻辑. 下面参见上述执行的模型,讲述James对Android接口回调技术的理解(结合前人的知识和自己的实践). 使用一个比喻很形象地说明:客户端有个疑问打电话请教服务端,但服务端无法现场给出解答,相互之间约定:服务端一旦有答案,使用电话的方式反馈给客户端. 以上有三个主体:客户端.服务端和接口(方式). 接口回调的原理框图说明: Demo界面

Delphi使用android的NDK是通过JNI接口,封装好了,不用自己写本地代码,直接调用

一.Android平台编程方式:      1.基于Android SDK进行开发的第三方应用都必须使用Java语言(Android的SDK基于Java实现)      2.自从ndk r5发布以后,已经允许完全用C/C++ 来开发应用或者游戏,而不再需要编写任何Java 的代码   Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序. 二.跨平台移动开发   Delphi使用android的NDK是通过JNI接口,封装好了,不用自己

微信公众平台消息接口开发-封装weixin.class.php(转)

一.封装weixin.class.php 由于微信公众平台的通信使用的是特定格式的XML数据,每次接受和回复都要去做一大堆的数据处理. 我们就考虑在这个基础上做一次封装,weixin.class.php,代码如下: <?php class Weixin {     public $token = '';//token     public $debug =  false;//是否debug的状态标示,方便我们在调试的时候记录一些中间数据     public $setFlag = false;

接口回调和向上转型

抄别人的,但为了自己掌握更加的踏实,所以复制到这里,拜谢原创!http://blog.csdn.net/u014025369/article/details/24707525 接口回调是指:可以把使用实现了某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法.实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调.看下面示例.interface People {     void people

【C/C++学院】0828-数组与指针/内存分配/数据结构数组接口与封装

[送给在路上的程序员] 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现. 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步. 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现. 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我. 数组与指针 #include<stdio.h> #include<stdlib.h> void main1() { int a[10]