The new architecture that FB has been promoting for years is probably familiar to many people. The major improvement is the shift from asynchronous Bridge mode to direct mode. Reduce message communication latency and improve performance. The key is TurboModule.

Open TurboModule

TurboModule has no documentation when enabled. Only the native module is interspersed with snippets. An example will take developers to react-native code. This means that there has been official support for this mechanism, but not official announcement. However, due to the high complexity, it is necessary to have an understanding of the RepO code structure of React-Native. A better example is react-native animated.

The project is modest in size and less complex in structure. It’s good for analogical research and implementation.

Implement NativeModule

As before, ReactContextBaseJavaModule inheritance. For details, please refer to here. Implement the getName method.

Add ReactModule annotations

This is one of the differences from the previous approach.

The code now looks like this:


@ReactModule(name = ReanimatedModule.NAME)
public class ReanimatedModule extends ReactContextBaseJavaModule {

  public static final String NAME = "ReanimatedModule";

  public ReanimatedModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @Override
  public String getName(a) {
    returnNAME; }}Copy the code

Finally add ReactMethod

  @ReactMethod
  public void animateNextTransition(int tag, ReadableMap config) {
    mTransitionManager.animateNextTransition(tag, config);
  }
Copy the code

The native module part is done. Let’s see how to register this native module.

Register native modules

That’s the point. In the previous section, the only difference from developing native modules was the addition of an @reactModule annotation. This part is a little bit different, according to the website is a little bit more than before.

1. Add an inheritanceTurboReactPackageThe class of

public class ReanimatedPackage extends TurboReactPackage {}
Copy the code

2. ImplementgetModulemethods

  @Override
  public NativeModule getModule(String name, ReactApplicationContext reactContext) {
    if (name.equals(ReanimatedModule.NAME)) {
      return new ReanimatedModule(reactContext);
    }

    return null;
  }
Copy the code

3. The implementationgetReactModuleInfoProvider

  @Override
  public ReactModuleInfoProvider getReactModuleInfoProvider(a) {
    Class<? extends NativeModule>[] moduleList =
        new Class[] {
          ReanimatedModule.class, ReanimatedUIManager.class,
        };

    final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>();
    for (Class<? extends NativeModule> moduleClass : moduleList) {
      ReactModule reactModule = moduleClass.getAnnotation(ReactModule.class);

      reactModuleInfoMap.put(
          reactModule.name(),
          new ReactModuleInfo(		/ / *
              reactModule.name(),
              moduleClass.getName(),
              true,
              reactModule.needsEagerInit(),
              reactModule.hasConstants(),
              reactModule.isCxxModule(),
              TurboModule.class.isAssignableFrom(moduleClass)));
    }

    return new ReactModuleInfoProvider() {
      @Override
      public Map<String, ReactModuleInfo> getReactModuleInfos(a) {
        returnreactModuleInfoMap; }}; }Copy the code

The name of the Module still plays an important role here. It is used to put before (JS) after (native). It is needed to find the Module between multiple native modules registered in the native. So the first argument to initialize ReactModuleInfo is the module name.

The third parameter canOverrideExistingModule, generally when you still have not TurboModules best is set to false.

NeedEgerInit set to false if you want this module to load lazily. Unless you want your app to initialize your module when it initializes. This will increase the boot time.

HasConstant set to true if your module hasConstant exports.

IsCxxModule is true if all code isC code.

IsTurboModule Set this parameter to true if the current module is a TurboModule. Not false. This parameter is here because ReactModuleInfo does not only serve Turbo Modules.

4. Register the Package in Application

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport(a) {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages(a) {
      return Arrays.<ReactPackage>asList(
		  // ...
          new ReanimatedPackage(), / / *
          // ...); }}Copy the code

Register the ReanimatedPackage() object in the method getPackages().

conclusion

FB’s optimization of React Native architecture mainly focuses on optimizing performance. In specific development activities, the turbo Module is used to optimize the new architecture. Speed up startup, make animation smoother, and make scrolling through long lists smoother.