Android 中Volley二次封装并实现网络请求缓存

Android 中Volley二次封装并实现网络请求缓存

Android目前很多同学使用Volley请求网络数据,但是Volley没有对请求过得数据进行缓存,因此需要我们自己手动缓存。 一下就是我的一种思路,仅供参考

具体使用方法为:

HashMap<String,String> params = new HashMap<>();
params.put("id", "1");
params.put("user", "mcoy");
new NetWorkHelper(getActivity()).jacksonMethodRequest
("method_id", params, new TypeReference<ReturnTemple<FirstCategories>>(){}, handler, msgId);

NetWorkHelper---对Volley的封装,首先调用CacheManager.get(methodName, params);方法获取缓存中的数据,如果数据为null,

则继续发送网络请求。

/**
 * @version V1.0 网络请求帮助类
 * @author: mcoy
 */
public final class NetWorkHelper { 

  private NetWorkManager netWorkUtils; 

  public NetWorkHelper(Context context){
    netWorkUtils = new NetWorkManager(context);
  } 

  public static final String COMMON_ERROR_MSG = "连接超时,请稍后重试";
  public static final int COMMON_ERROR_CODE = 2; 

  /**
   * 使用Jackson请求的方法
   * @param methodName
   * @param params
   * @param handler
   * @param msgId
   */
  public void jacksonMethodRequest(final String methodName,final HashMap<String,String> params,TypeReference javaType, final Handler handler,final int msgId){ 

    ResponseListener listener =  new ResponseListener(){
      @Override
      public void onResponse(Object response, boolean isCache) {
        PrintLog.log(response.toString());
        if (isCache){
          CacheManager.put(methodName, params, response);
        }
        if (handler != null) {
          Message message = handler.obtainMessage();
          message.what = msgId;
          message.obj = response;
          handler.sendMessage(message);
        }
      }
    }; 

    Object respone = CacheManager.get(methodName, params);
    if(respone != null){
      listener.onResponse(respone,false);
      return;
    } 

    HashMap<String,String> allParams = Config.setSign(true);
    allParams.putAll(params);
    Response.ErrorListener errorListener = new Response.ErrorListener() {
      @Override
      public void onErrorResponse(VolleyError error) {
        error.printStackTrace();
        if (handler != null) {
          Message message = handler.obtainMessage();
          message.what = msgId;
          message.obj = COMMON_ERROR_MSG;
          handler.sendMessage(message);
        }
      }
    };
    netWorkUtils.jacksonRequest(getUrl(methodName), allParams,javaType, listener, errorListener);
  } 

  /**
   * Url直接请求
   * @param url
   * @param params
   * @param handler
   * @param msgId
   */
  public void urlRequest(String url,HashMap<String,String> params,JsonParser jsonParser,final Handler handler,final int msgId){ 

    request(url, true, params, jsonParser, handler, msgId);
  } 

  /**
   * 通过方法请求
   * @param methodName 方法名
   * @param params 请求参数
   * @param jsonParser Json解析器
   * @param handler 回调通知
   * @param msgId 通知的Id
   */
  public void methodRequest(String methodName, final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){
    request(getUrl(methodName),true,params,jsonParser,handler,msgId);
  } 

  /**
   * 通过方法请求
   * @param methodName 方法名
   * @param params 请求参数
   * @param jsonParser Json解析器
   * @param handler 回调通知
   * @param msgId 通知的Id
   */
  public void methodRequest(String methodName, boolean isLogin,final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){
    request(getUrl(methodName),isLogin,params,jsonParser,handler,msgId);
  } 

