Hybrid App 应用开发中 5 个必备知识点复习 下

简介: Hybrid App 应用开发中 5 个必备知识点复习 下

四、什么是 JS Bridge,它的作用是什么

参考文章:《JSBridge的原理》

4.1 JS Bridge 介绍

JSBridge 简单来讲,主要是 给 JavaScript 提供调用 Native 功能的接口,让混合开发中的前端部分可以方便地使用地址位置、摄像头甚至支付等 Native 功能。

JSBridge 就像其名称中的 “Bridge” 的意义一样,是 Native 和非 Native 之间的桥梁,它的核心是 构建 Native 和非 Native 间消息通信的通道,而且是 双向通信的通道

JSBridge 另一个叫法及大家熟知的 Hybrid app 技术。

所谓 双向通信的通道:

  • JS 向 Native 发送消息 :

调用相关功能、通知 Native 当前 JS 的相关状态等。

  • Native 向 JS 发送消息 :

回溯调用结果、消息推送、通知 JS 当前 Native 的状态等。

4.2. JS Bridge 实现原理

参考文章:《Hybrid APP基础篇(四)->JSBridge的原理》

Android 和 iOS 的 JSBridge 实现方式:

4.2.1 基本流程

  • H5 页面通过某种方式触发一个 url scheme
  • Native 捕获到 url scheme,并进行分析和处理;
  • Native 调用 H5 的 JSBridge 对象传递回调;

原生的 WebView/UIWebView 控件已经能够和 JS 实现数据通信了,那为什么还要 JSBridge呢?

其实使用JSBridge有很多方面的考虑:

  • Android4.2以下,addJavascriptInterface 方式有安全漏掉。
  • iOS7以下,JS 无法调用 Native。
  • url scheme 交互方式是一套现有的成熟方案,可以完美兼容各种版本,对以前老版本技术的兼容。
4.2.1 实现流程(Android 为例)

  1. 拟定协议,参考 http 制定的协议为:jsbridge://className:port/methodName?jsonObj
className   // Android端实现暴露给前端的类名
port        // Android返回结果给前端的端口
methodName  // 前端需要调用的函数
jsonObj     // 前端给Android传递的参数
  1. 新建 HTML 文件命名为 index.html, 编写一个 button 绑定 click 事件;
<button onclick="JSBridge.call(
    'bridge',
    'showToast',
    {'msg':'Hello JSBridge'},
    function(res){
        alert(JSON.stringify(res))
    }
)">
    测试showToast 
</button>
  1. 新建 JS 文件命名为 JSBridge.js, 第2步中的 JSBridge.call 即为调用 JSBridge.js 中的 call 方法,后面带了四个参数;
call: function (obj, method, params, callback) {
    console.log(obj+" "+method+" "+params+" "+callback);
    var port = Util.getPort();
    console.log(port);
    this.callbacks[port] = callback;
    var uri=Util.getUri(obj,method,params,port);
    console.log(uri);
    window.prompt(uri, "");
},

JSBridge.js 中的 call 方法,最后调用了 window.prompt 方法,这个方法就是触发 Android 端 webChromeClient 的回调函数用的。

  1. window.prompt 触发了 WebChromeClient(这个需要使用函数WebView.setWebChromeClient( new WebChromeClietn() )进行设定);

类中的如下回调 onJsPrompt。这时就完成了前端与 Android端 的通信了,因为前端的信息都顺利通过这个函数传递给Android了。

@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
    result.confirm(JSBridge.callJava(view,message));
    return true;
}
  1. Android 中会定义一个类 JSBridge.java 来管理暴露给前端使用的函数;

这个类有两个功能:

  • 暴露给前端的函数的动态注册功能。
  • 解析前端信息,调用了 Android 端对应的函数,这个示例中是:showToast 函数。

解析前端的信息,获取前端调用的函数名:

Uri uri = Uri.parse(uriString);
className = uri.getHost();
param = uri.getQuery();
port = uri.getPort() + "";
String path = uri.getPath();
HashMap< String, Method> methodHashMap = exposedMethod.get(className);
Method method = methodHashMap.get(methodName);

