Skip to content

WebView是什么

WebView 是一个用于在应用内部显示网页的视图组件,它允许我们在应用内部嵌入一个简单的浏览器,可以用来显示网页或者加载网络内容。这就意味着,你可以在你的应用中直接嵌入网页,让用户在不离开应用的情况下浏览网页内容


在Android 中,WebView 是 android.webkit.WebView 类的一个实例,你可以在布局文件或者代码中创建它,并使用 loadUrl() 方法来加载网页。

你还可以通过各种配置和方法,来控制它的行为,比如启用/禁用 JavaScript、缩放页面、监听页面加载状态等。


在 iOS 中,WKWebView 是在 WebKit 框架下的一个用于显示网页的组件,与 Android 中的 WebView 类似。你可以将 WKWebView 嵌入到你的视图中,通过 load() 方法来加载网页。同时,WKWebView 还提供了一系列的 API,允许你控制它的行为,比如监听页面加载状态、处理网页出错、执行 JavaScript、与 JavaScript 进行交互等。 WKWebView 至少需要 iOS 8 和以上的系统才可以使用,早期是UIWebView(性能差)

JS Bridge

JS Bridge 主要用于JS和Native之间的双向通信,相当于是它们的一个桥梁。

通常情况下,JavaScript 是无法直接访问和控制设备原生的 API 的,JSBridge 简单来讲,主要是 给 JavaScript 提供调用 Native 功能的接口,让混合开发中的『前端部分』可以方便地使用地址位置、摄像头甚至支付等 Native 功能。同时,由名字 bridge,桥的意思来看,Native通用可以通过JS Bridge 调用JS

Native => JS

Native 调用 JavaScript 较为简单,毕竟不管是 iOS 的 WKWebView,还是 Android 的 WebView 组件,都以子组件的形式存在于 View/Activity 中,直接调用相应的 API 即可。

通过 WebView 的 loadUrl()evaluateJavaScript()

等方法调用 JavaScript 函数:这种方式通常用于 Android 向 Web 发送信息或者执行某个 JavaScript 函数。

java
// Android 4.4之前
webView.loadUrl("javascript:" + javaScriptString);
java
// android 4.4之后
webView.evaluateJavascript("javaScriptString:YourFunction()", new ValueCallback<String>() {
    @Override
    public voidon ReceiveValue(String value){

    }
});

IOS => WKWebView 的 evaluateJavaScript() 方法

typescript
webView.evaluateJavaScript("YourFunction()", completionHandler: nil);

JS(web) => Native


拦截URL Schema

Android 和 iOS 都可以通过拦截 Webview请求的URL Scheme, 并解析 Scheme 来决定是否进行对应的 Native 代码逻辑处理。


Android 的话,Webview 提供了 shouldOverrideUrlLoading 方法来提供给 Native 拦截 H5 发送的 URL Scheme 请求

java
webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("scheme://")) {
            // 这是一个从 JavaScript 发出的调用,拦截这个请求,不让 WebView 加载这个 URL
            // 从 URL 中解析出命令和参数...
            return true;  // 表示这个 URL 已经被处理了,WebView 不需要再加载它了。
        }
        return false;  // 表示这个 URL 没有被处理,让 WebView 继续加载它。
    }
});

iOS 的 WKWebview ,使用decidePolicyForNavigationAction

向WebView注入JS API

Android => addJavascriptInterface()

在 Android 端,通过 WebView 的addJavascriptInterface() 方法向 JavaScript 提供 Android 对象。 可以创建一个类(例如 NativeBridge),在这个类中定义一些供 JavaScript 调用的方法。然后通过 addJavascriptInterface() 方法将这个类的一个实例传递给 WebView

java
public class NativeBridge {

    // 增加JS调用接口
    @JavascriptInterface
    public void YourFunctionFromAndroid(String str) {
        // 执行的操作...
    }
}

webView.addJavascriptInterface(new NativeBridge(), "NativeBridge");

然后JS端就可以调用这个暴露出的方法了

typescript
window.NativeBridge.YourFunctionFromAndroid('Hello from JS');

IOS => WKScriptMessageHandler

  • iOS的UIWebView(早 oout 了)提供了JavaSciptCore
  • iOS的WKWebView提供了WKScriptMessageHandler
swift
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptCanOpenWindowsAutomatically = YES;
preferences.minimumFontSize = 40.0;
configuration.preferences = preferences;
    

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"share"];
  	[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"pickImage"];
}
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self.webView.configuration.userContentController 	removeScriptMessageHandlerForName:@"share"];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"pickImage"];
}
typescript
// JS 调用
window.webkit.messageHandlers.share.postMessage(xxx);