说说WebPlugin

243 阅读4分钟
  • 1,是干什么的,然后大致原理;
  • 2,离线包组成;
  • 3,工作原理;
  • 3.1,下载原理
  • 3.2,打开原理
  • 3.2,cookie注意点
  • 4,数据并行

WebPlugin是为了加速H5页面的展示速度,我们打开一个h5页面的流程大致如下

离线化插件的大致思路是将H5页面中的html、js、css以及一些静态的图片资源打包离线化至本地,在打开相应页面的时候从本地去打开,然后只需获取对应页面的数据,省去html、js、图片等资源的下载时间。

一个H5离线化插件一般对应某个业务。

离线化插件一般对应某个业务,这个业务通常包括多个H5页面。 离线化插件的内容主要包括两个方面:

  • 1、多个H5页面中的html、js、css以及一些静态的图片资源
  • 2、config.json文件。 config.json文件是插件配置文件,描述了这个插件中页面的名称和路径的映射关系

离线化插件工作的一个流程大概是是这样的:

  • 1、通过运营平台上传我们打包好的离线化插件
  • 2、服务端下发离线插件数据, 主要包括一个插件数组和一个总体md5值,每个插件对应:一个pluginid,唯一标识这个插件,也是作为这个插件下载的一个目录,一个插件下载的url,另外还有一个插件对应的md5值。 更新时机:app启动或者前后台切换的时候

主要的一个更新策略就是先去对比服务端下发的总体md5值和本地记录的总的md5值是否相同,相同就不更新,如果不同说明说明有更新,再去对比每个插件的m5值,对m5值改变的插件做更新,每个插件更新完成之后记录对应md5值,所有插件更新完成后记录总体md5值。

更新离线插件,可以先下载target.zip包,然后将其重命名为target_new.zip,然后解压,解压完成后,将旧的离线插件命名为target.temp,将新的离线包命名为target.zip,删除旧的离线插件临时文件target.temp,如果失败就恢复。

    val aTmp = File(a.parent, "${a.name}.tmp")
    if (a.exists()) {
        if (!a.renameTo(aTmp)) {
            throw IOException("Failed to rename a to temp")
        }
    }

    if (!b.renameTo(a)) {
        // 回滚
        aTmp.renameTo(a)
        throw IOException("Failed to rename b to a")
    }

    // 成功后删除临时文件
    if (aTmp.exists()) {
        aTmp.delete()
    }
}

紧急更新,先检查是否有当离线包的下载任务,并判断是否已经开始下载,如果没开始就删除这个任务,然后开启一个紧急任务去下载这个离线包;如果开始了就给这个任务添加一个监听器,监听完成,完成后重新打开这个离线包。

插件下载完成之后,我们就可以从本地进行打开: 打开的一个流程大概是这样的:

一个打开plugin的bdwm协议是这样的: demo://plugin?pluginId=xxx&pageName=xxx

  • (1)根据pluginId,获取该插件的目录

  • (2)读取config.json配置文件。

  • (3)根据的pageName,可以查找到对应页面的pagePath;

  • (4)构造出一个以file开头的h5文件的路径,然后使用webview去打开 在打开的过程中需要请求这个页面的数据 这个时候有两种情况:

  • 第一:页面不需要cookie信息,那么由这个页面自己发送网络请求

  • 第二:页面需要cookie信息,webview在加载url的时候会根据url的域自动带上本地cookie信息

但是我们现在加载的是以file开头的一个路径,这个路径中是没有域的,所有webview是没法带cookie的。 解决方式是h5调用我们native的网络请求能力,native网络请求中去带上cookie,然后把请求到的数据传递给h5页面。

为了进一步加快离线包的页面显示速度,还为这个离线包做了数据预加载的优化,让webview的打开过程和h5页面的数据加载过程并行。

数据预加载前提:

在离线包的config.json文件中为需要预加载的页面,添加预加载数据PreloadRequest,主要包含预加载的url,请求方法,请求参数等。

大致流程是:

  • 1、在webview打开页面同时,通过pluginId找到对应插件的config配置文件,读取相应页面的预加载数据。

  • 2、根据这个预加载数据使用我们本地的okhttp网络请求框架去请求数据,然后将结果传递给h5页面,h5页面收到后就可以数据刷新。

  • (3)当数据获取成功,如果jsbridge注入完成,则调用其回调方法PreloadFinish,将获取到的数据传递给h5页面;如果jsbridge未注入完成,则将获取的数据缓存到内存,待jsbridge注入完成,在其注入完成的回调中,调用h5页面的回调方法PreloadFinish将数据传递给h5页面。h5页面收到数据后,并可根据数据去填充页面。

blog.csdn.net/lixiaolu199…