JsbBridgeWrapper 基于原生反射机制的事件处理

    是封装在 JsbBridge 之上的事件派发机制,相对于 JsbBridge 而言它更方便易用。开发者不需要手动去实现一套消息收发机制就可以进行多事件的触发。但它不具有多线程稳定性或者是 100% 安全。如果遇到复杂需求场景,仍然建议自己实现对应的事件派发。

    如同之前的 jsb-bridge,它的接口被声明在 jsb.d.ts 文件中。

    OnNativeEventListener 是实际注册的 回调(callback) 类型,为了防止因为类型不匹配导致的低级错误,因此使用显示声明该类型。addNativeEventListener 中的第二个参数即为传入的 callback。当然也可以使用匿名函数代替。代码示例如下:

    1. // 当事件 “A” 触发时, ‘this.A’ 方法会被调用
    2. jsb.jsbBridgeWrapper.addNativeEventListener("A", (usr: string) => {
    3. this.A(usr);
    4. });

    addNativeEventListener

    增加一个事件监听。

    参数:

    • eventName: string 事件名称
    • listener: OnNativeEventListener 回调函数

    dispatchEventToNative

    派发一个事件到原生层。

    参数:

    • eventName: string 事件名称
    • arg?: string 参数

    removeNativeEventListener

    参数:

    • eventName: string 事件名称
    • listener: OnNativeEventListener 要删除的回调函数

    removeAllListeners

    删除所有的事件监听。

    JsbBridgeWrapper 在不同平台有不同的实现,开发者可以通过下列方式进行查看:

    • 安卓可查看 :

      1. // In JAVA
      2. public class JsbBridgeWrapper {
      3. public interface OnScriptEventListener {
      4. void onScriptEvent(String arg);
      5. }
      6. /**
      7. * Add a listener to specified event, if the event does not exist, the wrapper will create one. Concurrent listener will be ignored
      8. */
      9. public void addScriptEventListener(String eventName, OnScriptEventListener listener);
      10. * Remove listener for specified event, concurrent event will be deleted. Return false only if the event does not exist
      11. */
      12. public boolean removeScriptEventListener(String eventName, OnScriptEventListener listener);
      13. /**
      14. * Remove all listener for event specified.
      15. */
      16. public void removeAllListenersForEvent(String eventName);
      17. /**
      18. * Remove all event registered. Use it carefully!
      19. */
      20. public void removeAllListeners() {
      21. }
      22. /**
      23. * Dispatch the event with argument, the event should be registered in javascript, or other script language in future.
      24. */
      25. public void dispatchEventToScript(String eventName, String arg);
      26. /**
      27. */
      28. public void dispatchEventToScript(String eventName);
      29. }
    • Huawei HarmonyOS 也可以通过 JsbBridgeWrapper.java 查看其实现方式。

    常见的需求如数据存放在原生层,当需要将数据取至 JS 层时,可以通过 JsbBridgeWrapper 实现。

    下文通过一个示例说明,如何通过原生的回调结果改变 label 内容,当原生层的事件被触发时,将目标文本字符回传给 JS 层。

    当 JS 层的 changeLabelContent 事件被触发时,标签的内容会变成对应的字符串组合。接下来需要处理原生的事件注册。

    • 在 Objective-C 端使用下列代码:

      1. // Objective-C
      2. JsbBridgeWrapper* m = [JsbBridgeWrapper sharedInstance];
      3. OnScriptEventListener requestLabelContent = ^void(NSString* arg){
      4. JsbBridgeWrapper* m = [JsbBridgeWrapper sharedInstance];
      5. [m dispatchEventToScript:@"changeLabelContent" arg:@"Charlotte"];
      6. };
      7. [m addScriptEventListener:@"requestLabelContent" listener:requestLabelContent];
    • 在 JAVA 端使用如下代码:

      注意:JAVA 可以通过匿名函数的方法来实现 interface 的需求,此处写法简化。

    这里原生的返回值被设置成固定字符,但开发者可以根据需求实现异步亦或是延后的字符赋值,时机并非固定。简而言之,当原生收到 requestLabelContent 的事件时,原生将会反过来触发 JS 层的 changeLabelContent 的事件,并将字符作为事件触发的传参。

    最后一步,我们在场景中添加一个按钮和对应的事件。

    1. // 按钮点击事件 SAY HELLO
    2. public sayHelloBtn() {
    3. }

    最终的效果和 JsbBridge 的测试例效果相同。点击 按钮,第一行的内容会改变为打过招呼的信息,否则即为失败。

    使用 JsbBridgeWrapper 模块时,开发者不需要自己去维护多余的机制,只需要关心是否正确注册和取消注册即可。