[关闭]
@liter 2015-10-23T08:51:38.000000Z 字数 3508 阅读 3690

Android网络通信框架LiteHttp 第十四节:回调监听器详解

litehttp2.x版本系列教程


官网: http://litesuits.com

QQ群: 大群 47357508,二群 42960650

本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。

本系列文章目录总览: https://zybuluo.com/liter/note/186513


第十四节:LiteHttp之回调监听器详解

1. 开宗明义

本节讨论监听器 HttpListener ,将从以下几个方面了解它:

  • 回调时机
  • 延时触发
  • 安全回调
  • 回调线程指定
  • 全局监听器
  • 级联监听器

说起lite-http的监听器,下面三个方面是主要内容:

  1. 监听时机

    开始,成功,失败,取消,重试,上传进度,下载进度,结束

  2. 全局监听

    监听全部的请求,每一个都尽在掌握。

  3. 级联监听

    几乎可以无限级联,也就是可以设置一连串多个监听器。设想如既需要后台监听结果,又要前端监听进度,那级联监听就派上用场。

2. 回调时机

HttpListener 的回调时机有:

开始和结束作为开闭节点一定会被调用。
成功、失败、取消三个作为结果将有一个被调用。
下载进度通知仅在setReadingNotify为true时触发。
上传进度通知仅在setUploadingNotify为true时触发。

3. 延时触发

通过 setDelayMillis 方法设置回调触发时间的延迟。

这对于测试有很大帮助,如我要让请求耗时更长一些,好看下是否有异常。

再比如有时服务器响应很快,而你要看清楚加载动画是不是符合要求很难,这时加个3000毫秒的延迟触发,动画就看得很清楚了。

如果没有人工干预延迟,这些都是问题。

4. 安全回调

事情在不该发生的时间点上发生,会引起一些列异常。

网络请求也一样,比如请求比较耗时,页面都关掉销毁了,才拿到结果,显然不应该渲染界面了。

我建议继承 HttpListener 写一个自己的监听器,并复写 disableListener 方法在不合适的时机禁用回调,避免不必要的麻烦。

比如:

  1. class MyHttpListener<T> extends HttpListener<T> {
  2. private Activity activity;
  3. public MyHttpListener(Activity activity) {
  4. this.activity = activity;
  5. }
  6. @Override
  7. public boolean disableListener() {
  8. return activity == null || activity.isFinishing();
  9. }
  10. @Override
  11. public void onFailure(HttpException e, Response response) {
  12. new MyHttpExceptHandler(activity).handleException(e);
  13. }
  14. }

不仅在页面销毁之后禁用回调,而且失败时 统一采用自定义的异常处理器。它适用于Activity,Fragment里的监听器也一样的道理。

5. 回调线程指定

看一下监听器的构造函数:

  1. public HttpListener(boolean runOnUiThread) {
  2. setRunOnUiThread(runOnUiThread);
  3. }
  4. public HttpListener(boolean runOnUiThread, boolean readingNotify, boolean uploadingNotify) {
  5. this(runOnUiThread);
  6. this.readingNotify = readingNotify;
  7. this.uploadingNotify = uploadingNotify;
  8. }

顾名思义:

  • runOnUiThread: 所有回调是否在主线程
  • readingNotify: 是否开启下载进度通知
  • uploadingNotify: 是否开启上传进度通知

当然也可以通过 setRunOnUiThread 方法来设置,true为主线程回调,false为当前线程回调。

6. 全局监听器

定义一个普通监听器:

  1. /**
  2. * global http listener for all request.
  3. */
  4. GlobalHttpListener globalHttpListener = new GlobalHttpListener() {
  5. @Override
  6. public void onSuccess(Object data, Response<?> response) {
  7. HttpLog.i(TAG, "Global, request success ..." + data);
  8. }
  9. @Override
  10. public void onFailure(HttpException e, Response<?> response) {
  11. HttpLog.i(TAG, "Global, request failure ..." + e);
  12. }
  13. };

监听所有请求:

  1. liteHttp.getConfig().setGlobalHttpListener(globalHttpListener);

7. 级联监听器

定义一个监听器:

  1. HttpListener<Bitmap> secondaryListener = new HttpListener<Bitmap>(true, true, true) {
  2. @Override
  3. public void onSuccess(Bitmap bitmap, Response<Bitmap> response) {
  4. HttpLog.i(TAG, " second listener, request success ...");
  5. }
  6. @Override
  7. public void onFailure(HttpException e, Response<Bitmap> response) {
  8. HttpLog.i(TAG, " second listener, request failure ...");
  9. }
  10. };

定义新的监听器:

  1. HttpListener<Bitmap> firstHttpListener = new HttpListener<Bitmap>(false, false, false) {
  2. @Override
  3. public void onSuccess(Bitmap bitmap, Response<Bitmap> response) {
  4. HttpLog.i(TAG, "first Listener, request success ...");
  5. }
  6. @Override
  7. public void onFailure(HttpException e, Response<Bitmap> response) {
  8. HttpLog.i(TAG, "first Listener, request failure ...");
  9. }
  10. @Override
  11. public void onLoading(AbstractRequest<Bitmap> request, long total, long len) {
  12. HttpLog.i(TAG, "first Listener, request loading ...");
  13. }
  14. };

设置级联:

  1. // create a bitmap request.
  2. BitmapRequest bitmapRequest = new BitmapRequest(picUrl);
  3. // correct way to set first http listener
  4. bitmapRequest.setHttpListener(firstHttpListener);
  5. // correct way to set secondary (linked)listener
  6. firstHttpListener.setLinkedListener(secondaryListener);
  7. //load and show bitmap
  8. liteHttp.executeAsync(bitmapRequest);

firstHttpListener先被调用,secondaryListener后被调用。注意不能循环级联,比如:

  1. firstHttpListener.setLinkedListener(secondaryListener);
  2. secondaryListener.setLinkedListener(firstHttpListener);

这样就死循环了,框架会发现并抛出异常。

好的,这节比较长,到此结束,晚安~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注