Webview 是一种在应用程序内嵌入 Web 内容的技术。它允许开发人员在移动应用程序中显示 Web 内容,同时仍然保留应用程序的原生外观和感觉。Webview 组件由一个用户界面(UI)部分和一个可编程接口(API)部分组成。
UI 部分是应用程序中的一个视图,它显示 Web 内容。用户可以在此视图中浏览网页、填写表单等。UI 部分可以是 Android 或 iOS 中的一个视图,它支持一些基本的 Web 浏览器功能,例如滚动、放大缩小等。
API 部分是一组允许应用程序与 Webview 进行交互的编程接口。开发人员可以使用 API 部分访问 Webview 中的 DOM 元素、执行 JavaScript 代码、设置 Webview 的配置选项等。这使得开发人员可以在应用程序和 Web 内容之间实现双向通信和交互。
Webview 在移动应用程序中广泛使用,例如在社交媒体应用程序中显示网页内容,或在电子商务应用程序中显示商品详细信息。
Hybrid App的本质,其实是在原生的 App 中,使用 WebView 作为容器直接承载 Web页面。因此,最核心的点就是 Native端 与 H5端 之间的双向通讯层,其实这里也可以理解为我们需要一套跨语言通讯方案,来完成 Native(Java/Objective-c/...) 与 JavaScript 的通讯。这个方案就是我们所说的 JSBridge,而实现的关键便是作为容器的 WebView,一切的原理都是基于 WebView 的机制。
WebView是一个基于webkit引擎、展现web页面的控件。
H5开发
Hybrid APP开发方式,即App中既有原生页面又有H5页面的混合开发模式。
- 原生开发:使用Android 或IOS对应的编程语言在相应的平台上进行开发,不能跨平台开发,App页面上包含的所有UI元素、数据内容等随App安装到手机上,离线状态下也能使用大部分内容。如果页面内容有更新,则需要发布新的App版本并且用户更新版本才能看到。
- H5页面:使用html+js+css等web技术开发的页面就是H5页面。H5表示HTML5,是由w3c制定的HTML标准。H5页面通过浏览器运行,支持跨平台开发,只需要开发一套代码就可以在Android、IOS和Windows上运行。开发者更新页面内容后用户可以直接查看新的页面,不需要更新App版本。
- 混合开发:同时使用原生和web技术进行App开发,因为web页面需要浏览器支持,原生代码利用webview(Android)或UIWebview\WKWebView(IOS)为H5页面提供容器。
webview
WebView是一个基于webkit引擎、展现web页面的控件。JavaScript 执行在 WebView 的 Webkit 引擎中。webview提供了原生与H5(java与JavaScript)之间双向通讯的方案,即JSBridge。JSBridge 是一种 JS 实现的 Bridge,实现了JS调用原生和原生调用JS。
实现上分为4点:
(1). 原生编写方法供H5调用 (2). 原生调用H5提供的方法 (3). H5编写JS方法供原生调用 (4). H5调用原生提供的方法
其中第(1)、(2)点在原生中实现,第(3)、(4)点在H5中实现。
1.JavaScript调用原生的方式
拦截url scheme
在 WebView 中发出的网络请求,原生都能进行监听和捕获。因此由 h5 发起一个自定义协议请求,app 拦截这个请求后,根据请求的协议、参数、回调等进行处理,再由 app 调用 h5 中的回调函数。 详细步骤如下:
发起一个如
jsbridge://methodName?param1=value1¶m2=value2
自定义协议的网络请求有两种方式:1. 通过localtion.href;2. 通过iframe方式; 通过location.href有个问题,同时并发多次请求会被合并成为一次,导致协议被忽略,也就是连续多次修改window.location.href
的值,在Native层只能接收到最后一次请求,前面的请求都会被忽略掉。Webview 端通过
iframe.src
发送 url scheme 请求,之后 Native使用shouldOverrideUrlLoading
方法拦截到请求并对url协议进行解析,根据 url scheme(包括所带的参数)进行相关操作。jslet url = 'jsbridge://xxx/xxx'; let iframe = document.createElement('iframe'); iframe.src = url; document.body.appendChild(iframe);
原生解析自定义协议请求并处理后,需要将处理结果返回给H5,这里有两种方法实现:
- 原生调用H5提供在
window
上提供的回调函数 - 通过事件监听:H5发送自定义协议请求时在
window
上添加一个事件监听器,同时指定一个事件响应函数。原生处理完数据后通过window.dispatchEvent(event)
派发一个事件并且将需要返回的数据传递出去。
- 原生调用H5提供在
注入API:Native 获取 JavaScript环境上下文,并直接在上面挂载对象或者方法,使 js 可以直接调用,Android 与 IOS 分别拥有对应的挂载方式。但是这种方法存在一定的安全隐患。
原生重写windows上的方法:使用prompt、console.log、alert方式,在webview层重写这三个方法。
Native调用JavaScript
Native调用JS只需要H5在在全局暴露一些方法供原生调用,
window.sdk = {
double: val => val*2
}
原生调用的方式:
使用webview的loadurl调用
javawebview.loadurl('javascript:JSBridge.trigger("webviewReady")')
evaluateJavascript:Android 4.4+可以使用evaluateJavascript实现Native调用JS
javawebview.evaluateJavascript('window.sdk.double(4)');