Enabling in Android Library
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.
Once you have defined the JavaScript specs for your native modules as part of the prerequisites and followed 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. Configure Codegen in your Gradle Fileβ
You can now configure Codegen by specifying the following in the module-level build.gradle
file:
react {
libraryName = "samplelibrary"
codegenJavaPackageName = "com.example.samplelibrary"
root = rootProject.file("..")
jsRootDir = rootProject.file("../js/")
reactNativeDir = rootProject.file("../node_modules/react-native/")
codegenDir = rootProject.file("../node_modules/react-native-codegen/")
}
Please note that this setup requires you to have the React Gradle Plugin configured in the prerequisite step).
All the arguments are optional and provide default values, you might want to customize them to follow your setup.
libraryName
: A string that identifies your library. By default, the codegen will use a library name that is derived from the name of the module with aSpec
suffix. E.g. for:example:project
it will beExampleProjectSpec
.codegenJavaPackageName
: A string that represents the Java package your code should use. By default this will becom.facebook.fbreact.specs
but you might want to customize it.root
: Reference to the root of your project. By default is..
as Gradle is running inside the./android
folder.reactNativeDir
: Reference to thereact-native
package root. Usually located inside../node_modules/react-native
. For third-party NPM libraries that are installed innode_modules
, this will be../react-native
.jsRootDir
: Reference to the directory that contains the JavaScript specs for this library. By default is../js/
.codegenDir
: Reference to thereact-native-codegen
root. Usually located inside../node_modules/react-native-codegen
.
The generator will write its output inside the build folder, specifically inside the ./build/generated/source/codegen
folder.
2. Extend or implement the code-generated native interfacesβ
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.
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.
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
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.
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
β βββ 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
Extends the abstract class provided by the codegenβ
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).
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:
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;
}
}
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.