通过获取的函数名,这里是 showToast ,调用 Android 端的 showToast 函数。

method.invoke(null,webView,new JSONObject(param),new Callback(webView,port));
  1. 定义类 BridgeImpl.java 来具体的实现暴露给前端的所有函数。这里的 showToast 函数如下:
public static void showToast(WebView webView, JSONObject param, final JSBridge.Callback callback){
    String message = param.optString("msg");
    Toast.makeText(webView.getContext(),message,Toast.LENGTH_LONG).show();
    if(null != callback){
        try {
            JSONObject object = new JSONObject();
            object.put("key","value");
            object.put("key1","vaule1");
            callback.apply(getJSONObject(0,"ok",object));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}


五、请列举 Android 与 iOS 平台下 JS Bridge 的实现方式

这边代码比较多,我使用图片来展示,大家可以放大来查看。

5.1 Android 实现方式

5.1.1 Android 调用 JS 的 2 种方式
  1. 通过WebViewloadUrl():

JS 代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用。

Web 端代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>前端代码</title>
        <script>
        // Android需要调用的方法
        function callJS(){
            alert("Android调用了JS的callJS方法");
        }
    </script>
   </head>
</html>

Android 端代码:

  1. 通过WebViewevaluateJavascript()
// 只需要将第一种方法的loadUrl()换成下面该方法即可
mWebView.evaluateJavascript(
    "javascript:callJS()", 
    new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            //此处为 js 返回的结果
        }
    });
}
5.1.2 JS 调用 Android 的 3 种方式
  1. 通过 WebViewaddJavascriptInterface() 进行对象映射:

Android 映射:

// 继承自Object类
public class AndroidtoJs extends Object {
    // 定义JS需要调用的方法
    // 被JS调用的方法必须加入@JavascriptInterface注解
    @JavascriptInterface
    public void hello(String msg) {
        System.out.println("JS调用了Android的hello方法");
    }
}

Web:

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <title>前端代码</title>  
      <script>
         function callAndroid(){
        // 由于对象映射,所以调用test对象等于调用Android映射的对象
            test.hello("js调用了android中的hello方法");
         }
      </script>
   </head>
   <body>
      //点击按钮则调用callAndroid函数
      <button type="button" id="button1" "callAndroid()"></button>
   </body>
</html>

Android 端:

  1. 通过 WebViewClientshouldOverrideUrlLoading () 方法回调拦截 url

Web 端:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>前端代码</title>
        <script>
            function callAndroid(){
                /*约定的url协议为:js://webview?arg1=111&arg2=222*/
                document.location = "js://webview?arg1=111&arg2=222";
            }
        </script>
    </head>
    <!-- 点击按钮则调用callAndroid()方法  -->
    <body>
        <button type="button" id="button1" 
            onclick="callAndroid()"
        >点击调用Android代码</button>
    </body>
</html>

Android 端:

  1. 通过 WebChromeClient 的方法回调拦截JS对话框方法:

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

Web 端:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>前端代码</title>
        <script>
            function clickprompt(){
            // 调用prompt()
            var result=prompt("js://demo?arg1=111&arg2=222");
                alert("demo " + result);
            }
        </script>
    </head>
    <!-- 点击按钮则调用clickprompt()  -->
    <body>
        <button type="button" id="button1" 
            onclick="clickprompt()"
        >点击调用Android代码</button>
    </body>
</html>

Android 端:

5.2 iOS 实现方式

5.2.1 JS 调用 iOS 的 2 种方式
  1. 使用 XMLHttpRequest 发起请求的方式:

Web 端:

XMLHttpRequest bridge:

JS 端使用 XMLHttpRequest 发起了一个请求:execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);,请求的地址是 /!gap_exec;并把请求的数据放在了请求的 header 里面,见这句代码:execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages());

