在 Android 库中启用
本文档仍为 experimental,详细信息可能会随着我们的迭代而发生变化。 欢迎在此页面分享你对 工作组内部讨论 的反馈。
英This documentation is still experimental and details are subject to changes as we iterate. Feel free to share your feedback on the discussion inside the working group for this page.
而且,它还包含几个 手动步骤。 请注意,一旦新架构稳定,这将不代表最终的开发者体验。 我们正在开发工具、模板和库,以帮助你快速开始使用新架构,而无需完成整个设置。
英Moreover, it contains several manual steps. Please note that this won't be representative of the final developer experience once the New Architecture is stable. We're working on tools, templates and libraries to help you get started fast on the New Architecture, without having to go through the whole setup.
一旦你为你的原生模块定义了 JavaScript 规范作为 prerequisites 的一部分,设置了 Codegen 的配置,并遵循 Android/Gradle 设置,你现在就可以将你的库迁移到新的架构了。 你可以按照以下步骤来完成此操作。
英Once you have defined the JavaScript specs for your native modules as part of the prerequisites, set up the configuration of the Codegen, and follow the Android/Gradle setup, you are now ready to migrate your library to the new architecture. Here are the steps you can follow to accomplish this.
1. 扩展或实现代码生成的原生接口
原生模块或组件的 JavaScript 规范将用于为每个受支持的平台(即 Android 和 iOS)生成原生接口代码。 这些原生接口文件将生成 当构建依赖于你的库的 React Native 应用时。
英The JavaScript spec for your native module or component will be used to generate native interface code for each supported platform (i.e., Android and iOS). These native interface files will be generated when a React Native application that depends on your library is built.
虽然这生成了原生接口代码 不会作为你的库的一部分发货,但你确实需要确保你的 Java/Kotlin 代码符合这些原生接口文件提供的协议。
英While this generated native interface code will not ship as part of your library, you do need to make sure your Java/Kotlin code conforms to the protocols provided by these native interface files.
你可以调用 generateCodegenArtifactsFromSchema
Gradle 任务来生成库的原生接口代码,以便使用它们 作为参考:
英You can invoke the generateCodegenArtifactsFromSchema
Gradle task to generate your library’s native interface code in order to use them as a reference:
./gradlew generateCodegenArtifactsFromSchema
输出的文件可以在 build/generated/source/codegen
和 不应该犯 中找到,但你需要参考它们来确定需要对原生模块进行哪些更改,以便它们为每个生成的接口提供实现。
英The files that are output can be found inside build/generated/source/codegen
and should not be committed, but you’ll need to refer to them to determine what changes you need to make to your native modules in order for them to provide an implementation for each generated interface.
名为 NativeAwesomeManager
的模块的 Codegen 输出将如下所示:
英The output of the Codegen for a module called NativeAwesomeManager
will look like this:
app/build/generated/source/codegen
├── java
│ └── com
│ └── example
│ └── samplelibrary
│ └── NativeAwesomeManagerSpec.java
├── jni
│ ├── Android.mk
│ ├── CMakeLists.txt
│ ├── react
│ │ └── renderer
│ │ └── components
│ │ └── samplelibrary
│ │ ├── ComponentDescriptors.h
│ │ ├── EventEmitters.cpp
│ │ ├── EventEmitters.h
│ │ ├── Props.cpp
│ │ ├── Props.h
│ │ ├── ShadowNodes.cpp
│ │ └── ShadowNodes.h
│ ├── samplelibrary-generated.cpp
│ └── samplelibrary.h
└── schema.json
扩展 Codegen 提供的抽象类
更新你的原生模块或组件,以确保其 扩展抽象类 是根据你的 JavaScript 规范生成的代码(即上一个示例中的 NativeAwesomeManagerSpec.java
文件)。
英Update your native module or component to ensure it extends the abstract class that has been code-generated from your JavaScript specs (i.e., the NativeAwesomeManagerSpec.java
file from the previous example).
按照上一节中阐述的示例,你的库可能会导入 NativeAwesomeManagerSpec
,实现相关的原生接口及其必要的方法:
英Following the example set forth in the previous section, your library might import NativeAwesomeManagerSpec
, implement the relevant native interface and the necessary methods for it:
- Java
- Kotlin
import androidx.annotation.NonNull;
import com.example.samplelibrary.NativeAwesomeManagerSpec;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
public class NativeAwesomeManager extends NativeAwesomeManagerSpec {
public static final String NAME = "NativeAwesomeManager";
public NativeAwesomeManager(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public void getString(String id, Promise promise) {
// Implement this method
}
@NonNull
@Override
public String getName() {
return NAME;
}
}
import com.example.samplelibrary.NativeAwesomeManagerSpec
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
class NativeAwesomeManager(reactContext: ReactApplicationContext) :
NativeAwesomeManagerSpec(reactContext) {
override fun getString(id: String, promise: Promise) {
// Implement this method
}
override fun getName() = NAME
companion object {
val NAME = "NativeAwesomeManager"
}
}
请注意,你现在扩展的 生成的抽象类(本例中为 MyAwesomeSpec
)本身就是扩展 ReactContextBaseJavaModule
。 因此,你不应该访问你之前使用的任何方法/字段(例如,ReactApplicationContext
等)。 此外,生成的类现在还将为你实现 TurboModule
接口。
英Please note that the generated abstract class that you’re now extending (MyAwesomeSpec
in this example) is itself extending ReactContextBaseJavaModule
. Therefore you should not use access to any of the method/fields you were previously using (e.g., the ReactApplicationContext
and so on). Moreover, the generated class will now also implement the TurboModule
interface for you.