Retrofit网络请求,数据的封装(一)。

一、为什么要封装?
1.方便自己使用
2.将Activity里网络请求的业务代码和UI展示的代码分离,有点类似于MVP。
3.接口请求复用。
二、如何封装?
1.分析需求,根据公司接口做相应的处理。
2.现在大多都是使用Json请求和响应,我只提供Json封装的思路。
三、开始封装,首先关联相应的类库
compile 'com.google.code.gson:gson:2.8.2'  // 采用Gson解析
compile 'com.squareup.retrofit2:retrofit:2.3.0' // retrofit的关键库
compile 'com.squareup.retrofit2:adapter-rxjava2:+'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'  // 引入Rxjava和RxAndroid
四、请求和响应数据的分析。
1.请求后台接口的数据格式
{
   // 1. 具体的数据
    "data": {
        "loginName": "135****5219",
        "loginPass": "12***56"
    },
     // 2. 公司接口的公共请求头
    "head": {
        "_channel_": 1,
        "_platform_id_": 1, 
        "_request_time_stamp_": 1516780484149
    }
}
 2.后台响应的数据格式
{
    "data": {
    },
     // 固定响应
    "head": {
        "bcode": "1",
        "bmessage": "Success!",
        "code": "1",
        "message": "Success!",
        "responseTime": "1516780484695"
    }
}

从请求和响应的数据分析,都有公共固定的请求参数,但data是不确定的,而且有可能是数组、字符串等等。
因为data是不固定的所以采用泛型设计最好。

五、请求JavaBean的封装
/**
 * ================================================================
 * 描述:请求头
 * ================================================================
 */
public class RequestHead {
    public long _request_time_stamp_;
    public int _channel_ = 1;
    public int _platform_id_ = 1;   
}
/**
 * 请求数据的封装
 */

public class RequestBean<T> {
    /**
     * 请求头默认带的
     */
    public RequestHead head;
    /**
     * 请求的数据,不固定
     */
    public T data;

    public RequestBean() {
        this(null);
    }

    public RequestBean(T data) {
        this.data = data;
        this.head = new RequestHead();
    }
}
六、响应数据的封装,和请求思路一样
/**
 * 响应头,默认返回
 */

public class ResponseHead {
    public String bcode;
    public String bmessage;
    public String code;
    public String message;
    public String responseTime;
}
/**
 * 响应的封装
 */
public class ResponseBean<T> {
    /**
     * 响应头,默认返回
     */
    public ResponseHead head;
    /**
     * 返回的数据,不固定
     */
    public T data;
}

这样,数据的请求和响应的封装就搞定。

七、泛型解析(自己用)
/**
 * 服务端统一返回数据格式
 * @param <T> 具体的数据
 */
public class ResponseData<T> {
    private T data;
    private String errorCode;// 0是成功
    private String errorMsg;

    public boolean isSucceed() {
        return "0".equals(errorCode);
    }
    public int getErrorCode() {
        try {
            return Integer.parseInt(errorCode);
        } catch (Exception e) {

        }
        return -1;
    }
}
// 统一处理,自己的网络库
abstract class AppCallback<T> : ICallback {

    override fun onSuccess(result: String, client: RestClient) {
        try {
            // 1. 拿到泛型类型
            val genericType = this.getType()

            // 泛型T如果是字符串特殊处理
            val isStr = genericType.toString() == "${String::class.java}"
            if (isStr) {
                onSucceed(result as T, client)
                return
            }
            // 2. 创建ResponseData类型
            val responseType = ParameterTypeImpl(ResponseData::class.java, genericType)
            // 3. 拿到数据,转成:ResponseData<T>
            val data: ResponseData<T> = RestCreator.gson.fromJson(result, responseType)
            // 4. 根据后台约定判断
            if (data.isSucceed) {
                onSucceed(data.data, client)
            } else {
                onError(data.errorCode, data.errorMsg, client)
            }
        } catch (e: Throwable) {
            onError(-1, "解析数据异常", client)
        }
    }


    abstract fun onSucceed(data: T, client: RestClient)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容