Android的okhttp,OkGo,OkHttpUtils自定义CallBack的JsonCallback自定义
来源:互联网 发布:广州质量追溯软件 编辑:程序博客网 时间:2024/06/08 12:30
OkHttpUtils自定义CallBack的JsonCallback
这篇文档主要讲解JsonCallback的自定义方法与原理。这里我已经封装好了一个回调类了,该类包括了网络请求的加载对话框,检查接口是否是否需要登录,跳转登录界面,以及服务端返回code的判断及处理,网络请求出错提示,借助泛型可以自定义回调返回类型。无需在每个地方去重复做这些工作,一个回调类就可以搞定这些工作。
这里要注意的是,根据服务端返回的数据格式来写该类的业务逻辑,比较每个系统的业务逻辑不是一样的。
我们先看看一些服务端返回的格式类型,一般服务端返回的数据格式都是这样的,我相信这4种数据格式包含了99%以上的业务。
- 数据类型A-最外层数据类型是
JsonObject
,data 数据也是JsonObject
{"code":0,"msg":"请求成功","data":{"id":123456,"name":"张三","age":18}}
- 数据类型B-最外层数据类型是
JsonObject
,data 数据是JsonArray
{"code":0,"msg":"请求成功","data":[{"id":123456,"name":"张三","age":18},{"id":123456,"name":"张三","age":18},{"id":123456,"name":"张三","age":18}]}
- 数据类型C-没有固定的 msg、code 字段格式包装,服务器任意返回对象
"data":{"id":123456,"name":"张三","age":18}
- 数据类型D-最外层数据类型是
JsonArray
,内部数据是JsonObject
[{"id":123456,"name":"张三","age":18},{"id":123456,"name":"张三","age":18},{"id":123456,"name":"张三","age":18}]
下面的类只适用于数据类型A和B。(一般做法还是让服务端规范数据格式)
package com.yunyou.icloudinn.bookhouse.Callback;import android.app.Activity;import android.app.ActivityManager;import android.app.ProgressDialog;import android.content.Intent;import android.os.Looper;import android.view.Window;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.TypeReference;import com.yunyou.icloudinn.bookhouse.Activity.LoginActivity;import com.yunyou.icloudinn.bookhouse.Config.ResultCode;import com.yunyou.icloudinn.bookhouse.JavaBean.Result;import com.yunyou.icloudinn.bookhouse.Util.ToastUtils;import com.zhy.http.okhttp.OkHttpUtils;import com.zhy.http.okhttp.callback.Callback;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.net.ConnectException;import java.net.HttpRetryException;import java.net.SocketException;import java.net.SocketTimeoutException;import java.net.UnknownHostException;import javax.security.auth.login.LoginException;import okhttp3.Call;import okhttp3.Request;import okhttp3.Response;import static android.content.Context.ACTIVITY_SERVICE;/** * ================================================ * 作 者:陈万洲 * 版 本:1.0 * 创建日期:2017/8/24 * 描 述:默认将返回的数据解析成需要的Bean,可以是 BaseBean,String,List,Map * 处理需要登录逻辑 * 注 意:不能用其他类继承该类,否则无法使用 * ================================================ */public abstract class JsonCallback<T> extends Callback<T> { private Activity activity; private ProgressDialog dialog; // 加载对话框 private boolean isShowLoading = false; //是否显示对话框 private void initDialog() { dialog = new ProgressDialog(activity); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setCanceledOnTouchOutside(false); dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); dialog.setMessage("请求网络中..."); } public JsonCallback(Activity activity,boolean isShowLoading) { this.activity = activity; this.isShowLoading = isShowLoading; if(isShowLoading){ initDialog(); } } @Override public void onBefore(Request request, int id) { if(isShowLoading) { if (dialog != null && !dialog.isShowing()) { dialog.show(); } } } @Override public T parseNetworkResponse(Response response , int id) throws Exception { Result<String> result = JSON.parseObject(response.body().string(),new TypeReference<Result<String>>(){}); // 解析出当前类的父类上的泛型的真实泛型 ,继承该类是获取的泛型会变 Type genType = getClass().getGenericSuperclass(); Type type = ((ParameterizedType)genType).getActualTypeArguments()[0]; T data = null; // api接口状态 if (result.getCode() == 100) { if(result.getData()==null||result.getData()=="")return null; if(type.equals(String.class)){ data = (T)result.getData(); }else { data = JSON.parseObject(result.getData(), type); } }else if(result.getCode() == 101||result.getCode() == 103){ //根据取消其他请求 防止弹出多次登录界面 OkHttpUtils.getInstance().cancelTag(activity); //有登录需求时 跳转登录界面 Intent intent = new Intent(); intent.setClass(activity, LoginActivity.class); if(!isTopLoginRun()&&LoginActivity.runningNum < 1){ // 防止连续多次打开请登录界面,请在LoginActivity申请该静态变量, // 并在onStop()方法中--1操作 // 在此处 ++1操作(为了更快,如在LoginActivity的oncreate()中++1无法达到此效果) LoginActivity.runningNum = LoginActivity.runningNum + 1; activity.startActivityForResult(intent, ResultCode.LOGIN_SUCCEED);//请求码的值随便设置,但必须>=0 throw new LoginException("没有登录哦"); } } else { showToast(result.getMsg()); throw new Exception("数据请求异常!"); } if(data==null||data=="")throw new NullPointerException("数据为空!"); return data; } @Override public void onError(Call call, Exception e, int id) { if(e instanceof UnknownHostException||e instanceof ConnectException){ ToastUtils.showLongToast("网络连接失败,请连接网络...."); }else if(e instanceof SocketTimeoutException){ ToastUtils.showLongToast("网络请求超时"); }else if(e instanceof HttpRetryException){ ToastUtils.showLongToast("服务器拒绝请求"); }else if(e instanceof SocketException){ //ToastUtils.showShortToast("网络请求取消!"); }else if(e instanceof LoginException){ ToastUtils.showShortToast(e.getMessage()); } else { ToastUtils.showShortToast("网络错误!"+e); } } @Override public void onAfter(int id) { super.onAfter(id); if(!isShowLoading)return; if (dialog != null && dialog.isShowing()) { try { dialog.dismiss(); }catch (Exception e){ } } } // 子线程弹出toast private void showToast(String s){ Looper.prepare(); ToastUtils.showLongToast(s); Looper.loop(); } // 判断LoginActivity是否处于顶层 private boolean isTopLoginRun() { ActivityManager am = (ActivityManager)activity.getSystemService(ACTIVITY_SERVICE); String topActivity = am.getRunningTasks(1).get(0).topActivity.getClassName(); if(topActivity==LoginActivity.class.toString()){ return true; }else { return false; } }}
参考(作者写得非常好):https://github.com/jeasonlzy/okhttp-OkGo/wiki/JsonCallback
具体原理请参考这篇文章:http://www.jianshu.com/p/4c17956fe3b4
阅读全文
1 0
- Android的okhttp,OkGo,OkHttpUtils自定义CallBack的JsonCallback自定义
- OkHttpUtils | okhttp-OkGo的使用,完美支持RxJava
- OKGO使用,编写JSONCALLBACK
- okhttp的自定义封装
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- Okhttp与Okhttputils的用法及区别
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- okhttp-OkGo
- 关于okhttp的自定义拦截器
- android okGo、okHttp、XUtils网络框架使用
- Android okHttp封装库(2) -- okhttp-OkGo
- OkHttp的Callback回调封装
- 自定义okhttp
- 使用callback实现自定义的erlang行为模式
- okGo的相关应用
- 使用okgo的步骤
- 实现Shell脚本自动备份Gitlab档案并同步到远程
- CentOS7编译安装Subversion1.9.7及Apache2.4.27并集成
- 纯干货,Spring-data-jpa详解,全方位介绍
- 蚂蚁金服平台摘要
- POJ3045
- Android的okhttp,OkGo,OkHttpUtils自定义CallBack的JsonCallback自定义
- 左链接 数据变少 sql语句
- js中如何将arguments伪数组转为数组
- 附1.pyton中的range()函数
- 1275:小明A+B(2)
- python文件运行报错: 'NoneType' object has no attribute 'TF_DeleteStatus'
- loj #2038. 「SHOI2015」超能粒子炮・改(组合数学)
- maven运行项目出现编译环境的错误
- dommemstat