# study-JockeyJS **Repository Path**: jacfang/study-JockeyJS ## Basic Information - **Project Name**: study-JockeyJS - **Description**: 本人做的很多 H5 项目,是通过 JockeyJS 与原生进行交互。最近被问到其实现原理,今天咱们就一起来盘一盘。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-09-30 - **Last Updated**: 2023-09-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 盘一盘 H5 与原生交互之 JockeyJS ### 本人做的很多 H5 项目,是通过 JockeyJS 与原生进行交互。最近被问到其实现原理,今天咱们就一起来盘一盘。理解不对的地方,还请各位大佬批评指正。 ## 一、JockeyJS 简介 #### 如果你问 GPT,H5 与原生交互常见的方法,可能会得到这些:JSBridge、URL Scheme、JavaScript Core、WebView 提供的接口、消息通信机制等。而 JockeyJS 属于 JSBridge 的一种实现,它提供了 API 和通信机制,使得 H5 和原生可以进行双向通信,实现功能调用和数据传递。 ## 二、JockeyJS 的使用 #### 接下来本人就从 H5 的视角分别讲下 H5 调用原生接口和原生调用 H5 接口的过程: ### (一)H5 调用原生接口 1. 原生提供接口:比如原生注册了一个名为 getAppInfo 的事件,供 H5 获取原生的语言、主题等设置。 ``` Jockey.on("getAppInfo", new JockeyHandler() {...}) ``` 2. H5 引入 JockeyJS:这会生成一个全局对象 Jockey 3. H5 调用 getAppInfo:Jockey 中 send 方法接收三个参数:第一个参数是事件名,这里是 getAppInfo,第二个参数是 H5 要传递给原生的参数,该事件无需传参,所以是 {},第三个参数是完成处理后的回调函数,这里打印原生返回的结果。 ``` Jockey.send("getAppInfo", {}, res => { console.log('getAppInfo res', res); }); ``` 4. H5 传递消息给原生:第3步最终会生成一个 jockey://xxx 格式的 url,并导航到该 url。url 的 scheme 为 jockey,会被拦截,并交给原生处理。 ``` window.location.href = "jockey://event/0?xxxgetAppInfoxxx"; ``` 5. 原生执行相应操作:上述 url 解析出来是个 event,事件名是 getAppInfo,所以执行第1步原生注册的 getAppInfo 事件 JockeyHandler 里的逻辑。 6. 原生将结果返回给 H5:原生处理完后,将结果转换为 "javascript:Jockey.triggerCallback("%d")" 的形式传递到 WebView 中执行,调用 Jockey 对象的 triggerCallback 方法,即执行第3步 H5 调用 getAppInfo 时写的回调函数里的逻辑。 7. H5 处理结果:这里是打印原生返回的结果 ``` { lang: "zh-hans", theme: 2, ... } ``` ### (二)原生调用 H5 接口 1. H5 引入 JockeyJS:这会生成一个全局对象 Jockey 2. H5 提供接口:比如 H5 注册一个名为 statusChanged 的事件,监听原生登录态的变化。 ``` Jockey.on("statusChanged", payload => { console.log('statusChanged payload', payload); }) ``` 3. 当原生登录态发生变化时,调用 statusChanged ``` jockey.send("statusChanged", webView, new JockeyCallback() {...}) ``` 4. 原生传递消息给 H5:原生将请求参数转换为 "javascript:Jockey.trigger("%s", %d, %s)" 的形式传递到 WebView 中执行,trigger 的事件是 statusChanged。 5. H5 执行相应操作:这里是打印原生传递过来的参数 ``` { type: "3" } ``` 6. H5 将结果返回给原生:Jockey 最终生成一个 jockey://xxx 格式的 url,并导航到该 url。url 的 scheme 为 jockey,会被拦截,并交给原生处理。 ``` window.location.href = "jockey://callback/0?xxx"; ``` 7. 原生处理结果:上述 url 解析出来是个 callback,原生就执行第3步调用 statusChanged 时写的 JockeyCallback 里的逻辑。 ## 三、总结 通过 JockeyJS,H5 和原生都可以注册事件供对方调用,并相互传递数据。H5 向原生传递消息是通过导航到 "jockey://xxx",原生拦截 "jockey" scheme。原生向 H5 传递消息是通过在 WebView 执行 "javascript:Jockey.xxx" 调用 Jockey 相应的方法。 以上是本人从 H5 的视角分别讲了 H5 调用原生接口和原生调用 H5 接口的过程,如有不正确的地方,欢迎各位大佬批评指正。同时,也欢迎推荐原生视角的讲解,谢谢!