Hybrid App 应用开发中 9 个必备知识点复习(WebView / 调试 等)

本文详细介绍了在Hybrid App开发中,iOS和Android平台的WebView调试,包括WKWebView与UIWebView的区别、WKWebView的常见问题、Crosswalk的作用,以及WebView性能优化方案。此外,还讲解了在Android和iOS环境下如何调试WebView,以及利用Fiddler和Charles进行网络调试。针对企业微信、微信和钉钉版的调试工具也进行了说明,同时分享了调试技巧,如Chrome控制台和console.log的使用。
摘要由CSDN通过智能技术生成

bg

前言

我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 《Hybrid APP 混合应用专题》 主题的第二期和第三期的合集。

这一期共整理了 10 个问题,和相应的参考答案,文字和图片较多,建议大家可以收藏,根据文章目录来阅读

之前分享的每周内容,我都整理到掘金收藏集 ?《EFT每周一练》 上啦,欢迎点赞收藏咯??。

内容回顾:

  1. 《EFT 每周分享 —— Hybrid App 应用开发中 5 个必备知识点复习》

  2. 《EFT 每周分享 —— HTTP 的15个常见知识点复习》

  3. 《EFT 每周分享 —— 数据结构与算法合集》

文章收录:

本系列所有文章,都将收录在 Github 上,欢迎点击查阅

注:本文整理部分资料来源网络,有些图片/段落找不到原文出处,如有侵权,联系删除。

一、iOS 平台中 UIWebView 与 WKWebView 有什么区别?

参考文章:《UIWebView与WKWebView》

UIWebView 是苹果继承于 UIView 封装的一个加载 web 内容的类,它可以加载任何远端的web数据展示在你的页面上,你可以像浏览器一样前进后退刷新等操作。不过苹果在 iOS8 以后推出了 WKWebView 来加载 Web,并应用于 iOS 和 OSX 中,它取代了 UIWebViewWebView ,在两个平台上支持同一套 API。

它脱离于 UIWebView 的设计,将原本的设计拆分成14个类,和3个代理协议,虽然是这样但是了解之后其实用法比较简单,依照职责单一的原则,每个协议做的事情根据功能分类。

UIWebView

WKWebViewUIWebView 的区别:

  • WKWebView 的内存远远没有 UIWebView 的开销大,而且没有缓存;

  • WKWebView 拥有高达 60FPS 滚动刷新率及内置手势;

  • WKWebView 支持了更多的 HTML5 特性;

  • WKWebView 高效的 app 和 web 信息交换通道;

  • WKWebView 允许 JavaScriptNitro 库加载并使用, UIWebView 中限制了;

  • WKWebView 目前缺少关于页码相关的 API;

  • WKWebView 提供加载网页进度的属性;

  • WKWebView 使用 Safari 相同的 JavaScript 引擎;

  • WKWebView 增加加载进度属性: estimatedProgress

  • WKWebView 不支持页面缓存,需要自己注入 cookie , 而 UIWebView 是自动注入 cookie

  • WKWebView 无法发送 POST 参数问题;

  • WKWebView 可以和js直接互调函数,不像 UIWebView 需要第三方库 WebViewJavascriptBridge 来协助处理和 js 的交互;

注意:

大多数App需要支持 iOS7 以上的版本,而 WKWebView 只在 iOS8 后才能用,所以需要一个兼容性方案,既 iOS7 下用 UIWebViewiOS8 后用 WKWebView 。但是目前 IOS10 以下的系统以及很少了,

小结:

WKWebView 相较于 UIWebView 在整体上有较大的提升,满足 iOS 上面使用同一套控件的功能,同时对整个内存的开销以及滚动刷新率和 JS 交互做了优化的处理。

依据职责单一原则,拆分成了三个协议去实现 WebView 的响应,解耦了 JS 交互和加载进度的响应处理。

WKWebView 没有做缓存处理,所以对网页需要缓存的加载性能要求没那么高的还是可以考虑 UIWebView

二、WKWebView 有哪一些坑?

参考文章:《WKWebView 那些坑》

1. WKWebView 白屏问题

WKWebView 实际上是个多进程组件,这也是它加载速度更快,内存暂用更低的原因。

UIWebView 上当内存占用太大的时候,App Process 会 crash;而在 WKWebView 上当总体的内存占用比较大的时候,WebContent Process 会 crash,从而出现白屏现象。

解决办法:

  1. 借助 WKNavigtionDelegate

