React-Native系列Android——通信数据模型分析

无论是计算机领域还是日常生活中,我们所言的通信,其核心都是数据信息的交换,而数据模型的优劣对通信效率有着决定性的作用。

React-Native项目中,Javascript语言与Native两种语言(JavaOC等)间存在着大量的数据交换,也就是所谓的通信。众所周知,移动APP对性能的要求无比苛刻,如果通信数据模型设计地不合理,很可能引起多线程下的数据安全问题,以及应用性能问题,比如内存泄漏,UI绘制缓慢等。

前面几篇博客我们详细分析过React-Native的通信机制,主要有两个方向: Java->Bridge->JavascriptJavascript->Bridge->Java。所以,真正的数据交换其实发生在JavaBridgeJavascriptBridge两个环节。

JavascriptBridge间的数据通信是借助于Webkit使用Json完成,简单实用,水到渠成,不多分析。而JavaBridge间的数据通信相比之下就复杂多了,作为真正运行在设备上的程序语言,这恰恰是决定整个通信过程效率高低最核心的一环,也是本篇博客研究的内容。

JavaAndroid应用程序的本地开发语言,而Bridge是使用C++开发的动态链接库,由Java语言通过JNI的方式调用。JavaBridge间的数据通信,实质是JavaC++两种程序语言间的数据传输,而传递的方向又分为两个场景:Java传输数据给C++C++ 传输数据给Java


我们先来看第一种场景。

Java主动向Javascript通信,主要是通过ReactBridge.java类的callFunction方法,将需要调用的组件(moduleId)、功能(methodId)、数据(arguments)三者传递到Bridge。

package com.facebook.react.bridge;

public class ReactBridge extends Countable {
   

  static final String REACT_NATIVE_LIB = "reactnativejni";

  static {
    SoLoader.loadLibrary(REACT_NATIVE_LIB);
  }

  ...

  public native void callFunction(int moduleId, int methodId, NativeArray arguments);

  ...

}

我们可以看到,传输的数据类型是NativeArray,来瞧下具体的代码,位于com.facebook.react.bridge包下:

public abstract class NativeArray {
   
  static {
    SoLoader.loadLibrary(ReactBridge.REACT_NATIVE_LIB);
  }

  protected NativeArray(HybridData hybridData) {
    mHybridData = hybridData;
  }

  @Override
  public native String toString();

  @DoNotStrip
  private HybridData mHybridData;
}

NativeArray是一个抽象类,其中,只有一个HybridData类型成员变量,由其构造方法赋值初始化。

NativeArray还有一个名为ReadableNativeArray的直接子类,和一个名为WritableNativeArray的间接子类,后者是继承于前者。顾名思义,一个是用于读数据,一个是用于写数据。

JavaBridge传输数据,自然就是写数据了,所以我们先来看WritableNativeArray

package com.facebook.react.bridge;

public class WritableNativeArray extends ReadableNativeArray implements WritableArray {
   

  static {
    SoLoader.loadLibrary(ReactBridge.REACT_NATIVE_LIB);
  }

  public WritableNativeArray() {
    super(initHybrid());
  }

  @Override
  public native void pushNull();
  @Override
  public native void pushBoolean(boolean value);
  @Override
  public native void pushDouble(double value);
  @Override
  public native void pushInt(int value);
  @Override
  public native void pushString(String value);

  @Override
  public void pushArray(WritableArray array) {
    Assertions.assertCondition(
        array == null || array instanceof WritableNativeArray, "Illegal type provided");
    pushNativeArray((WritableNativeArray) array);
  }

  @Override
  public void pushMap(WritableMap map) {
    Assertions.assertCondition(
        map == null || map instanceof WritableNativeMap, "Illegal type provided");
    pushNativeMap((WritableNativeMap) map);
  }

  private native static HybridData initHybrid();
  private native void pushNativeArray(WritableNativeArray array);
  private native void pushNativeMap(WritableNativeMap map);
}

里面有7个写数据的native方法,涵盖了intstringarraymap等不同的数据类型和结构。

还有一个名为initHybrid()native方法,用于创建HybridData类的实例,然后通过构造方法给其超父类NativeArraymHybridData成员变量赋值,具体作用后面来分析,先略过。

接下来,我们来验证一下WritableNativeArray是否是真正传输给Bridge的数据类型。

Java调用Javascript组件,都是由名为JavaScriptModuleInvocationHandler的动态代理类统一拦截处理的吗?来回顾一下代码,位于com.facebook.react.bridge.JavaScriptModuleRegistry.java

  private static class JavaScriptModuleInvocationHandler implements InvocationHandler {
   

    private final CatalystInstanceImpl mCatalystInstance;
    private final JavaScriptModuleRegistration mModul
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值