一个普通APP的开发中使用最频繁的操作莫过于网络请求,既然这样我们便需要将全部的网络请求操作都集中起来使用统一的方法进行管理。否则一个临时的任务变更会增加大量的工作量

对一个完整的网络请求进行分析,大致分为以下几个流程:

  1. 发起网络连接
  2. 得到回执消息,判断连接情况
  3. 根据实际需求对数据进行解析

  • 发起网络连接通常会使用三方网络请求库,这里以Retrofit为例,首先需要对Retrofit进行初始化操作
OkHttpClient okHttpClient = new OkHttpClient.Builder()//连接主机超时时间.connectTimeout(10, TimeUnit.SECONDS)//从主机读取超时时间.readTimeout(120, TimeUnit.SECONDS)//上传到主机的超时时间.writeTimeout(120, TimeUnit.SECONDS).build();
retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(okHttpClient).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build();

网络请求库初始化完成后开始正式发起网络请求。首先这里大致的介绍一下Retrofit的网络请求方式,在接口中通过注解的方式对URL以及请求参数进行配置,然后通过之前初始化得到的Retrofit对象来生成请求接口的实现类对象。这样就能得到每个网络请求具体的网络执行对象Call<>,最后通过Call对象开始执行网络请求并且实现请求回调。

//配置
public interface Api {@GET("xxxxx")Call<ResponseBody> getData();
}
//得到Call对象
public class Net implements Api {private static final Net ourInstance = new Net();private final Api mApi;public static Net getInstance() {return ourInstance;}private ElNet() {mApi = NetUtil.getInstance().getRetrofit().create(Api.class);}@Overridepublic Call<ResponseBody> getData() {return mApi.getData();}
}
//开始请求
Call<ResponseBody> call = getData();call.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {}});
  • 这样一个请求部分就算做完了,接下来是需要对状态进行判断,因为虽然请求已经发出但是是否请求成功是不确定的,Retrofit的回调接口中实现了两个方法,分别是成功和失败,但是需要注意,这里的失败回调仅仅是当由于自身网络原因产生的失败才会回调进onFailure()方法中,那些因为服务器原因造成的请求失败需要在onResponse()中进行进一步判断,这里可以通过response.isSuccessful()判断是否真的网络请求成功,其实这个方法的原理也就是通过判断响应码是否为200(200为成功,其他都是错误)。
