当前位置: 首页 > Web前端 > HTML5

VasSonicAndroid源码分析

时间:2023-04-05 14:33:05 HTML5

VasSonic是腾讯推出的一款高性能Hybrid框架,用于提高H5页面首屏加载速度。目前广泛应用于QQ商城等Hybrid界面,提升用户体验。https://github.com/Tencent/Va...github地址一、实现原理几乎所有的Hybrid接口都是以WebView接口为载体,而H5接口的加载时间主要消耗在WebView初始化、网络请求、和WebView渲染。部分。WebView初始化和WebView渲染都在100ms量级,主要时间瓶颈是网络请求,尤其是弱网情况下,消耗时间会达到s级,导致H5长时间白屏接口或异常打开。为了解决这个问题,在WebView中提供了publicWebResourceResponseshouldInterceptRequest(WebViewview,Stringurl)函数,负责拦截加载html中使用的资源文件。基于此,介绍了VasSonic的核心思想。并行加载、本地缓存、模板更改。总体思路是利用WebView初始化的时间并行进行网络请求,使用缓存进行预加载。网络请求完成后,将改变的部分返回给浏览器,使用JS改变数据。2.核心进程SonicSession的全部源代码我们应该以SonicSession文件为入口。它管理整个并行过程,负责获取缓存、网络请求,并通过向外界暴露抽象方法,交给子类处理错误处理、预加载和模板。改变,并提供唯一与JS交互的出口,我们来详细了解一下它的过程。WebView在启动和初始化之前,会调用SonicSession的start方法,然后在子线程中调用runSonicFlow方法开始并行处理。在runSonicFlow中,我们会尝试去获取缓存,交给子类的handleLocalHtml处理,这里可以处理preloading。然后将运行handleFlow_connection方法。首先,它会获取SessionConnect,然后会在本地缓存中添加一些信息,获取变化后的网页。connect操作后会得到responseCode,交给SonicSession的子类进行HanldeFlow_304、handleFlow_HttpError、handleFlow_ServiceUnavailable等串行错误处理。之后会判断缓存是否为空。如果缓存为空,则由子类的handleFlow_FirstLoad处理。如果不为空,则Data发生变化时,由子类的handleFlow_TemplateChange处理。handleFlow_DataChange处理。可以看出,SonicSession主要是在几个关键节点上将方法暴露给子类。获取缓存后,子类调用handleLocalHtml进行处理。网络连接完成后,会根据错误码等信息,将一系列错误交给子类hanldeFlow_304、leFlow_HttpError、handleFlow_ServiceUnavailable。处理,获取网络请求成功后,如果缓存为空,会调用子类的handleFlowFirstLoad进行处理。如果缓存不为空,则根据结果的头部信息判断是模板变化还是数据变化,分别由handleFlow_TemplateChange和handleFlow_DataChange处理。在SonicSession中,也提供了一些方法用于各种事件的回调。SessionClient创建完成后调用OnClientReady方法,表示WebView已经初始化完成。当WebView开始加载资源时,会被shouldInterceptRequest方法拦截,调用我们的OnClientRequestResource方法来标记WebView开始加载数据。WebView渲染完成后会调用OnWebReady方法,里面会携带JS的回调方法,最后通过setResult调用H5的回调方法。3、SonicSession的两种具体实现从上面对SonicSession的分析可以看出,子类SonicSession需要重点调用loadUrl或loadUrlWithBaseUrl来启动浏览器加载过程。分配pengdingWebResourceStream返回给浏览器解析。模板和数据变化通知发送到浏览器进行相应的处理。拦截资源实现加载。调用setResult进行浏览器回调。1、StandardSonicSession是基于安全考虑,StandardSonicSession模式下只支持loadUrl。浏览器就绪后,我们可以直接调用loadUrl,所以在OnClientReady中,我们可以直接调用loadUrl。pendingWebResourceStream的赋值是在上面这行的过程中完成的。WebView支持边加载边渲染的特性。我们可以在流进去之后继续写,所以我们定义了SonicSessionStream,后面会介绍。因此需要判断数据是否被接受,区别对待赋值操作,然后执行保存数据的操作。我们来看看StandardSession进程是如何处理的,pendingWebResourceStream是在哪里操作的。在上面的流程图中,可以看到会根据模板和Data的变化进行不同的处理。从上面的分析可以看出,在loadingUrl之后,WebView可以在onClientRequestResource方法中拦截浏览器资源的加载,注意!该方法只会拦截我们的html文件并传入文件流,不会拦截资源文件。此方法等待网络流。等待pengdingWebResourceStream的值后,会返回流给浏览器加载渲染。setResul需要在onWebReady中使用一次,这里我们确定回调方式。以后每次流程变化都需要调用一次,这样可以帮助我们理清每次请求的流程,更重要的是当Data发生变化时,我们可以调用浏览器的回调方法。2、QuickSonicSession与Standard核心的区别在于,加入缓存的html字符串可以通过loadBaseUrl实现,在速度上有一定的优势,但是在安全上存在一定的问题,经过实测速度优势并不明显.在实现上,我们需要注意标准模式的变化。重点是不能在OnClientReady中直接调用loadUrl。有缓存的时候需要loadBaseUrl,然后自己构造header。其他变化不大。4、具体过程下面我们来梳理一下具体过程。首先,我们将展示初始化过程。SonicSession启动后的流程如下图。5.不同线程之间处理等待的具体问题如何调度和通信网络请求所在的业务在Sonic子线程中,主线程主要通过main的handler与WebView所在的主线程进行通信线。WebView所在的主线程主要通过控制Atomic变量来控制子线程。当WebView加载完毕,网络请求的结果还没有赋值时,会通过同步锁等待网络请求的结果。其实WebView是支持加载渲染的特性的,只要把数据流传给WebView就行,所以提供了SonicSessionStream来支持这个特性,下面会介绍。如何桥接网络流和内存流可以看到,当网络数据完成时,直接将数据放入Stream,未完成时,创建一个SonicSessionStream。上面的outputStream代表已经读入内存的memStream,responseStream代表还没有读入的netStream。桥接可以通过重写SonicSeesionStream的read方法来实现。如何做局部刷新当加载缓存数据网页时,也就是调用onWebReady后,js回调方法会通过javascriptInterface返回给App。当服务端要通知客户端部分刷新时,会通过header中的template-tag通知,并返回数据的json。将本地数据与新数据进行比较,返回差异数据,并将结果赋值给pendingDiffData。然后会通过setResult调用js的回调方法,完成局部刷新过程。存储缓存文件进行缓存时,会计算返回结果的sha1值,存储到sp中。获取缓存时,会从sp中读取文件的sha1值进行比较。负责人管理(跨域问题)