android 缓存方案,Android 缓存方案探究&实践

fc15414daff1

缓存方案流程图

网上看了很多的WebView缓存的文章,做了个H5缓存的方案,提高H5体验,提升H5加载 速度。主要部分为缓存和文件差异对比。

缓存:SP+文件存储,SP 保存文件名和存储路径

文件差异对比:文件MD5对比,不同则需要删除更新,相同则可以直接使用,保证用户看到的是最新的页面

PS: 文件对比方案可以服务端给客户端返回缓存文件对应的MD5配置表,然后每次取缓存文件时对比MD5值。

fc15414daff1

工具类

实现WebViewClient shouldInterceptRequest 方法,此方法做具体逻辑操作,代码如下:

public class XWebViewClient extends WebViewClient {

@Override

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

return XWebInterceptor.shouldInterceptRequest(view, request);

}

@Override

public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

return XWebInterceptor.shouldInterceptRequest(view, url);

}

}

public class XWebInterceptor {

public static final String TAG = "====XWebInterceptor====";

private static Map interceptMap = new HashMap<>();

static {

interceptMap.put(".js", "application/javascript");

interceptMap.put(".html", "text/html");

interceptMap.put(".htm", "text/html");

interceptMap.put(".css", "text/css");

interceptMap.put(".png", "image/png");

interceptMap.put(".jpg", "image/jpeg");

interceptMap.put(".jpeg", "image/jpeg");

interceptMap.put(".gif", "image/gif");

interceptMap.put(".ico", "image/x-icon");

interceptMap.put(".mp3", "audio/mp3");

}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

public static WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

return shouldInterceptRequest(view.getContext(), request.getUrl());

}

public static WebResourceResponse shouldInterceptRequest(WebView view, String url) {

return shouldInterceptRequest(view.getContext(), Uri.parse(url));

}

private static WebResourceResponse shouldInterceptRequest(final Context context, Uri requestUri) {

final String remoteUrl = requestUri.toString();

Log.d(TAG, "拦截时间:" + System.currentTimeMillis() + "\t拦截地址:" + remoteUrl);

if (isInterceptor(remoteUrl)) {

Log.d(TAG, "符合拦截条件,开始拦截");

String filePath = SPUtil.getString(context, remoteUrl);

File localFile = null;

if (TextUtils.isEmpty(filePath)) {

localFile = download(context, remoteUrl);

}

if(localFile == null){

localFile = new File(filePath);

if (!localFile.exists()) {

localFile = download(context, remoteUrl);

}

}

try {

FileInputStream fis = new FileInputStream(localFile);

//本地文件MD5

String localFileMd5 = FileUtil.getFileMD5(fis);

//获取远端返回MD5

String remoteFileMd5 = SPUtil.getString(context, remoteUrl.substring(remoteUrl.lastIndexOf("/") + 1));

if (!localFileMd5.equals(remoteFileMd5)) {

//校验本地文件MD5,不一致则删除本地文件再次下载

localFile.delete();

localFile = download(context, remoteUrl);

}

return new WebResourceResponse(getMimeType(remoteUrl), "UTF-8", new FileInputStream(localFile));

} catch (FileNotFoundException e) {

e.printStackTrace();

Log.d(TAG, "存在缓存文件,发生异常");

} catch (NullPointerException e) {

e.printStackTrace();

}

}

return null;

}

@SuppressLint("CheckResult")

private static File download(final Context context, final String remoteUrl) {

Log.d(TAG, "无现有缓存可用,开始下载:" + remoteUrl);

File localFile = null;

OkHttpClient okHttpClient = new OkHttpClient();

Request request = new Request.Builder()

.url(remoteUrl)

.build();

try {

String path = context.getCacheDir().getPath() + File.separator + "h5Cache" + File.separator;

FileUtil.createFolder(path);

String name = remoteUrl.substring(remoteUrl.lastIndexOf("/") + 1);

Response response = okHttpClient.newCall(request).execute();

InputStream is = response.body().byteStream();

localFile = FileUtil.createFile(path + name, is);

SPUtil.putString(context, remoteUrl, path + name);

Log.d(TAG, "下载完成,缓存文件保存路径" + localFile.getPath());

} catch (IOException e) {

Log.d(TAG, "IO 异常,下载失败:" + remoteUrl + "\t" + e.getMessage());

} catch (Exception e) {

Log.d(TAG, "其他异常,下载失败:" + remoteUrl + "\t" + e.getMessage());

}

return localFile;

}

private static boolean isInterceptor(String remoteUrl) {

if (!remoteUrl.contains(".")) {

return false;

}

String suffixName = remoteUrl.substring(remoteUrl.lastIndexOf("."));

return interceptMap.containsKey(suffixName);

}

/**

* @see Http Content-type 对照表

*/

private static String getMimeType(String remoteUrl) {

if (TextUtils.isEmpty(remoteUrl) || !remoteUrl.contains(".")) {

return null;

}

String suffixName = remoteUrl.substring(remoteUrl.lastIndexOf("."));

if (interceptMap.containsKey(suffixName)) {

return interceptMap.get(suffixName);

}

return URLConnection.guessContentTypeFromName(remoteUrl);

}

}

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值