  private void request(final String url, boolean isLogin,final HashMap<String,String> params,final JsonParser jsonParser,final Handler handler,final int msgId){
    final HashMap<String,String> allParams = Config.setSign(isLogin);
    allParams.putAll(params);
    Response.Listener listener = new Response.Listener<String>() {
      @Override
      public void onResponse(String response) {
        /**
         * 有些请求默认是没有parser传过来的,出参只求String,譬如联合登录等
         * 所以加了一个else if
         */
        Object result;
        PrintLog.log(response);
        if (jsonParser != null ) {
          jsonParser.json2Obj(response);
          jsonParser.temple.description = jsonParser.temple.getResultDescription();
          result = jsonParser.temple;
        } else {
          ReturnTemple temple = new ReturnTemple();
          temple.issuccessful = false;
          temple.description = COMMON_ERROR_MSG;
          temple.result = -100;
          result = temple;
        }
        if (handler != null) {
          Message message = handler.obtainMessage();
          message.what = msgId;
          message.obj = result;
          handler.sendMessage(message);
        }
      }
    }; 

    Response.ErrorListener errorListener = new Response.ErrorListener() {
      @Override
      public void onErrorResponse(VolleyError error) {
        Object result;
        if (jsonParser != null) {
          ReturnTemple temple = new ReturnTemple();
          temple.issuccessful = false;
          temple.description = COMMON_ERROR_MSG;
          temple.result = COMMON_ERROR_CODE;
          result = temple;
        } else {
          result = COMMON_ERROR_MSG;
        }
        if (handler != null) {
          Message message = handler.obtainMessage();
          message.what = msgId;
          message.obj = result;
          handler.sendMessage(message);
        }
      }
    };
    netWorkUtils.request(url, allParams, listener, errorListener);
  } 

  /**
   * 根据访求名拼装请求的Url
   * @param methodName
   * @return
   */
  private String getUrl(String methodName){
    String url = Config.getUrl();
    if (!StringUtil.isNullOrEmpty(methodName)) {
      url = url + "?method=" + methodName;
    }
    return url;
  }
}

CacheManager---将针对某一method所请求的数据缓存到本地文件当中,主要是将CacheRule写到本地文件当中

/**
 * @version V1.0 <缓存管理>
 * @author: mcoy
 */
public final class CacheManager {
  /**
   * 一个方法对应的多个Key,比如分类都是同一个方法,但是请求会不一样,可能都要缓存
   */
  private static HashMap<String, ArrayList<String>> methodKeys;
  private static final String keyFileName = "keys.pro"; 

  /**
   * 读取缓存的Key
   */
  public static void readCacheKey() {
    methodKeys = (HashMap<String, ArrayList<String>>) readObject(keyFileName);
    if (methodKeys == null) {
      methodKeys = new HashMap<String, ArrayList<String>>();
    }
  } 

  /**
   * 保存缓存
   */
  public static void put(String method, HashMap<String, String> params, Object object) {
    long expireTime = CacheConfig.getExpireTime(method);
    if (expireTime <= 0 || methodKeys == null) {//有效时间小于0,则不需要缓存
      return;
    }
    String key = createKey(method, params);
    if (methodKeys.containsKey(method)) {
      ArrayList<String> keys = methodKeys.get(method);
      keys.add(key);
    } else {
      ArrayList<String> keys = new ArrayList<>();
      keys.add(key);
      methodKeys.put(method, keys);
    }
    writeObject(methodKeys, keyFileName);
    String fileName = key + ".pro";
    CacheRule cacheRule = new CacheRule(expireTime, object);
    LogModel.log(" put " + method + " " + key + " " + cacheRule);
    writeObject(cacheRule, fileName);
  } 

