继文章‘’ 自己动手写一个轻量级的Android网络请求框架‘’后续------增加缓存功能

时间:2021-07-06 20:26:15

原文地址:LaterEqualsNever,自己动手写一个轻量级的Android网络请求框架

看了原作者写的文章,感觉受益匪浅,可以看出作者有很强的能力和功底。而我就是个渣渣了,但是又想自己也做点事情,因此在原文的基础上增加了缓存和进度回调的功能,让我们的框架更强大一点。

OK。看一下今天我们做个什么事情呢?

诺,其实很简单,增加了一个类,并修改了HttpRequest中的一部分代码。

继文章‘’ 自己动手写一个轻量级的Android网络请求框架‘’后续------增加缓存功能
在原来9个类的基础上只增加了一个CacheManager类,用来做我们的缓存管理类。
那么我们怎么用呢?
建一个Application类,进行缓存地址的初始化:

    CacheManager.getInstance.initCacheDir(getApplicationContext,"dir");
若第二个参数指定,则缓存的文件夹为指定名称,默认APP名称。

在HttpRequest的sendHttpGetToServer方法中,

CacheManager.getInstance().putFileCache(url,result,urlInfo.getExpires());//存入缓存,第一个参数url为带参请求体的url,第二个为缓存的字符串,第三个参数为XML中指定的缓存时间
result=CacheManager.getInstance().getFileCache(url,urlInfo.getExpires());//取出缓存内容

下来看一下我们CacheManager这个类的内容:

putFileCache() /**
* 缓存SD卡
* @param url,缓存url
* @param result,缓存内容
* @param expires,缓存时间,过期失效
*/


getFileCache() /**
* 获取缓存内容
*
* @param url
*/


clearCache() /**
* 删除对应缓存文件
* @param url,缓存url
*/

先看第一个方法putFileCache()是怎么实现的,我们的缓存是怎么做的

 public void putFileCache(String url,String result,long expires){
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
curDate = new Date(System.currentTimeMillis());
String data=df.format(curDate);
writeStr2SDCard(url,data+result);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 命名缓存目录并写入缓存,因为文件夹命名不能含有? / \ 等字符,所以以参数体作为文件命名的唯一区分
*
* @param url,缓存url
* @param result,缓存内容
*/

private void writeStr2SDCard(String url,String str) throws Exception{
FileOutputStream fos = new FileOutputStream(DIR+"/"+url.split("?")[1]);
fos.write(str.getBytes());
}

我这儿给每个新的缓存内容都新建一个文件夹,以url+参数的形式区分文件夹,开始缓存的时间作为缓存内容的开头

下面再看方法getFileCache()是怎么实现的

public String getFileCache(String url,long Expires){
if(Expires>0){
if(DIR==null||"".equals(DIR)){
return "";
}else{
Date endDate = new Date(System.currentTimeMillis());
try {
//获取指定文件对应的输入流
FileInputStream fis = new FileInputStream(DIR+"/"+url.split("?")[1]);
//将指定输入流包装成BufferReader
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
StringBuilder sb = new StringBuilder("");
String line = null;
//循环读取文件内容
while((line = br.readLine()) != null){
sb.append(line);
}
br.close();
try{
String priveTime=sb.substring(0, 19);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=null;
date= df.parse(priveTime);
if (date == null) {
return "";
} else {
long diff = endDate.getTime() - date.getTime();
//时间间隔,并且是ms级别的。
if(Expires>=diff){
return sb.toString();
}else{
clearCache(DIR+"/"+url.split("?")[1]);
return "";
}
}
}catch(Exception exception){
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return "";
}

首先拿到获取缓存的时间戳,然后如果存在url路径,则读取文件内容。
截取文件内容的前19位为当时进行缓存而保存的时间戳,两个时间戳进行减法,如果这个时间大于XML中设置的缓存时间,证明是过期缓存,则返回空重新进行网络请求,并清空此缓存。

再看一下clearCache()方法

   private void clearCache(String url) {
// TODO Auto-generated method stub
//常规写法,删除文件下的内容
File dirFile = new File(url);
if(! dirFile.exists()){
return;
}
if (dirFile.isDirectory()) {
String[] children = dirFile.list();
for (int i = 0; i < children.length; i++) {
new File(dirFile, children[i]).delete();
}
}
dirFile.delete();
}

大概思路就是这样子,算是对原文的功能扩展,写的不是很好,望多指正。