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优化思路还有落地离线加载的过程,希望可以对一些小伙伴有作用,也欢迎小伙伴们讨论和给些建议~

相关推荐
晨曦_子画7 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
孤客网络科技工作室29 分钟前
AJAX 全面教程:从基础到高级
android·ajax·okhttp
Mr Lee_2 小时前
android 配置鼠标右键快捷对apk进行反编译
android
顾北川_野2 小时前
Android CALL关于电话音频和紧急电话设置和获取
android·音视频
&岁月不待人&2 小时前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
Winston Wood4 小时前
Android Parcelable和Serializable的区别与联系
android·序列化
清风徐来辽4 小时前
Android 项目模型配置管理
android
帅得不敢出门5 小时前
Gradle命令编译Android Studio工程项目并签名
android·ide·android studio·gradlew
problc5 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
帅得不敢出门16 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