需求:高效地向服务器请求数据并解析。

涉及的主要工具类:
HttpManager 大哥类。最重要的类,封装了GET和POST方法。所有的参数都要经过这个类发送给服务器。
HttpRequestListener 监听接口。封装了请求状态和毁掉方法
HttpRequestVo 信使类。封装了http请求的参数。
JSONParser 解析器。

HttpRequestVo 封装了Http请求中携带的参数。这个类类似于一个通信使者,在主调用函数中赋值,传递给HttpManager,让后者将它进一步加工成http请求。

public class HttpRequestVo {//请求地址public String requestUrl;//上下文public Context context;//客户端的本地请求参数public HashMap<String, String> requestDataMap;//JSON请求参数public JSONObject requestJson;//JSON解析器public JSONParser parser;
}

HttpRequestListener是一个接口,它里面封装了几个Request的返回状态,还有一个很重要的回调方法action,用于返回网络请求的结果状态,以及解析好的数据Object(一般为HashMap)。

public interface HttpRequestListener {public static final int BASE_EVENT = 0x100;//没有网络提示public static final int EVENT_NO_NETWORK = BASE_EVENT + 1;//网络异常public static final int EVENT_NETWORK_ERROR = BASE_EVENT + 2;//获取网络数据失败public static final int EVENT_GET_DATA_ERROR = BASE_EVENT + 3;//获取网络数据成功public static final int EVENT_GET_DATA_SUCCESS = BASE_EVENT + 4;/*** 实现方法** @param actionCode 事件代码* @param object 解析好并返回给调用者的最终数据*/public abstract void action(int actionCode, Object object);}

JSONParser的代码如下,它的作用将返回的网络数据由JSONObject格式解析为Bean。这里用到Gson来解析数据,这样的好处是:只用写一份代码,就可以解析任何类型的JSON数据,比如:得到news就解析成NewsBean,得到user就解析成UserBean。而Parser解析器只有一份,极大提高了代码的复用性。

public HashMap<String, Object> parseJSON(String paramString) throws JSONException {HashMap<String, Object> map = new HashMap<String, Object>();JSONObject jsonObject = new JSONObject(paramString);String result = jsonObject.getString("result");Gson gson = new Gson();map.put("datamap", gson.fromJson(result, cls));return map;

JavaBean的格式如下,存放的是一个列表,其中的元素是一个一个的Model。使用Gson,可以轻易地将返回数据中对应的字段解析为Bean中的成员。要注意:返回数据中的字段名应该与Bean中的变量名完全一致,否则无法解析成功。

public class NewsListEntity {public ArrayList<NewsModel> newsList;public static class NewsModel {public int news_id;             public int news_type;          public String news_title;   public String news_sub;        public String news_content;   public String news_imgurl; public int istop;public String news_time;                   }
}

———主调用函数的使用———
代码如下。展示了主要流程:1.封装请求参数 2. 调用请求函数获取回调数据

protected void getNewsData(int type) {HttpRequestVo vo = new HttpRequestVo();vo.requestUrl = ConstantValues.GET_NEWS_LIST;vo.context = mContext;HashMap<String, String> map = new HashMap<String, String>();map.put("istop", "0");map.put("type", type + "");vo.requestDataMap = map;JSONObject requestJson = new JSONObject();  //目前暂时没用vo.parser = new JSONParser(NewsListEntity.class);vo.requestJson = requestJson;getDataFromServer(HttpManager.GET_METHOD, vo, new DataCallback<HashMap<String, Object>>() {@Overridepublic void onStart() {}@Overridepublic void onFailed() {}/*** 处理返回的news列表数据* @param paramObject*/@Overridepublic void processData(HashMap<String, Object> paramObject) {NewsListEntity newsEntity = (NewsListEntity) paramObject.get("datamap");ArrayList<NewsListEntity.NewsModel> newsList = newsEntity.newsList;mList.addAll(newsList);if (mListView.getAdapter() == null) {mAdapter = new NewsItemAdapter(getContext(), mList);mListView.setAdapter(mAdapter);} else {mAdapter.notifyDataSetChanged();}}@Overridepublic void onFinish() {}});}

下面这个就是回调接口。调用方(一般为Activity或Fragment)使用某个请求函数来向服务器请求数据时,要把该接口作为传入参数。

public abstract interface DataCallback<T> {public abstract void onStart();public abstract void onFailed();/*** 处理服务器返回的数据** @param paramObject 服务器返回的数据实体*/public abstract void processData(T paramObject);public abstract void onFinish();}

下面的代码展示将回调接口应用在主调用函数中。getDataFromServer这个主调用函数有三个参数,第一个你可以选择GET或POST,第二个是你自己定义的HttpRequestVo请求体,第三个就是上面提到的回调函数,在主调用函数中实现它里面的方法,对返回并解析好的数据进行使用。

/*** 从服务器上获取数据,并回调处理** @param requestType* @param requestVo*/protected void getDataFromServer(int requestType, HttpRequestVo requestVo, DataCallback callback) {final BaseHandler handler = new BaseHandler(mContext, callback);httpManager = new HttpManager(mContext, new HttpRequestListener() {@Overridepublic void action(int actionCode, Object object) {Message msg = Message.obtain();switch (actionCode) {case HttpRequestListener.EVENT_NO_NETWORK:msg.what = HttpRequestListener.EVENT_NO_NETWORK;break;case HttpRequestListener.EVENT_NETWORK_ERROR:msg.what = HttpRequestListener.EVENT_NETWORK_ERROR;break;case HttpRequestListener.EVENT_GET_DATA_ERROR:msg.what = HttpRequestListener.EVENT_GET_DATA_ERROR;msg.obj = null;break;case HttpRequestListener.EVENT_GET_DATA_SUCCESS:msg.obj = object;msg.what = HttpRequestListener.EVENT_GET_DATA_SUCCESS;break;default:break;}handler.sendMessage(msg);}}, requestVo);callback.onStart();if (requestType == HttpManager.GET_METHOD) {/****/httpManager.sendGetRequest();} else if (requestType == HttpManager.POST_METHOD) {/****/httpManager.sendPostRequest();}}

下面以GET方法为例,看一下我们是如何发送Http请求的。前面的部分是遍历HttpRequestVo中的参数map,进行url的字符串拼接。拼接完成后,这里我们使用Volley来发送GET请求,这样可以避免书写繁琐的HttpUrlConnection、输入输出流语句,并且不需要另开一个线程,因为多线程代码已经被封装。如果请求成功,在回调函数的onsuccess方法中,需要做两件事:使用parser将请求到的JSONObject解析为Java对象;HttpRequestListener调用action回调方法,将解析结果传回给主调用函数getDataFromServer。

public void sendGetRequest() {requestStatus = 1;String urlStr = "";try {StringBuffer buffer = new StringBuffer();buffer.append(requestVo.requestUrl);if (requestVo.requestDataMap != null) {if (!buffer.toString().contains("?")) {buffer.append("?");} else {buffer.append("&");}HashMap<String, String> map = requestVo.requestDataMap;int i = 1;int size = map.size();for (Map.Entry<String, String> entry : map.entrySet()) {if (i == size) {if (TextUtils.isEmpty(entry.getValue())) {buffer.append(entry.getKey() + "=");} else {buffer.append(entry.getKey() + "=" + requestEncodeStr(entry.getValue()));}} else {if (TextUtils.isEmpty(entry.getValue())) {buffer.append(entry.getKey() + "=" + "&");} else {buffer.append(entry.getKey() + "=" + requestEncodeStr(entry.getValue()) + "&");}}i++;}}urlStr = buffer.toString();VolleyRequest.RequestGet(context, urlStr, "volleyGet",new VolleyInterface(context, VolleyInterface.mListener, VolleyInterface.mErrorListener) {@Overridepublic void onMySuccess(JSONObject result) {if (result != null) {try {if (requestVo.parser != null) {HashMap<String, Object> map = requestVo.parser.parseJSON(result.toString());listener.action(HttpRequestListener.EVENT_GET_DATA_SUCCESS, map);} else {listener.action(HttpRequestListener.EVENT_GET_DATA_SUCCESS, result);}} catch (JSONException e) {e.printStackTrace();}}}@Overridepublic void onMyError(VolleyError error) {listener.action(HttpRequestListener.EVENT_NETWORK_ERROR, null);Log.i("TAG", error.toString());}});} catch (UnsupportedEncodingException e) {e.printStackTrace();}}

至此,我们已经获取到了封装好的JavaBean,剩下要做的就是把数据展现在UI上了。

Android网络请求中的回调相关推荐

  1. android中网络请求中页面关闭了会怎么样

    这是我在面试的时候,别人问的,其实 ,在实际开发中,并没有怎么遇到: 如果activity中开启了一个网络请求,正在请求中的时候,activity关闭了,那网络请求会怎么样? 因为之前没有遇到过这个问 ...

  2. Android -- 网络请求

    一. HttpURLConnection 二. HttpClient 三.Volley 四.OkHttp 五. Retrofit ----------------------------------- ...

  3. Android网络请求框架之Retrofit(二)

    前面一篇文章介绍了Retrofit的基本用法,没有看过的童鞋可以移步:Android网络请求框架之Retrofit(一),现在我们来继续介绍Retrofit配合RxJava.RxAndroid的用法. ...

  4. JSON在Android网络交互中的使用方法

    在Android网络交互中使用到JSON传输接收数据. JSONObject为键值对形式的数据,内部使用LinkedHashMap实现.键的类型固定为String,值可取的类型在JSONObject, ...

  5. okhttp的应用详解与源码解析--android网络请求框架发展史

    乘5G之势,借物联网之风,Android未来亦可期,Android优势在于开放,手机.平板.车载设备.智能家居等都是Android的舞台,Google不倒,Android不灭,本专栏的同步视频教程已经 ...

  6. android网络请求回调管理,Android HTTP网络请求的异步实现

    前言 大家都知道网络操作的响应时间是不定的,所有的网络操作都应该放在一个异步操作中处理,而且为了模块解耦,我们希望网络操作由专门的类来处理.所有网络数据发送,数据接收都有某几个类来实现,外部其它模块只 ...

  7. android网络请求回调管理,Android网络请求回调没正常走 处理方案

    处理类 import android.os.Handler; import android.os.Looper; import android.os.Message; /** * * 考虑可能回调没正 ...

  8. Android 网络请求详解

    我们知道大多数的 Android 应用程序都是通过和服务器进行交互来获取数据的.如果使用 HTTP 协议来发送和接收网络数据,就免不了使用 HttpURLConnection 和 HttpClient ...

  9. 防止网络请求(或其他回调)引用,从而造成内存泄漏

    本文的解决方案用来解决类似如:Activity请求网络,而回调传的是自身,造成Activity执行finish()后并没有被销毁,而是被网络请求持有.和其相类似的问题 正文 1.网络请求使用Activ ...

最新文章

  1. 贪心  POJ - 3617 ​​​​​​​Best Cow Line
  2. 中国 AI 出海,大华等企业助力联合国制定面部识别标准
  3. apk修改strings.xml后重新打包出错
  4. 【转载】ABAP中数据和对象的动态创建和调用
  5. 学Java技术,这些问题要避免!
  6. 从Weex到Web,性能逆势如何破局?
  7. 百一测评java基础答案_百一测评——《Web应用开发》选择题(含参考答案)—JavaEE基础...
  8. having vs where
  9. ubuntu wps缺少字体_WPS各版本
  10. mysql性能优化配置总结
  11. python进行接口请求,第一个接口返回的数据作为第二个参数的入参
  12. linux 用命令安装软件,Linux安装软件的三种常用命令
  13. CAD转JPG如何才能清晰?来看这两个方法
  14. 如何从当前文件夹直接打开cmd快捷键
  15. 京东和淘宝近十年搜索热度对比,发现顶尖者的PK规律
  16. 中药图片拍照识别系统全套开源
  17. FFMPEG使用 frei0r 给视频添加马赛克效果
  18. Android混淆心得
  19. SWT的MessageBox对话框
  20. XSS挑战之旅---游戏通关攻略

热门文章

  1. cx_freeze打包python3.6成exe/msi应用
  2. 无限镜面灯板制作教程
  3. ios微信web登录,QQweb登录中遇到的坑
  4. 【算法设计zxd】第一章 算法基础 4.设计工具【三角矩阵,】
  5. Upload-labs通关总结
  6. 雷达距离分辨率和速度分辨率计算
  7. 无人机倾斜摄影三维全景电子沙盘开发教程第5课
  8. 什么是 WEEE 标签?
  9. 【Azure】微软 Azure 基础解析(五)核心体系结构之管理组、订阅、资源和资源组以及层次关系
  10. hoRTC网络视频加密电话原理测试版使用说明