  public static Object get(String method, HashMap<String, String> params) {
    long expireTime = CacheConfig.getExpireTime(method);
    if (expireTime <= 0 || methodKeys == null || !methodKeys.containsKey(method)) {//有效时间小于0,则不需要缓存
      return null;
    }
    ArrayList<String> keys = methodKeys.get(method);
//    String saveKey = keys.get(method);
    String key = createKey(method, params);
    String fileName = key + ".pro";
//    LogModel.log("get"+method+" "+(saveKey.equals(key))+" path:"+fileName); 

    CacheRule cacheRule = null;
    try {
      if (keys.contains(key)) {
        cacheRule = (CacheRule) readObject(fileName);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    LogModel.log("get :" + method + " " + key + " " + cacheRule);
    if (cacheRule != null && cacheRule.isExpire()) {
      return cacheRule.getData();
    } else {
      return null;
    }
  } 

  public static void main(String[] args) {
    String method = "category.getCategory";
    HashMap<String, String> params = new HashMap<>();
    params.put("categoryId", "-3");
    System.out.println(createKey(method, params));
    System.out.println(CacheRule.getCurrentTime());
  } 

  /**
   * 生成Key
   *
   * @param method 请求的方法名
   * @param params 私有参数(除公共参数以外的参数)
   * @return
   */
  private static String createKey(String method, HashMap<String, String> params) {
    try {
      MessageDigest digest = MessageDigest.getInstance("md5");
      digest.digest(method.getBytes("UTF-8"));
      StringBuilder builder = new StringBuilder(method);
      if (params != null && params.size() > 0) {
        Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
        while (iterator.hasNext()) {
          Map.Entry<String, String> entry = iterator.next();
          builder.append(entry.getKey()).append("=").append(entry.getValue());
        }
      }
      byte[] tempArray = digest.digest(builder.toString().getBytes("UTF-8"));
      StringBuffer keys = new StringBuffer();
      for (byte b : tempArray) {
        // 与运算
        int number = b & 0xff;// 加盐
        String str = Integer.toHexString(number);
        // System.out.println(str);
        if (str.length() == 1) {
          keys.append("0");
        }
        keys.append(str);
      }
      return keys.toString().toUpperCase();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return method.toUpperCase();
  } 

  /**
   * 将对象写到文件中
   *
   * @param object
   * @param fileName
   */
  private static void writeObject(Object object, String fileName) {
    try {
      ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File(CacheConfig.getCachePath() + fileName)));
      oo.writeObject(object);
      oo.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  } 

  /**
   * 读取对象
   *
   * @param fileName
   * @return
   */
  private static Object readObject(String fileName) {
    Object result = null;
    try {
      File file = new File(CacheConfig.getCachePath() + fileName);
      if (file.exists()) {
        ObjectInputStream oi = new ObjectInputStream(new FileInputStream(file));
        result = oi.readObject();
        oi.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }
}

CacheConfig---初始化哪些方法需要做缓存处理,以及缓存的有效时间

/**
 * @version V1.0 <设置哪些类数据需要缓存> 

 * @author: mcoy
 */
public final class CacheConfig {
  /**方法对应的缓存有效时间,时间是毫秒*/
  private static HashMap<String,Long> methodExpireTimes = new HashMap<String, Long>();
  private static String cachePath = null; 

  static {
    methodExpireTimes.put(ConstMethod.GET_CATEGORY_LIST,30 * 60 * 1000L);
    methodExpireTimes.put(ConstMethod.GET_NEW_CATEGORY_LIST,30 * 60 * 1000L);
  } 

  /**
   * 初始化缓存路径
   * @param context
   */
  public static void init(Context context){
    cachePath = context.getFilesDir().getPath()+ File.separator+"cache"+File.separator;
    File file = new File(cachePath);
    if(!file.exists()){
      file.mkdirs();
    }
    CacheManager.readCacheKey();
  } 

  /**缓存路径*/
  public static String getCachePath() {
    return cachePath;
  } 

  /**
   * 获取有方法对应的有效时间,如果方法没有添加缓存或者缓存时间小于0,则不添加缓存
   * @param method
   * @return
   */
  public static long getExpireTime(String method){
    if(methodExpireTimes.containsKey(method)){
      return methodExpireTimes.get(method);
    }else {
      return -1;
    }
  }
}

CacheRule---主要有两个参数,expireTime需要缓存的时间, data需要缓存的数据

public class CacheRule implements Serializable{
  /** 有效时间 */
  public long expireTime;
  /** 缓存时间*/
  public long cacheTime;
  /** 缓存数据 */
  private Object data; 

  public CacheRule(long expireTime,Object data){
    cacheTime = getCurrentTime();
    this.expireTime = expireTime;
    this.data = data;
  } 

  public Object getData() {
    return data;
  } 

  public void setData(Object data) {
    this.data = data;
  } 

  @Override
  public int hashCode() {
    return BeanTools.createHashcode(expireTime, cacheTime, data);
  } 

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("expireTime:").append(expireTime).append(" cacheTime:").append(cacheTime)
        .append(" curTime:").append(getCurrentTime())
        .append(" isExpire:").append(isExpire()).append(" data:").append(data==null?"null":data.toString());
    return builder.toString();
  } 

  /**
   * 数据是否有效
   * @return
   */
  public boolean isExpire(){
    long curTime = getCurrentTime();
    return curTime>(expireTime+cacheTime)?false:true;
  } 

  /**
   * 获取当前时间
   * @return
   */
  public static long getCurrentTime(){
//    if (Build.VERSION_CODES.JELLY_BEAN_MR1 <= Build.VERSION.SDK_INT) {
//      return SystemClock.elapsedRealtimeNanos();
//    } else {
      return System.currentTimeMillis();
//    }
  }
}

NetWorkManager---往RequestQueue中添加JacksonRequest请求,然后Volley会去请求数据

/**
 * 网络请求的工具类
 */
public final class NetWorkManager { 

  private RequestQueue requestQueue ; 

  public NetWorkManager(Context context){
    requestQueue = Volley.newRequestQueue(context);
  } 

  /**
   * 使用Jackson解析请求的方法
   * @param url
   * @param params
   * @param javaType 成功时返回的Java类型
   * @param listener
   * @param errorListener
   */
  public void jacksonRequest(final String url,final HashMap<String,String> params,TypeReference javaType, ResponseListener listener, Response.ErrorListener errorListener){
    JacksonRequest jacksonRequest = new JacksonRequest(url,javaType,params,listener,errorListener);
    requestQueue.add(jacksonRequest);
  } 

  /**
   * 普通的网络请求,返回的Json
   * @param url
   * @param params
   * @param listener
   * @param errorListener
   */
  public void request(final String url,final HashMap<String,String> params,Response.Listener listener,Response.ErrorListener errorListener){ 

    StringRequest stringRequest = new StringRequest(Request.Method.POST,url,listener,errorListener){
      @Override
      protected Map<String, String> getParams() throws AuthFailureError {
        if (PrintLog.DEBUG) {
          Iterator<Map.Entry<String,String>> iterator = params.entrySet().iterator();
          StringBuilder builder = new StringBuilder(url+" ");
          while (iterator.hasNext()){
            Map.Entry<String,String> entry = iterator.next();
            builder.append(entry.getKey()+":"+entry.getValue()).append("; ");
          }
          PrintLog.log(builder.toString());
        }
        return params;
      }
    };
    requestQueue.add(stringRequest);
  } 

}

JacksonRequest---继承Request,重写deliverResponse方法,并调用ResponseListener的onResponse方法,并通过CacheManager.put(methodName, params, response);将获取的response缓存到CacheManager中。这一步很重要,调用我们自己的listener,而不是Volley提供给我们的Response.Listener

/**
 * Created by mcoy
 */
public class JacksonRequest extends Request {
  private final HashMap<String,String> params;
  private final ResponseListener listener;
  private final ObjectMapper mapper;
  private final TypeReference javaType; 

  public JacksonRequest(String url,TypeReference javaType,HashMap<String,String> params,ResponseListener listener,Response.ErrorListener errorListener){
    super(Method.POST,url,errorListener);
    mapper = new ObjectMapper();
    mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES,true);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    this.params = params;
    this.listener = listener;
    this.javaType = javaType;
  } 

  @Override
  protected Map<String, String> getParams() throws AuthFailureError {
    return params;
  } 

  @Override
  protected Response parseNetworkResponse(NetworkResponse response) {
    String json;
    try {
      json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
      PrintLog.log("返回的json:" + json);
      return Response.success(mapper.readValue(json,javaType), HttpHeaderParser.parseCacheHeaders(response));
    }catch (UnsupportedEncodingException e){
      json = new String(response.data);
      PrintLog.log("json:"+json);
      try {
        return Response.success(mapper.readValue(json,javaType),HttpHeaderParser.parseCacheHeaders(response));
      } catch (IOException e1) {
        return Response.error(new ParseError(e));
      }
    } catch (JsonParseException e) {
      PrintLog.log(e.toString());
      return Response.error(new ParseError(e));
    } catch (JsonMappingException e) {PrintLog.log(e.toString());
      return Response.error(new ParseError(e));
    } catch (IOException e) {PrintLog.log(e.toString());
      return Response.error(new ParseError(e));
    }
  } 

  @Override
  protected void deliverResponse(Object response) {
    listener.onResponse(response,true);
  } 

}

ResponseListener---自定义的一个listener接口, 在发送请求时,需要将其实现。其中才参数中比Volley的提供的listener过了一个isCache的Boolean值,根据此值来决定是否要缓存。

/**
 * @version V1.0 <描述当前版本功能>
 * @author: mcoy
 */
public interface ResponseListener<T> {
  public void onResponse(T response, boolean isCache);
}

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android Volley框架使用方法详解

    本文主要从两个方面对Android Volley框架的使用方法进行讲解,具体内容如下 一.网络请求 1.get方式请求数据 // 1 创建一个请求队列 RequestQueue requestQueue = Volley.newRequestQueue(VolleyActivity.this); // 2 创建一个请求 String url = "http://api.m.mtime.cn/PageSubArea/TrailerList.api"; StringRequest stri

  • Android中Volley框架进行请求网络数据的使用

    问题的阐述:Android SDK中的HttpClient和HttpUrlConnection两种请求方式用来处理网络的复杂的操作,但当应用比较复杂的时候需要我们编写大量的代码处理很多东西:图像缓存,请求的调度等等: 解决:Volley就是为解决这些而生,它与2013年Google I/O大会上被提出:使得Android应用网络操作更方便更快捷:抽象了底层Http Client等实现的细节,让开发者更专注与产生RESTful Request.另外,Volley在不同的线程上异步执行所有请求而避免

  • Android Volley框架全面解析

     Volley简介 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行HTTP通信,HttpURLConnection和HttpClient,几乎在任何项目的代码中我们都能看到这两个类的身影,使用率非常高. 不过HttpURLConnection和HttpClient的用法还是稍微有些复杂的,如果不进行适当封装的话,很容易就会写出不少重复代码.于是乎,一些Android网络

  • Android 开发中Volley详解及实例

    Android 开发中Volley详解及实例 最近在做项目的时候,各种get和post.简直要疯了,我这种啥都不了解的,不知道咋办了,然后百度看了下,可以用volley进行网络请求与获取,下面就介绍下volley的用法. volley有三种方式:JsonObjectRequest,JsonArrayRequest,StringRequest.其实都是差不多了,举一反三就ok了,这里我就讲下JsonObjectRequest. 方法如下: JsonObjectRequest jsonObjectR

  • 深入解读Android的Volley库的功能结构

    Volley 是一个 HTTP 库,它能够帮助 Android app 更方便地执行网络操作,最重要的是,它更快速高效.我们可以通过开源的 AOSP 仓库获取到 Volley . Volley 有如下的优点: 自动调度网络请求. 高并发网络连接. 通过标准的 HTTP cache coherence(高速缓存一致性)缓存磁盘和内存透明的响应. 支持指定请求的优先级. 撤销请求 API.我们可以取消单个请求,或者指定取消请求队列中的一个区域. 框架容易被定制,例如,定制重试或者回退功能. 强大的指

  • Android 网络请求框架Volley实例详解

    Android 网络请求框架Volley实例详解 首先上效果图 Logcat日志信息on Reponse Volley特别适合数据量不大但是通信频繁的场景,像文件上传下载不适合! 首先第一步 用到的RequetQueue RequestQueue.Java RequestQueue请求队列首先得先说一下,ReuqestQueue是如何对请求进行管理的...RequestQueue是对所有的请求进行保存...然后通过自身的start()方法开启一个CacheDispatcher线程用于缓存调度,开

  • Android的HTTP类库Volley入门学习教程

    1. 什么是Volley 我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进行HTTP通信,HttpURLConnection和HttpClient,几乎在任何项目的代码中我们都能看到这两个类的身影,使用率非常高. 不过HttpURLConnection和HttpClient的用法还是稍微有些复杂的,如果不进行适当封装的话,很容易就会写出不少重复代码.于是乎,一些Androi

  • Android 使用volley过程中遇到的问题解决办法

    Android 使用volley过程中遇到的问题解决办法 本文主要介绍使用 volley 过程中遇到的问题,错误提示: com.android.volley.NoConnectionError: java.io.InterruptedIOException",内容加载失败,问题出在重复调用 queue.start() 方法. 错误提示:com.android.volley.NoConnectionError: java.io.InterruptedIOException",然后就内容加

  • Android 中Volley二次封装并实现网络请求缓存

    Android 中Volley二次封装并实现网络请求缓存 Android目前很多同学使用Volley请求网络数据,但是Volley没有对请求过得数据进行缓存,因此需要我们自己手动缓存. 一下就是我的一种思路,仅供参考 具体使用方法为: HashMap<String,String> params = new HashMap<>(); params.put("id", "1"); params.put("user", &quo

  • Android中的二维码生成与扫描功能

    0. 前言 今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,为什么要讲二维码,因为二维码太普遍了,随便一个Android APP都会有二维码扫描.本篇旨在帮助有需求的同学快速完成二维码生成和扫描的功能. 1.    Zxing的使用 从github上下载项目后,可以看到整体代码结构如下: 我们只需将Zxing包下的所有代码copy一份到我们的项目中去,除了这些还需要zxing的jar包,最后相应的资源文件,包括values文件下的ids文件.raw文件中的资源文件(可以替换).

  • Android中Volley框架下保持会话方法

    公司经理把我拉出来,死马当活马医,做一个安卓app,作为刚毕业几个月且只是培训了几个月的小白来说,这无疑是一个非常大的挑战,当然最大的挑战不是这个,最大的挑战时两个周做出来.这是最蛋疼的,说实话,对于有两三年的开发经验的人来说,两个周开发一个项目很简单,说不定还有很多时间用来干别的. 于是一上来就把自己给难住了,登陆还是很好做的,只要验证返回的信息就可以跳转,但是在接下来后面的数据接口连接的时候各种报错,整了两天,查了很多信息,还接受了公司老人的嘲讽和谩骂终于做出来了. 这个是基于session

  • 项目中Axios二次封装实例Demo

    1.为什么做封装? 方便代码整体调用.对请求做公共处理.个性化定制 2.别人已经封装了很多,为什么不直接修改使用? 封装思路不适合自身项目 封装后调用不方便 3.个人封装demo 代码结构[基于vue] 基本思路 将所有的请求接口地址按照文件分模块存储,比如 request/module/user 用户信息相关模块[服务] 2.封装方法.类.给所有请求绑定常用的请求方法,和对请求url上的路径参数做处理 generateServer.js import server from "../util/

  • 微信小程序中网络请求缓存的解决方法

    需求 提交小程序审核时,有一个体验测评,产品让我们根据小程序的体验测评报告去优化小程序. 其中有一项是网络请求的优化,给我们出了很大的难题. 文档中是这样解释的:3分钟以内同一个url请求不出现两次回包大于128KB且一模一样的内容 看到这个问题的时候,首先想到的是在响应头上加上cache-control,经过测试发现小程序并不支持网路请求缓存.搜索发现官方明确答复,小程序不支持网络请求缓存:wx.request不支持http缓存 既然官方不支持网络请求缓存,那只能自己想办法解决这个问题了. 先

  • Android中volley封装实践记录(二)

    前言 关于android的volley封装之前写过一篇文章,见链接(https://www.jb51.net/article/155875.htm).这篇文章主要是换种方式进行封装,具体步骤如下所示. 步骤如下 1.创建Request,并设置相应的参数: public class CommonJsonObjectRequest extends JsonObjectRequest { private String TAG = this.getClass().getSimpleName(); /*

  • Android中对RecyclerView Adapter封装解析

    前言 关于adapter的封装,网上有很多开源库,开发的时候可以直接拿来用,省了很多事. 最近闲来无事,想着自己动手封装一个adapter. 问题 1.通常我们封装的时候,可以简化到这一步: BaseRecyclerViewAdapter adapter = new BaseRecyclerViewAdapter() { private static final int TYPE_FIR = 1; private static final int TYPE_SEC = 2; private st

  • Android中okhttp3.4.1+retrofit2.1.0实现离线缓存

    关于Retrofit+OkHttp的强大这里就不多说了,还没了解的同学可以自行去百度.这篇文章主要讲如何利用Retrofit+OkHttp来实现一个较为简单的缓存策略: 即有网环境下我们请求数据时,如果没有缓存或者缓存过期了,就去服务器拿数据,并且将新缓存保存下来,如果有缓存而且没有过期,则直接使用缓存.无网环境下我们请求数据时,缓存没过期则直接使用缓存,缓存过期了则无法使用,需要重新联网获取服务器数据. 缓存处理还是很有必要的,它有效的减少服务器负荷,降低延迟提升用户体验,同时也方便用户即使在

  • Android中volley封装实践记录

    前言 在项目中一般使用使用volley方式如下,用起来给人一种很乱的感觉,于是一种盘它的想法油然而生. public void get() { String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=......"; StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<

随机推荐