美文网首页
Glide 玩转 WebView缓存

Glide 玩转 WebView缓存

作者: 米奇小林 | 来源:发表于2023-02-23 14:45 被阅读0次

    最近接到个奇葩需求,缓存webview,我想着webview不是自带缓存么,奈何手上这个设备由于网络等各种限制问题,导致webview不能直接加载H5中的资源。也就是说原生缓存机制啥的用不了。

    思路:

    1.H5本身是html文件,可以想办法保存在本地。

    2.H5内的图片可以通过Glide来处理。设置WebViewClient,通过shouldInterceptRequest 拦截所有的资源请求,将图片交给Glide。

    开搞: 这里有个问题H5本身怎么保存,估计要写很多代码吧,对于我这个懒人来说太麻烦,html本身就是文件,能不能用glide来处理尼。

    查资料发现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 数组输出流,缓冲区容量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();
                        //改变为byte[]
                        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.第一次联网加载后,去缓存目录查看:

    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
    

    相关文章

      网友评论

          本文标题:Glide 玩转 WebView缓存

          本文链接:https://www.haomeiwen.com/subject/qmazkdtx.html