前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JSBridge小科普

JSBridge小科普

作者头像
娜姐
发布2020-09-22 10:46:53
2.8K0
发布2020-09-22 10:46:53
举报
文章被收录于专栏:娜姐聊前端

做Hybird APP开发的同学,应该对JSBridge不陌生,它用于H5页面和Native(Android或者iOS)通信。常用的三方库如Dsbridge系列(https://github.com/wendux/DSBridge-Android)。那么,你知道JSBridge到底是如何在两端进行通信的吗?

下面的实例代码,Native端以Android为例。

1. Web调用Native能力

1.1 通过URI Schema请求(全局注册)

Native应用可以在移动端系统中注册一个Schema协议的URI,这个URI可以在系统的任意地方授权访问,用来调起一段原生方法,或者唤起一个原生界面。

于是,Native WebView控件中的H5页面,可以通过JS代码请求这个通用Schema协议。 比如,通过添加一个不可见的iframe,设置其src属性,发送一个URI请求。

代码语言:javascript
复制
let iframe = document.createElement('iframe');
iframe.setAttribute('style', 'display:none');
document.body.appendChild(iframe);
iframe.setAttribute('src', 'myapp://className/method?args')

整个调用流程如下图。一旦系统捕获到注册表中的Schema URI,就会通过此URI地址执行该Schema协议定义的Native操作,执行一段Native代码或者打开APP的某个页面(如打开摄像头,唤起图片预览功能,跳转APP支付页面等)

jsBridge_native Schema.png

1.2 通过代码注入(针对webView组件)

以Android为例,可以通过addJavascriptInterface方法将Native的一个对象注入到页面中,供JS调用。

代码语言:javascript
复制
/** 
* 添加javascriptInterface 
* 第一个参数:这里需要一个与js映射的java对象 
* 第二个参数:该java对象被映射为js对象后在js里面的对象名,在js中要调用该对象的方法就是通过这个来调用 
*/  
 webView.addJavascriptInterface(new JSInterface(), "android");  

 private final class JSInterface{  
    /** 
     * 注意这里的@JavascriptInterface注解, target是4.2以上都需要添加这个注解,否则无法调用 
     * @param text 
     */  
    @JavascriptInterface  
    public void showToast(String text){  
         Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();  
    }  
}  
--------------------------------------------------------------------
/**
 * js中调用java方法
 */
android.showToast('toast');

Native会向webView全局作用域注入一个android的全局对象,该对象上有showToast的方法。

Android 4.2 之前注入对象的接口是 addJavascriptInterface ,但是由于安全原因慢慢不被使用(4.2以下版本,通过JS可以访问设备SD卡上面的任何内容,甚至是联系人信息,短信等。此为安全漏洞)。

现在,一般会通过拦截JS原生的window.confirmwindow.prompt方法,从而达到H5向Native通信的目的。 如,在 Webview 上添加 onJsConfirmonJsPrompt 监听(其实,监听window.console或者window.alert也是可以的,但是这两个方法在JS coding中比较常用,所以为了避免不必要的事件触发,一般我们不会选择在客户端劫持它们)。代码如下:

代码语言:javascript
复制
webview.setWebChromeClient(new WebChromeClient());

public class JSBridgeWebChromeClient extends WebChromeClient {
    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        String handledRet = parentEngine.bridge.promptOnJsPrompt(origin, message, defaultValue);
        ......
        return true;
    }
}

2. Native调用Web函数

反之,如果Native需要主动调用JS的方法,又该怎么做呢?

很简单,只要 H5 将 JS 方法暴露在 Window 上给 Native 调用即可。 是不是非常像客户端注册 Schema URI呢?

JS注册好函数,Native就可以调用了。

Android 4.4 以前,通过 loadUrl 方法,执行一段 JS 代码来实现(缺点是效率低,无法获得返回结果,且调用的时候会刷新 WebView):

代码语言:javascript
复制
/**
 * js中声明全局函数
 */
<script>
function log(msg) {
    console.log(msg);
}
</script>

--------------------------------------------------------------------
/**
 * 设置与Js交互的权限
 */
webSettings.setJavaScriptEnabled(true);

private final class JSInterface{  

    @JavascriptInterface  
    public void showJsLog(String text){  
        webView.loadUrl("javascript:log('"+text+"')");  
    } 
}  

4.4 以后,可以使用 evaluateJavascript 方法实现(效率更高,可获取返回值,调用时候不刷新WebView)

代码语言:javascript
复制
String text = "hello world";
webView.evaluateJavascript("javascript:log('"+text+"')", new ValueCallback<String>() {
  @Override
  public void onReceiveValue(String value){
   ......
  }
});

小结

Native和H5需要在接口设计上达成一致。只要API规定好,后续通信实现就不难了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Web调用Native能力
  • 2. Native调用Web函数
  • 小结
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档