美文网首页
探索WebKit(一)

探索WebKit(一)

作者: FingerStyle | 来源:发表于2017-09-07 15:23 被阅读121次

最近由于webview频繁崩溃等一些原因,开始研究起webkit了。 网上研究webkit的文章很多,但是大多是基于QT或者Chrome的,真正跟iOS相关的很少,于是我决定研究一下iOS内部的实现。 由于公开资料太少,我只能从苹果网站上下载源码,然后结合其他平台上的研究成果,讲一讲我自己对于WebKit的理解。

WebKit架构

按照国际惯例,首先来一张架构图:(盗用其他人的)

WebKit 从大体说包含有 WebCore和JSCore以及各个平台上的移植部分(因为是跨平台的)。实际运行的时候有两个进程:WebProcess和UIProcess。UIProcess 就是处理UI相关的,界面展示、用户操作等等,WebProcess处理核心的Web资源的加载、DOM的渲染等等。在某些平台上(比如Android)这两个进程可以单独控制,这样即使Web进程崩溃了,App也不至于卡死或者崩溃,保证了比较好的用户体验。

在iOS 上Webkit的实际载体是UIWebView和WKWebView,UIWebView可参考的资料比较少,虽然内核是一样的,但WKWebView研究起来显然更方便点。下面我就着重讲WKWebView的加载过程。我不喜欢贴代码,需要看源码的可以直接去官网下载https://opensource.apple.com/release/ios-935.html

WKWebView加载过程

1. 创建WKWebView,根据WKWebViewConfiguration配置相应选项。

2. 客户端调用WKWebView的LoadRequest方法,这时会进入Webkit框架,调用WebPageProxy的loadRequest方法,请求的参数是一个ResourceRequest,以及是否加载外部链接的策略、用户自定义参数等。这个方法会根据URL判断是否需要启用沙箱扩展来处理外部链接,并且调用其内部的WebPage对象来处理页面加载。

WebPageProxy是WebPage的代理,他把WebPage的方法封装起来,外部(如WKWebView)调用时通过其内部的WebProcessProxy(继承自ChildProcessProxy) 发送到WebProcess进程调用。而真正处理请求的是WebPage对象,这个对象管理着每一个页面的加载,包括前进、后退、停止加载等等。当WebProcess需要用户做出一些决策的时候,也会通过WebPageProxy回调到UIProcess上的WKWebView等上层对象。

3. WebPage也有一个loadRequest方法,在这里面把加载页面的请求转成了加载MainFrame的请求,也就是FrameLoadRequest。接下来就是加载Frame的过程,这个进入到WebCore框架内部的Page类,而其实Page也只是把Frame组装起来,真正的调用是由frame的loader对象,也就是FrameLoader来完成。

FrameLoader结构

4. FrameLoader中最重要的类是DocumentLoader,负责页面的加载。FrameLoader维护了三个DocumentLoader对象,分别对应于不同的阶段,m_policyDocumentLoader对应于收到用户load调用,进行policy check阶段,m_provisionalDocumentLoader对应于policy check以后,Frame数据还没有到来之前,它会负责startLoadingMainResource的调用。m_documentLoader则是Frame第一个数据到来以后使用的DocumentLoader,这个时候,前一个主Frame的DocumentLoader已经不能再用(user agent开始白屏,刷掉前一个页面的显示)。

5. 下面具体讲一下policy check阶段。在FrameLoader的loadWithDocumentLoader方法中,做了一些判断,是页面部分的加载还是整个页面的加载,以及调用policyChecker的checkNavigationPolicy方法来检测这次浏览的处理方法。checkNavigationPolicy这个方法里设置了外部链接的action,以及有一个dispatchDecidePolicyForNavigationAction的回调函数让用户决定是否需要继续浏览(内部默认实现为空,实际上是调用到了WebKit框的WebFrameLoaderClient类中,而这个类我估计会直接调用到 WKWebViewNavigation的代理方法)。checkNavigationPolicy执行的最后会回调到FrameLoader的continueLoadAfterNavigationPolicy方法,这个方法在过滤了一些非法的URL后,docuemntloader进入到provisional阶段。

6. 在continueLoadAfterNavigationPolicy方法最后有一行代码,调用了mClient(实际上是WebFrameLoaderClient)的dispatchWillSubmitForm方法,通知UIProcess进行界面的处理,然后调用了continueLoadAfterWillSubmitForm方法。这个方法里面做了一些准备工作,然后就开始加载主页面资源,也就是前面说的startLoadingMainResource方法。

To be continued....

相关文章

网友评论

      本文标题:探索WebKit(一)

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