而在 Objective-C 端使用一个 NSURLProtocol 的子类来检查每个请求,如果地址是 /!gap_exec 的话,则认为是 Cordova 通信的请求,直接拦截,拦截后就可以通过分析请求的数据,分发到不同的插件类(CDVPlugin 类的子类)的方法中:

Cordova 中优先使用这种方式, Cordova.js 中的注释有提及为什么优先使用 XMLHttpRequest 的方式,及为什么保留第二种 iframe bridge 的通信方式:

// XHR mode does not work on iOS 4.2, so default to IFRAME_NAV for such devices.
// XHR mode’s main advantage is working around a bug in -webkit-scroll, which
// doesn’t exist in 4.X devices anyways123

iframe bridge:

在 JS 端创建一个透明的 iframe,设置这个 ifamesrc 为自定义的协议,而 ifame src 更改时,UIWebView 会先回调其 delegatewebView:shouldStartLoadWithRequest:navigationType: 方法,关键代码如下:

  1. 通过设置透明的 iframesrc 属性:
5.2.2 iOS 调用 JS 的方式

UIWebView 有一个这样的方法 stringByEvaluatingJavaScriptFromString:,这个方法可以让一个 UIWebView 对象执行一段 JS 代码,这样就可以达到 Objective-C 跟 JS 通信的效果,在 Cordova 的代码中多处用到了这个方法,其中最重要的两处如下:

  1. 获取 JS 的请求数据:

  1. 把 JS 请求的结果返回给 JS 端:

结语

对于初入混合应用开发的小伙伴,这些会有点难度,但是好好理解下那几张流程图,再理一理思路,相信会有帮助😁

给大家加加油~~

目录
相关文章
|
11天前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
141 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
8天前
|
人工智能 搜索推荐 数据挖掘
原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
原生鸿蒙版小艺APP成功接入DeepSeek-R1,为HarmonyOS用户带来更智能高效的交互体验。通过此次升级,用户在编程、学习和工作中的问题可迅速获得专业解答。同时,此举为HarmonyOS应用开发者提供了新的技术参考,激发了更多创新应用场景的开发,助力打造差异化竞争优势,推动HarmonyOS生态繁荣发展。
135 68
原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
|
27天前
|
Dart 前端开发
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
116 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
4天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
23 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
11天前
|
机器学习/深度学习 存储 人工智能
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
MNN-LLM App 是阿里巴巴基于 MNN-LLM 框架开发的 Android 应用,支持多模态交互、多种主流模型选择、离线运行及性能优化。
884 14
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
|
16天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
121 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
24天前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
75 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
14天前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
37 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
前端开发 Java 开发工具
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
81 18
【03】完整flutter的APP打包流程-以apk设置图标-包名-签名-APP名-打包流程为例—-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈 章节内容【03】
|
29天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
79 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程

热门文章

最新文章

  • 1
    MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
  • 2
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
  • 4
    【Azure App Service】基于Linux创建的App Service是否可以主动升级内置的Nginx版本呢?
  • 5
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 6
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 7
    【Azure Function】Function App出现System.IO.FileNotFoundException异常
  • 8
    【Azure Logic App】使用MySQL 新增行触发器遇见错误 :“Unknown column 'created_at' in 'order clause'”
  • 9
    阿里云APP备案流程图以及备案所需材料整理,跟着教程一步步操作
  • 10
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 1
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    34
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 3
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 4
    【Azure Function】Function App门户上的Test/Run返回错误:Failed to fetch
    31
  • 5
    陪玩APP推送配置:陪玩系统手机锁屏收不到推送?可能是这些原因!解决方案来了!
    34
  • 6
    小游戏源码开发之可跨app软件对接是如何设计和开发的
    33
  • 7
    原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
    135
  • 8
    PiliPala:开源项目真香,B站用户狂喜!这个开源APP竟能自定义主题+去广告?PiliPala隐藏功能大揭秘
    60
  • 9
    语音app系统软件源码开发搭建新手启蒙篇
    44
  • 10
    MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
    884