call.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {if (response.isSuccessful()) {//请求成功}else {//请求失败LogUtil.setLog("failed: " + "\n 错误码:" + response.code() + " 错误信息:" + response.body());}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {//请求失败}});
  • 得到最终数据后,根据实际的项目需求进行解析,常见的解析方式是拿到Json字符串,使用Gson等三方解析库将Json转换成对应实体类进行下一步操作。
    其实如果是使用Retrofit进行数据解析的话,它是可以通过添加Gson转换器GsonConverterFactory进行直接转换的,只需要在编写网络请求参数接口时直接给Call对象指定想要生成的实体类对象便可以回调到想要的实体类对象。
    但是这样做有很大的局限性,首先你得有个好后台,你得有个好后台,你得有个好后台!重要的话说三遍!!!否则不知道数据就直接交给库进行转换,到时候各种bug都不知道错在哪里,其次这样会导致在项目中是完全看不到Json结构的,需要借助别的工具先请求该接口,看到实际的结构后生成实体类才能进行。当然,如果你有个很给力并且负责的后台,可以保证数据不会有一些奇葩的错误,并且每个接口文档都有完善的Json结构示例的话完全可以直接使用这种方式。

  • 以上说的是常规情况下的处理方式,在正常开发中,很多接口除开请求失败意外本身就是被设计成两种结果的,比较常见的例如一个登陆接口,会有登陆成功和失败两种结果,当成果是返回用户的信息,token等等,失败后返回失败原因如账号密码错误等等。这里就会涉及到处理两种完全不同的Json结构。在这种情况下Json会有一个status属性,当status为FALSE时则为失败,需要返回对应错误消息,为TRUE时成功按正常流程进行下去。所以需要先判断Json是否有Status状态,并且根据状态值进行下一步操作,由于Status状态的不确定性,还需要使用try/catch进行异常捕获,大致实现如下:

call.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {if (response.isSuccessful()) {//请求成功String json = null;try {json = response.body().string();try {JSONObject jsonObject = new JSONObject(json);String status = jsonObject.getString("status");if (status.equals("error")) {String msg = jsonObject.getString("msg");if (msg == null)msg = "未知原因";//失败情况return;}} catch (JSONException e) {e.printStackTrace();}MyApplication.gson.fromJson(json, reBody);} catch (IOException e) {e.printStackTrace();}} else {//请求失败LogUtil.setLog("failed: " + "\n" + response.code() + " " + response.body());}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {}});
  • 看起来是不是非常繁琐,而且里面还有很多细节其实是没有判断的,比如Json为空的情况等等,加上各种回调方法,这样的方法应该没有人愿意频繁的重复书写吧,但是由于每个网络请求的数据结构都是不同的,因此需要生成的实体类对象也不尽相同,常规的写法无法针对不同的数据得到不同的结果。这里便需要用的泛型的概念,不为方法指定某个具体的类型,而是我给你什么类型你就按照什么类型来解析。代码如下:
/*** presenter工具类* 需要返回数据** @param reBody   需要转出的类型* @param call     网络请求call模型* @param callBack 网络回调*/public <T> void getData(final Class<T> reBody, Call<ResponseBody> call, final PublicCallback.NetCallback<T> callBack) {call.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {if (response.isSuccessful()) {try {String json = response.body().string();LogUtil.setLog(reBody.getSimpleName() + " json :" + "\n" + json);dealJson(json, callBack);T t = MyApplication.gson.fromJson(json, reBody);if (t != null)callBack.onSuccess(t);elsecallBack.onFailed("没有数据");} catch (IOException e) {LogUtil.setLog(reBody.getSimpleName() + "error: " + "\n" + e.toString());callBack.onFailed(e.getMessage());}} else {callBack.onFailed(response.code() + "");LogUtil.setLog(reBody.getSimpleName() + "error: " + "\n" + response.code() + " " + response.body());}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {callBack.onFailed(t.getMessage());LogUtil.setLog(reBody.getName() + "error: " + t.toString());}});}/*** 对json进行初步处理,避免NULL及错误*/private void dealJson(String json, final PublicCallback.BaseCallback callBack) {if (json.trim().equals("")) {callBack.onFailed("");return;}try {JSONObject jsonObject = new JSONObject(json);String status = jsonObject.getString("status");if (status.equals("error")) {String msg = jsonObject.getString("msg");if (msg == null)msg = "未知原因";callBack.onFailed(msg);return;}} catch (JSONException e) {e.printStackTrace();}}
  • 上面方法需要传入三个参数,分别是需要解析和生成的实体类类型,Retrofit的网络请求对象Call,对应的回调接口,这里接口为了统一我也根据情况定义了几个标准的接口类型:
public class PublicCallback {public interface BaseCallback {void onFailed(String msg);}public interface NetCallBack extends BaseCallback {void onSuccess();void onFailed(String msg);}public interface NetCallback<T> extends BaseCallback {void onStart();void onSuccess(T t);void onFailed(String msg);}public interface NetCallbackVerifica<T> {void onVerification();void onStart();void onSuccess(T t);void onFailed(String msg);}public static class SimpleCallback<T> implements NetCallback<T> {@Overridepublic void onStart() {}@Overridepublic void onSuccess(T t) {}@Overridepublic void onFailed(String msg) {}}public static class SimpleCallbackVerifica<T> implements NetCallbackVerifica<T> {@Overridepublic void onVerification() {}@Overridepublic void onStart() {}@Overridepublic void onSuccess(T t) {}@Overridepublic void onFailed(String msg) {}}
}

通过这样的方式就可以实现全局网络请求的统一解析,当发现网络解析有遗漏或者需要修改参数解析逻辑的时候,便能实现全局修改,减少了很大的工作量以及个别出错的可能性。

完整解析源文件下载 附Rxjava写法

Android 打造万能网络解析框架相关推荐

  1. Android将网页做成app-- Jsoup网络解析框架

    Android将网页做成app– Jsoup网络解析框架 Jsoup能够获得网页数据,而我们在制作app的数据来源为一些公开网站,比如:干活集中营,豆瓣,知乎之类的.不过目前主流框架模式是Retrof ...

  2. android 打造万能keyStore

    概述:总所周知,我们在打包我们APK到应用市场的时候,出于安全和设置三方接入(微信.ShareSDK.地图)的唯一识别SHA1值,必须生成一个唯一的keyStore,来保证我们开发项目的安全性.唯一性 ...

  3. Android使用Fragment打造万能页面切换框架

    首先我们来回忆一下传统用Activity进行的页面切换,activity之间切换,首先需要新建intent对象,给该对象设置一些必须的参数,然后调用startActivity方法进行页面跳转.如果需要 ...

  4. Android使用Fragment打造万能页面切换框架(一)

    首先我们来回忆一下传统用Activity进行的页面切换,activity之间切换,首先需要新建intent对象,给该对象设置一些必须的参数,然后调用startActivity方法进行页面跳转.如果需要 ...

  5. Android使用Fragment打造万能页面切换框架(三)

    接下来就是处理基类BaseFragment的问题了,这里贴出该类所有代码,具体请参考注释. public class BaseFragment extends Fragment {private st ...

  6. fragment中文网_Android使用Fragment打造万能页面切换框架

    首先我们来回忆一下传统用Activity进行的页面切换,activity之间切换,首先需要新建intent对象,给该对象设置一些必须的参数,然后调用startActivity方法进行页面跳转.如果需要 ...

  7. Android之解剖网络请求框架Volley

    转载请标明出处:[顾林海的博客] 个人开发的微信小程序,目前功能是书籍推荐,后续会完善一些新功能,希望大家多多支持! Volley介绍 Volley是Google推出的网络请求库,包含的特性有JSON ...

  8. Android新的网络请求框架volley源码解释及示例

    最近遇到一个问题:我想用HttpClient来访问网络,发现怎么都无法new出HttpClient的对象,这我就有点摸不着头脑了.记得我之前都是可以使用这个类的,怎么突然间就用不了了.因为不知情,一下 ...

  9. Android 打造万能圆点指示器

    1.首先自定义圆点的属性,动态显示,比较方便修改圆点的颜色,取名为:attrs.xml <?xml version="1.0" encoding="utf-8&qu ...

  10. Android 必须最近流行的框架库及开发语言,看这一篇就够了!

    本文更新时间:2018年07月12日15:50:40 目录 导语 图片加载库 异步分发通信库 新技术语言 注入注解框架 设计模式 UI框架 网络请求库 日志打印库 logger,简单,漂亮的andro ...

最新文章

  1. jquery如何对多个对象绑定同一事件
  2. SQL Server2016 原生支持JSON
  3. wchar_t*,wchar_t,wchat_t数组,char,char*,char数组,std::string,std::wstring,CString....转换
  4. 【学习笔记】月末操作-自动清账
  5. 使用Laravel框架发送邮件
  6. python xlwt模块生成excel文件并写入数据 xlrd读取数据
  7. 【MFC】MFC中调用系统软键盘的几种方法
  8. 使用Kubeadm创建k8s集群之节点部署(三十二)
  9. java 删除二维数组中的null_避免在Java中检查Null语句
  10. 阿里对mysql的优化_阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结...
  11. java mail 收发邮件
  12. Dijkstra算法 简易理解(原创)
  13. VRP基础,命令行基础,文件系统基础,系统管理(2017年12月13日 09:51:51)
  14. 小说网站源码+采集器+App端
  15. 蜂鸣器原理与驱动方式
  16. 使用Apache Tika实现内容分析
  17. 【食品加工技术】第四章 饮料生产技术 笔记
  18. “暴跌”微博难翻身:用户数持续大降,豪赌视频号没胜算
  19. centos7挂载nas存储_CentOS 7配置NAS(网络共享存储)
  20. 计算机游戏 英文作文,电脑游戏英语作文

热门文章

  1. 掩膜裁剪tif步骤_ENVI中掩膜掩膜操作及影像分类教程
  2. php清除页面别人挂的马
  3. JDBC - 宋红康 - 核心技术
  4. 编译原理笔记05-语法分析自底向上
  5. ZIP:ZipEntry
  6. 视频教程-【深入理解计算机网络】讲师解读计算机网络原理视频课程(中)-计算机网络
  7. 高雅复古立式钢琴音源 Native Instruments The Gentleman Kontakt
  8. 学习笔记4--惯性导航及总结
  9. 模拟电子电路技术基础 | 常用半导体器件
  10. C标准 C90~C18 官网PDF下载