WKWebView 总体内存占用过大,页面即将白屏的时候,系统会调用上面的回调函数,我们在该函数里执行[webView reload](这个时候 webView.URL 取值尚不为nil)解决白屏问题。在一些高内存消耗的页面可能会频繁刷新当前页面,H5侧也要做相应的适配操作。

  1. 检测 webView.title 是否为空

并不是所有 H5 页面白屏的时候都会调用上面的回调函数,比如,最近遇到在一个高内存消耗的 H5 页面上 present 系统相机,拍照完毕后返回原来页面的时候出现白屏现象(拍照过程消耗了大量内存,导致内存紧张,WebContent Process 被系统挂起),但上面的回调函数并没有被调用。在 WKWebView 白屏的时候,另一种现象是 webView.titile 会被置空, 因此,可以在 viewWillAppear 的时候检测 webView.title 是否为空来 reload 页面。

2. WKWebView Cookie 问题

WKWebView Cookie 问题在于 WKWebView 发起的请求不会自动带上存储于 NSHTTPCookieStorage 容器中的 Cookie,而在 UIWebView 会自动带上 Cookie

原因是:

WKWebView 拥有自己的私有存储,不会将 Cookie 存入到标准的 Cookie 容器NSHTTPCookieStorage 中。

实践发现 WKWebView 实例其实也会将 Cookie 存储于 NSHTTPCookieStorage 中,但存储时机有延迟,在 iOS 8上,当页面跳转的时候,当前页面的 Cookie 会写入 NSHTTPCookieStorage 中,而在 iOS 10 上,JS 执行 document.cookie 或服务器 set-cookie 注入的 Cookie 会很快同步到 NSHTTPCookieStorage 中,FireFox 工程师曾建议通过 reset WKProcessPool 来触发 Cookie 同步到 NSHTTPCookieStorage 中,实践发现不起作用,并可能会引发当前页面 session cookie丢失等问题。

解决办法1:

WKWebView loadRequest 前,在 request header 中设置 Cookie, 解决首个请求 Cookie 带不上的问题;

解决办法2:

通过 document.cookie 设置 Cookie 解决后续页面(同域)Ajax``、iframe 请求的 Cookie 问题;(注意:document.cookie() 无法跨域设置 cookie)。

3. WKWebView loadRequest 问题

WKWebView 上通过 loadRequest 发起的 post 请求 body 数据会丢失,同样是由于进程间通信性能问题HTTPBody 字段被丢弃。

4. WKWebView NSURLProtocol问题

WKWebView 在独立于 app 进程之外的进程中执行网络请求,请求数据不经过主进程,因此,在 WKWebView 上直接使用 NSURLProtocol 无法拦截请求。

解决办法:

由于 WKWebView 在独立进程里执行网络请求。一旦注册 http(s) scheme 后,网络请求将从 Network Process 发送到 App Process,这样 NSURLProtocol 才能拦截网络请求。在 webkit2 的设计里使用 MessageQueue 进行进程之间的通信,Network Process 会将请求 encode 成一个 Message,然后通过 IPC 发送给App Process。出于性能的原因,encode 的时候 HTTPBodyHTTPBodyStream 这两个字段会被丢弃掉了。

5. WKWebView 页面样式问题

WKWebView 适配过程中,我们发现部分 H5 页面元素位置向下偏移或被拉伸变形,追踪后发现主要是 H5 页面高度值异常导致。

解决办法:

调整 WKWebView 布局方式,避免调整webView.scrollView.contentInset 。实际上,即便在 UIWebView 上也不建议直接调整 webView.scrollView.contentInset 的值,这确实会带来一些奇怪的问题。如果某些特殊情况下非得调整 contentInset 不可的话,可以通过下面方式让H5页面恢复正常显示。

6. WKWebView 截屏问题

WKWebView 下通过 -[CALayer renderInContext:]实现截屏的方式失效,需要通过以下方式实现截屏功能:

@implementation UIView (ImageSnapshot) 
- (UIImage*)imageSnapshot { 
    UIGraphicsBeginImageContextWithOptions(self.bounds.size,YES,self.contentScaleFactor);
    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES]; 
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 
@end

然而这种方式依然解决不了 webGL 页面的截屏问题,截屏结果不是空白就是纯黑图片。

解决办法:

无奈之下,我们只能约定一个JS接口,让游戏开发商实现该接口,具体是通过 canvas getImageData()方法取得图片数据后返回 base64 格式的数据,客户端在需要截图的时候,调用这个JS接口获取base64 String并转换成 UIImage。<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值