Hybrid混合开发 和 JSBridge 的使用

书接上篇:移动端研发技术的进化历程 

针对纯原生开发主要面临动态化和开发成本两个问题,诞生了一些跨平台的动态化框架。业界一直都在努力寻找好的解决方案,而时至今日,已经有很多跨平台框架(“跨平台”特指 Android 和 iOS 两个平台),根据其原理,主要分为三类:

  • H5 + 原生(Cordova、Ionic、微信小程序)
  • JavaScript 开发 + 原生渲染 (React Native、Weex)
  • 自绘UI + 原生 (Qt for mobile、Flutter)

Hybrid混合开发

将 App 中需要动态变动的内容通过HTML5(简称 H5)来实现,通过原生的网页加载控件WebView 来加载。

H5 + 原生 的开发模式称为混合开发 ,App我们称之为混合应用或 Hybrid App ,如果一个应用的大多数功能都是 H5 实现的话,我们称其为 Web App。

优点:
混合开发中,H5 部分是可以随时改变而不用发版,动态化需求能满足;同时,由于 H5 代码只需要一次开发,就能同时在 Android 和 iOS 两个平台运行,这也可以减小开发成本。

缺点:
混合开发中,H5代码是运行在原生WebView 中,其 JavaScript 依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统、不能使用蓝牙等。且性能体验不佳,对于复杂用户界面或动画,WebView 有时会不堪重任。

在此,我们需要提一下小程序,目前国内各家公司小程序应用层的开发技术栈是 Web 技术栈,而底层渲染方式基本都是 WebView 和原生相结合的方式。


 Android 平台使用JSBridge

JSBridge 简单来讲,主要是 给 JavaScript 提供调用 Native 功能的接口,让混合开发中的『前端部分』可以方便地使用平台的地图定位、相册、摄像头等 Native 功能。
实际上,JSBridge 就像其名称中的『Bridge』的意义一样,是 Native 和非 Native 之间的桥梁,它的核心是 构建 Native 和非 Native 间消息通信的通道,而且是“双向通信”的通道。


原生调用Web方法

WebView调用loadUrl(),会重新刷新页面,无返回结果。

// 调用js中的函数:jsFun(msg)
webView.loadUrl("javascript:jsFun('" + msg + "')"); 

evaluateJavascript(),不会使页面刷新,有返回结果。

mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        //此处为 js 返回的结果
    }
  });
} 

Web调用原生的方法

WebView通过调用addJavascriptInterface()方法(推荐)
// 参数1:Android的本地对象、 参数2:JS的对象
mWebView.addJavascriptInterface(new MyJSInterface(),"androidJsInterface");
private static class MyJSInterface{
      public void showMessage(String msg){
        Toast.makeText(WebViewActivity.this, "成功"+ msg, Toast.LENGTH_LONG).show();
      }
}

原理: 通过对象映射的方式将Android中的本地对象和JS中的对象进行关联,从而实现JS调用Android的对象和方法。

漏洞:因为addJavascriptInterface绑定了一个Java对象实例,根据Java的反射机制,就可以获得更多方法,甚至间接获得更多的实例对象。Android 4.2版本之后,Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击。

@JavascriptInterface
public void showMessage(String msg)...

通过WebViewClient.shouldOverrideUrlLoading拦截url,分析意图执行相应操作。

需要与前端人员沟通如何定义Url,此url可以作为内部交互的意图,当网页加载后有一个url,可以进行判断后执行native的逻辑处理。

webView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
        //a.比如,点击网页按钮关闭Activity。这里url字符串查找是否包含“finish_app”关键字。
        if(url.contains("finish_app")) {//退出Activity
            finish();
        }

        //b.比如,这个是从WebView页面跳转另外一个Activity页面。
        if (url.contains("MyLuckLog")){//会员页面
            startActivity(new Intent(WebViewActivity.this,NewActivity.class));
        }
        return true;
      }
});

例如,网易云音乐的app 里面的积分商城就是使用这种方式实现H5与native交互。微信和网易一样通过拦截url分析意图来执行相应的操作的。

缺陷:因为url是可以伪造的,存在一定的风险。例如,微信自己会在native代码里验证他的appid,所以一定程度上可以避免大部分的攻击。


通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调,拦截JS对话框alert()、confirm()、prompt() 消息。

Android通过 WebChromeClient 的onJsAlert()onJsConfirm()onJsPrompt()方法回调分别拦截JS对话框 。得到他们的消息内容,然后分析意图执行相应操作。

同样,也需要和前端开发人员做好约定好消息内容的意图。推荐prompt方法拦截意图。

  • 因为onJsPrompt调用较少,而onJsAlert、onJsConfirm可能调用频繁。
  • 只有prompt()可以返回任意类型的值,而alert()没有返回值、confirm()只能返回两种状态(确定 / 取消)两个值。
  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾阳Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值