React Native填坑之旅--开启TurboModule(Android)

测试不通过
• 阅读 4536

FB宣传了N多年的新架构估计很多人都熟知了。最主要的改进就是从所有通讯都通过异步Bridge的方式转为直接通讯的方式。减少消息通讯延迟,提高性能。这其中最关键的就是TurboModule

开启TurboModule

开启TurboModule没有文档。只有就的原生module里夹杂着只言片语。一个例子就把开发同学带到react-native的代码里了。这说明官方早就支持这个机制了,只是没正式官宣。但是复杂度太高,还需要对react-native的repo代码结构有了解。还有一个更好的例子react-native-animated

这个项目大小适中,结构也不那么复杂。很适合类比研究,实现。

实现NativeModule

和之前一样,继承ReactContextBaseJavaModule。具体可以参考这里实现getName方法

添加ReactModule注解

这是和之前的方式不同的一点。

现在代码看起来是这样的:


@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() {
    return NAME;
  }
}

最后添加ReactMethod

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

原生模块这部分就完事儿了。下面看看如何注册这个原生模块。

注册原生模块

这个部分就是重点了。上一节,和之前开发原生模块唯一不同的点就是多了一个@ReactModule的注解。这一部分不同的地方就有点多,按照官网的说法是比之前稍微多了几步。

1. 添加一个继承了TurboReactPackage的类

public class ReanimatedPackage extends TurboReactPackage {}

2. 实现getModule方法

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

    return null;
  }

3. 实现getReactModuleInfoProvider

  @Override
  public ReactModuleInfoProvider getReactModuleInfoProvider() {
    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() {
        return reactModuleInfoMap;
      }
    };
  }

在这里Module的名字依然扮演了重要的角色,它是把前(JS)后(原生),在原生里注册的多个原生模块之间如何找到那个模块都需要这模块名称。所以在初始化ReactModuleInfo的时候第一个参数就是模块名称。

第三个参数canOverrideExistingModule,一般在你还有不是TurboModules的时候最好是设置为false

needEgerInit如果你需要这个模块懒加载的话设置为false。除非你要你的app在初始化的时候也一起初始化你的模块。这样会增加开机时间。

hasConstant如果你的模块有常量导出的话设置为true

isCxxModuletrue如果代码都是C代码。

isTurboModule如果当前模块是turbo module设置为true。不是为false。这个参数在这里是因为ReactModuleInfo不是只服务于turbo module的。

4. 在Application里注册Package

public class MainApplication extends Application implements ReactApplication {

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

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

在方法getPackages()里注册ReanimatedPackage()对象。

总结

FB对React Native架构的优化主要集中在优化性能。在具体的开发活动里,主要就是利用turbo module来使用新架构的优化。加快开机速度,让动画更流畅,让长列表滚动更加流畅。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
3年前
EventBus源码分析
一、        EventBus简介1.1、EventBusEventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化Android事件传递,这里的事件可以理解为消息,本文中统一称为事件。事件传递既可用于Android四大组件间通讯,也可以用户异步线程和主线程间通讯等等。传统的事件
Stella981 Stella981
3年前
AsyncTask的用法
AsyncTask,即异步任务,是Android给我们提供的一个处理异步任务的类.通过此类,可以实现UI线程和后台线程进行通讯,后台线程执行异步任务,并把结果返回给UI线程..为什么需要使用异步任务?我们知道,Android中只有UI线程,也就是主线程才能进行对UI的更新操作,而其他线程是不能直接操作UI的.这样的好处是保证了UI的稳定性和准确性,避
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Wesley13 Wesley13
3年前
IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列
1、引言消息是互联网信息的一种表现形式,是人利用计算机进行信息传递的有效载体,比如即时通讯网坛友最熟悉的即时通讯消息就是其具体的表现形式之一。消息从发送者到接收者的典型传递方式有两种:1)一种我们可以称为即时消息:即消息从一端发出后(消息发送者)立即就可以达到另一端(消息接收者),这种方式的具体实现就是平时最常见的IM聊天消息;
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
测试不通过
测试不通过
Lv1
回鞭指长安,西日落秦关。
文章
4
粉丝
0
获赞
0