diff --git a/docs/new-architecture-app-modules-android.md b/docs/new-architecture-app-modules-android.md index 23a2a129e5a..4891fd9690e 100644 --- a/docs/new-architecture-app-modules-android.md +++ b/docs/new-architecture-app-modules-android.md @@ -4,6 +4,8 @@ title: Enabling TurboModule on Android --- import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; +import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import constants from '@site/core/TabsConstants'; @@ -135,11 +137,14 @@ You can now verify that everything works correctly by running your android app: yarn react-native run-android ``` -## 2. Java - Provide a `ReactPackageTurboModuleManagerDelegate` +## 2. Java/Kotlin - Provide a `ReactPackageTurboModuleManagerDelegate` Now is time to actually use the TurboModule. First, we will need to create a `ReactPackageTurboModuleManagerDelegate` subclass, like the following: + + + ```java package com.awesomeproject; @@ -179,6 +184,52 @@ public class MyApplicationTurboModuleManagerDelegate extends ReactPackageTurboMo } ``` + + + + +```kotlin +package com.awesomeproject + +import com.facebook.jni.HybridData +import com.facebook.react.ReactPackage +import com.facebook.react.ReactPackageTurboModuleManagerDelegate +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.soloader.SoLoader + +class MyApplicationTurboModuleManagerDelegate +protected constructor( + reactApplicationContext: ReactApplicationContext, + packages: List +) : ReactPackageTurboModuleManagerDelegate(reactApplicationContext, packages) { + + override protected external fun initHybrid(): HybridData? + class Builder : ReactPackageTurboModuleManagerDelegate.Builder() { + override protected fun build( + context: ReactApplicationContext, + packages: List + ): MyApplicationTurboModuleManagerDelegate = + MyApplicationTurboModuleManagerDelegate(context, packages) + } + + @Synchronized + override protected fun maybeLoadOtherSoLibraries() { + // Prevents issues with initializer interruptions. + if (!isSoLibraryLoaded) { + SoLoader.loadLibrary("myapplication_appmodules") + isSoLibraryLoaded = true + } + } + + companion object { + @Volatile private var isSoLibraryLoaded = false + } +} +``` + + + + Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `LOCAL_MODULE :=` inside the `Android.mk` file you created before. This class will then be responsible of loading the TurboModules and will take care of loading the native library build with the NDK at runtime. @@ -189,6 +240,9 @@ Then, you can provide the class you created to your `ReactNativeHost`. You can l Once you located it, you need to add the `getReactPackageTurboModuleManagerDelegateBuilder` method as from the snippet below: + + + ```java public class MyApplication extends Application implements ReactApplication { @@ -212,10 +266,43 @@ public class MyApplication extends Application implements ReactApplication { } ``` + + + +```kotlin +class MyApplication : Application(), ReactApplication { + private val reactNativeHost: ReactNativeHost = + object : ReactNativeHost(this) { + + override fun getUseDeveloperSupport(): Boolean { + /* ... */ + } + + override fun getPackages(): List? { + /* ... */ + } + + override fun getJSMainModuleName(): String? { + /* ... */ + } + + @NonNull + override fun getReactPackageTurboModuleManagerDelegateBuilder() = + ReactPackageTurboModuleManagerDelegate.Builder() + } +} +``` + + + + ## 4. Extend the `getPackages()` from your `ReactNativeHost` to use the TurboModule Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created TurboModule. Update the method to include the following: + + + ```java public class MyApplication extends Application implements ReactApplication { @@ -272,8 +359,72 @@ public class MyApplication extends Application implements ReactApplication { return new MyApplicationTurboModuleManagerDelegate.Builder(); } }; +} +``` + + + + +```kotlin +class MyApplication() : Application(), ReactApplication { + + private val reactNativeHost: ReactNativeHost = + object : ReactNativeHost(this) { + override fun getUseDeveloperSupport(): Boolean { + /* ... */ + } + + override protected fun getPackages(): List? { + val packages: MutableList = PackageList(this).getPackages() + + // Add those lines + packages.add( + object : TurboReactPackage() { + @Nullable + override fun getModule( + name: String, + reactContext: ReactApplicationContext? + ): NativeModule? = + if ((name == NativeAwesomeManager.NAME)) { + NativeAwesomeManager(reactContext) + } else { + null + } + + override fun getReactModuleInfoProvider() = + mutableMapOf( + NativeAwesomeManager.NAME, + ReactModuleInfo( + NativeAwesomeManager.NAME, + "NativeAwesomeManager", + false, // canOverrideExistingModule + false, // needsEagerInit + true, // hasConstants + false, // isCxxModule + true // isTurboModule + ) + ) + } + ) + return packages + } + + override protected fun getJSMainModuleName(): String? { + /* ... */ + } + + @NonNull + override protected fun getReactPackageTurboModuleManagerDelegateBuilder(): + ReactPackageTurboModuleManagerDelegate.Builder? { + return Builder() + } + } +} ``` + + + ## 5. C++ Provide a native implementation for the methods in your `*TurboModuleDelegate` class If you take a closer look at the class `MyApplicationTurboModuleManagerDelegate` that you created before, you will notice how some of the methods are `native`. @@ -422,6 +573,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { Now you can finally enable the `TurboModule `support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. + + + ```java public class MyApplication extends Application implements ReactApplication { @@ -430,8 +584,26 @@ public class MyApplication extends Application implements ReactApplication { ReactFeatureFlags.useTurboModules = true; //... } +} +``` + + + + + +```kotlin +class MyApplication : Application(), ReactApplication { + + override fun onCreate() { + ReactFeatureFlags.useTurboModules = true + // ... + } +} ``` + + + It’s now time to run again your Android app to verify that everything works correctly: ```bash