diff --git a/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt b/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt new file mode 100644 index 00000000000..b3b325b7022 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactActivityDelegate.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.defaults + +import com.facebook.react.ReactActivity +import com.facebook.react.ReactActivityDelegate +import com.facebook.react.ReactRootView + +/** + * A utility class that allows you to simplify the setup of a [ReactActivityDelegate] for new apps + * in Open Source. + * + * Specifically, with this class you can simply control if Fabric and Concurrent Root are enabled + * for an Activity using the boolean flags in the constructor. + * + * @param fabricEnabled Whether Fabric should be enabled for the RootView of this Activity. + * @param concurrentRootEnabled Whether ConcurrentRoot (aka React 18) should be enabled for the + * RootView of this Activity. + */ +open class DefaultReactActivityDelegate( + activity: ReactActivity, + mainComponentName: String, + val fabricEnabled: Boolean = false, + val concurrentRootEnabled: Boolean = false +) : ReactActivityDelegate(activity, mainComponentName) { + + /** + * Override this method to enable Concurrent Root on the surface for this Activity. See: + * https://reactjs.org/blog/2022/03/29/react-v18.html + * + * This requires to be rendering on Fabric (i.e. on the New Architecture). + * + * @return Whether you want to enable Concurrent Root for this surface or not. + */ + override fun isConcurrentRootEnabled(): Boolean { + return concurrentRootEnabled + } + + override fun createRootView(): ReactRootView = + ReactRootView(getContext()).apply { setIsFabric(fabricEnabled) } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt b/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt index 841dea31549..81cd6f72697 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt +++ b/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt @@ -12,6 +12,14 @@ import com.facebook.react.ReactNativeHost import com.facebook.react.ReactPackageTurboModuleManagerDelegate import com.facebook.react.bridge.JSIModulePackage +/** + * A utility class that allows you to simplify the setup of a [ReactNativeHost] for new apps in Open + * Source. + * + * Specifically, for apps that are using the New Architecture, this Default class takes care of + * providing the default TurboModuleManagerDelegateBuilder and the default JSIModulePackage, + * provided the name of the dynamic library to load. + */ abstract class DefaultReactNativeHost protected constructor(application: Application) : ReactNativeHost(application) { @@ -32,7 +40,7 @@ abstract class DefaultReactNativeHost protected constructor(application: Applica /** * Returns the name of the dynamic library used by app on the New Architecture. This is generally - * "_appmodules" + * "_appmodules" or just "appmodules" * * If null, we will assume you're not using the New Architecture and will not attempt to load any * dynamic library at runtime. diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.java b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.java index ecdb54f8f15..143765e1984 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.java +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterActivity.java @@ -11,26 +11,24 @@ import android.os.Bundle; import androidx.annotation.Nullable; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; -import com.facebook.react.ReactRootView; +import com.facebook.react.defaults.DefaultReactActivityDelegate; public class RNTesterActivity extends ReactActivity { - public static class RNTesterActivityDelegate extends ReactActivityDelegate { + public static class RNTesterActivityDelegate extends DefaultReactActivityDelegate { private static final String PARAM_ROUTE = "route"; private Bundle mInitialProps = null; private final @Nullable ReactActivity mActivity; public RNTesterActivityDelegate(ReactActivity activity, String mainComponentName) { - super(activity, mainComponentName); + super( + activity, + mainComponentName, + true, // fabricEnabled + true // concurrentRootEnabled + ); this.mActivity = activity; } - @Override - protected ReactRootView createRootView() { - ReactRootView reactRootView = new ReactRootView(getContext()); - reactRootView.setIsFabric(true); - return reactRootView; - } - @Override protected void onCreate(Bundle savedInstanceState) { // Get remote param before calling super which uses it @@ -51,11 +49,6 @@ public class RNTesterActivity extends ReactActivity { protected Bundle getLaunchOptions() { return mInitialProps; } - - @Override - protected boolean isConcurrentRootEnabled() { - return true; - } } @Override diff --git a/template/android/app/src/main/java/com/helloworld/MainActivity.java b/template/android/app/src/main/java/com/helloworld/MainActivity.java index 405d80a8d97..d66f035735a 100644 --- a/template/android/app/src/main/java/com/helloworld/MainActivity.java +++ b/template/android/app/src/main/java/com/helloworld/MainActivity.java @@ -2,7 +2,7 @@ package com.helloworld; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; -import com.facebook.react.ReactRootView; +import com.facebook.react.defaults.DefaultReactActivityDelegate; public class MainActivity extends ReactActivity { @@ -16,33 +16,19 @@ public class MainActivity extends ReactActivity { } /** - * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and - * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer - * (Paper). + * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link + * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent Root (aka + * React 18) with two boolean flags. */ @Override protected ReactActivityDelegate createReactActivityDelegate() { - return new MainActivityDelegate(this, getMainComponentName()); - } - - public static class MainActivityDelegate extends ReactActivityDelegate { - public MainActivityDelegate(ReactActivity activity, String mainComponentName) { - super(activity, mainComponentName); - } - - @Override - protected ReactRootView createRootView() { - ReactRootView reactRootView = new ReactRootView(getContext()); - // If you opted-in for the New Architecture, we enable the Fabric Renderer. - reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); - return reactRootView; - } - - @Override - protected boolean isConcurrentRootEnabled() { - // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18). - // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html - return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; - } + return new DefaultReactActivityDelegate( + this, + getMainComponentName(), + // If you opted-in for the New Architecture, we enable the Fabric Renderer. + BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, // fabricEnabled + // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18). + BuildConfig.IS_NEW_ARCHITECTURE_ENABLED // concurrentRootEnabled + ); } }