最近接到個奇葩需求店枣,緩存webview速警,我想著webview不是自帶緩存么,奈何手上這個設備由于網絡等各種限制問題艰争,導致webview不能直接加載H5中的資源坏瞄。也就是說原生緩存機制啥的用不了。
思路:
1.H5本身是html文件甩卓,可以想辦法保存在本地鸠匀。
2.H5內的圖片可以通過Glide來處理。設置WebViewClient逾柿,通過shouldInterceptRequest 攔截所有的資源請求缀棍,將圖片交給Glide。
開搞: 這里有個問題H5本身怎么保存机错,估計要寫很多代碼吧爬范,對于我這個懶人來說太麻煩,html本身就是文件弱匪,能不能用glide來處理尼青瀑。
查資料發(fā)現(xiàn)Glide Decode:
142245.png
里面有File,那么是不是完全可以把h5一個鏈接當作file使用glide加載了萧诫。上代碼
1.先處理Glide加載圖片部分,新建一個專門處理各種資源的工具類
public class GlideUtil {
public static byte[] syncLoad(String url, String type) {
GlideUrl glideUrl = buildUrl(url);
byte[] bt = null;
switch (type) {
case "gif":
FutureTarget<byte[]> targetGif = Glide.with(App.instance)
.as(byte[].class)
.load(glideUrl)
.decode(GifDrawable.class).submit();
try {
bt = targetGif.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
case "img":
FutureTarget<Bitmap> targetImg = Glide.with(App.instance)
.asBitmap().load(glideUrl).submit();
try {
Bitmap bitmap = targetImg.get();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
bt = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
break;
case "html":
FutureTarget<File> targetHtml = Glide.with(App.instance)
.asFile()
.load(glideUrl)
.submit();
try {
File file = targetHtml.get();
FileInputStream fis = new FileInputStream(file);
//新的 byte 數(shù)組輸出流斥难,緩沖區(qū)容量1024byte
ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
//緩存
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
//改變?yōu)閎yte[]
bt = bos.toByteArray();
//
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return bt;
}
public static GlideUrl buildUrl(String url){
GlideUrl cookie = new GlideUrl(url, new LazyHeaders.Builder()
.addHeader("Cookie", "2")
.build());
return cookie;
}
}
這里為什么要返回byte[],往下看
2.webview 設置 WebViewClient,重寫 shouldInterceptRequest
web.webViewClient = object : WebViewClient(){
override fun shouldInterceptRequest(
view: WebView?,
request: WebResourceRequest?
): WebResourceResponse? {
var url = request?.url.toString()
if(url.endsWith(".png") || url.endsWith(".jpg")){
val bytes = GlideUtil.syncLoad(url, "img")
if (bytes != null) {
return WebResourceResponse(
"image/*",
"utf-8",
ByteArrayInputStream(bytes)
)
}
}
if(url.endsWith(".html")){
val bytes = GlideUtil.syncLoad(url, "html")
if (bytes != null) {
return WebResourceResponse(
"text/html",
"utf-8",
ByteArrayInputStream(bytes)
)
}
}
return super.shouldInterceptRequest(view, request)
}
}
測試搞起來
1.第一次聯(lián)網加載后帘饶,去緩存目錄查看:
dsdsd.png
這里面應該包含了圖片及html源文件吧哑诊。
2.殺進程,斷網后及刻,再次打開app镀裤,完美還原>翰!暑劝!
3.為了驗證H5資源是使用了Glide緩存骆莹,將上圖中的文件拷出,嘗試一下重名名
1213123213.png
這些不就是H5所有的東西了嘛铃岔。
有的人要說有些H5里有視頻汪疮,我想只要把視頻當作file來處理,同樣是可行的吧毁习。待驗證.......
附上 Glide 4.+ 設置緩存路徑智嚷,便于后期維護本地資源
class App :Application() {
companion object{
lateinit var instance:Application
}
override fun onCreate() {
super.onCreate()
instance = this
initGlide()
}
fun initGlide(){
val builder = GlideBuilder()
//設置內存緩存大小為20mb
val memoryCacheSize = 1024 * 1024 * 200 // 200M
//設置內存緩存大小
builder.setMemoryCache(LruResourceCache(memoryCacheSize.toLong()))
//設置硬盤緩存大小為1G
val diskCacheSize = 1024 * 1024 * 1000 // 1G
// builder.setDiskCache(InternalCacheDiskCacheFactory(this, "Glide_Cache", diskCacheSize.toLong()))
builder.setDiskCache(DiskLruCacheFactory(cacheDir.path + "/Glide_Cache_Folder", diskCacheSize.toLong()))
Glide.init(this, builder)
}
}
筆記
通過 oss請求碼獲取視頻第一幀畫面
https://xxxxxxxxxx.mp4?x-oss-process=video/snapshot,t_1000,f_jpg,w_750