Android 离线加载落地

Android 离线加载落地

作者简介:Serpit,Android开发工程师,2023年加入37手游技术部,目前负责国内游戏发行 Android SDK 开发。

前言

在使用WebView时,会有一个老生常谈的话题------"WebView加载优化"。那WebView加载优化,一般有几个方向:

  • WebView的预创建和复用
  • WebView代理请求
  • WebView的离线加载

这里简单科普一下这几个优化方向(大佬可以直接忽略~~)

预创建和复用

预创建和复用,见名知意,就是可以提前缓存一些WebView。这是因为,在WebView创建的时候,会需要一点时间,所以,为了节省这部分的时间,可以提前实例化WebView。这里可以使用缓存池来实现~

代理请求

代理请求,该方案是接管WebView的一些请求,帮助前端页面做请求,然后通过与前端的交互,将数据带回给前端页面。那,为什么要这么做呢?那也是"抢跑",提前在跳转/其他时机的时候,同时做一些网络请求,将业务数据处理好,等到前端页面加载好的时候,来客户端取即可。这样就节省了前端做请求的耗时了~

简单介绍完预创建和复用、WebView代理请求,接下来就介绍本文的离线加载了。

离线加载

离线加载是节省的哪一部分耗时呢?回答这个问题前,先了解下离线加载是个什么方案。

离线加载的原理是,拦截WebView的请求,转而在端内构造对应的响应来进行返回。所以,离线加载节省的是请求资源的耗时,快速页面的渲染。

如何落地?

落地这个离线加载,是离不开WebViewClient中一个关键的API

java 复制代码
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)

这个API是我们完成资源拦截的关键,它的Request参数,带有当前WebView正要加载资源的URL,而返回值WebResourceResponse则是返回给WebView,当前资源的响应。

下面就是伪代码

java 复制代码
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        WebResourceResponse webResourceResponse = fetchResource(request); //根据请求匹配资源
    if (webResourceResponse != null) {
        return webResourceResponse;
    }
    return super.shouldInterceptRequest(view, request);
}


private WebResourceResponse fetchResource(WebResourceRequest webResourceRequest) {
        String url = webResourceRequest.getUrl().toString();
        Uri uri = Uri.parse(url);
        File file = findFileLocal(uri); //省略匹配的逻辑...
        return new WebResourceResponse(mime, "UTF-8", new FileInputStream(file));
    }

有了这个强有力的API的,我们就可以轻松实现离线加载了。是不是很简单~

资源

因为离线加载除了加载逻辑以外,还有一个核心的点------资源!那资源管理这部分也是十分重要,下面将介绍资源管理部分需要注意的点和方案。由于我们的资源是前端资源,所以会有版本管理的需求,毕竟前端更新的时候本地的资源也需要更新,否则,加载出来的页面就会有问题。下面就介绍一下如何可以做到更新同步的。

更新注意的点有以下几个:

  • 更新时机
  • 更新策略

更新时机

更新时机,一般来说,在APP启动的时候会需要有一个检查的机制,检查当前的资源是否最新。然后防止用户在使用的过程中,前端有更新,也会在打开页面前做一次更新,确保用户的页面不受旧缓存影响。因此,更新的时机有两个,应用启动和打开页面。

更新策略

更新策略,也按应用启动和打开页面,有两个流程,下面用流程图的方式给大家介绍一下。

打开APP流程

在打开APP时,需要异步检查本地的离线包hash值是否与线上最新的版本一致,不一致则更新本地离线包,然后在更新成功后,则保存最新的离线包。当然,资源包目前只是做的整包更新,还可以在这个基础上优化做资源包的差分处理,做到增量资源包更新。这里先不展开,有兴趣的同学可以留言讨论~

打开页面更新流程

在打开页面前,也需要做一次检查,检查离线包是否最新,但这里有一个注意点和APP启动流程不太一样,因为更新离线资源是一个耗时的操作,所以当检查到本地不是最新时,需要把拦截WebView请求的逻辑给去除,让本次加载走线上的资源,同时等待下次资源最新可用的时候,才开启离线加载。

资源怎么来?

资源怎么来?很多同学会说,这不是废话吗?那当然从前端和后端资源服务接口来呀。这是肯定,没错的。但是,在调研初期,没有前端和后端同学的帮助时,又该如何验证可行性呢?这里安利一个Chrome的小插件Save All Resources。这个插件可以把浏览器的请求资源拦截到本地文件夹中,是不是一个妥妥的调研神器~

万事具备,落地!

不知大家是否还记得,在上一篇WebView文章中提到的"WebHook"概念呢?没有看过的同学可以回头看下这个这是你们项目中WebView的样子吗?。在这里我们可以实现一个LocalH5WebHook,然后针对一些开关和更新策略,对这个WebHook进行插拔,就可以灵活实现对离线加载功能的控制了。

java 复制代码
public class LocalH5WebHook extends SimpleWebHook {
     //... 省略其他代码
     public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        WebResourceResponse webResourceResponse = fetchResource(request);
        if (webResourceResponse != null) {
            return webResourceResponse;
        }
        return super.shouldInterceptRequest(view, request);
    }
}

总结

上述介绍了一些的WebView优化思路还有落地离线加载的过程,希望可以对一些小伙伴有作用,也欢迎小伙伴们讨论和给些建议~

相关推荐
锋风Fengfeng1 小时前
安卓15预置第三方apk时签名报错问题解决
android
User_undefined1 小时前
uniapp Native.js原生arr插件服务发送广播到uniapp页面中
android·javascript·uni-app
程序员厉飞雨2 小时前
Android R8 耗时优化
android·java·前端
丘狸尾4 小时前
[cisco 模拟器] ftp服务器配置
android·运维·服务器
van叶~6 小时前
探索未来编程:仓颉语言的优雅设计与无限可能
android·java·数据库·仓颉
Crossoads10 小时前
【汇编语言】端口 —— 「从端口到时间:一文了解CMOS RAM与汇编指令的交汇」
android·java·汇编·深度学习·网络协议·机器学习·汇编语言
li_liuliu11 小时前
Android4.4 在系统中添加自己的System Service
android
C4rpeDime13 小时前
自建MD5解密平台-续
android
鲤籽鲲15 小时前
C# Random 随机数 全面解析
android·java·c#
m0_5485147718 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php