mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Provide defaults for TurboModuleManagerDelegate and JSIModulePackage (#34418)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/34418 This is an attempt to relax the need of specifying a custom `TurboModuleManagerDelegate` and a `JSIModulePackage` in new apps for New Architecture. Users can just specify the name of the dynamic library to load and they'll default to use the `DefaultTurboModuleManagerDelegate` and `DefaultJSIModulePackage`. Users will still have to provide a C++ implementation for it for the time being, but this at least removes one extra file that we requested them to create and maintain. If we're fine with this approach, I'll replicate it inside the default template. Changelog: [Android] [Added] - Provide defaults for TurboModuleManagerDelegate and JSIModulePackage Reviewed By: cipolleschi Differential Revision: D38701180 fbshipit-source-id: eec302c5789990700eb75353d97751358ca6799f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d35aab45b9
commit
9a2eb9089f
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.jni.HybridData
|
||||
import com.facebook.proguard.annotations.DoNotStrip
|
||||
import com.facebook.react.fabric.ComponentFactory
|
||||
|
||||
/**
|
||||
* A utility class that provides users a ComponentRegistry they can customize with a C++
|
||||
* implementation of its native methods.
|
||||
*
|
||||
* Please note that you need to provide a native implementation for the method initHybrid for this
|
||||
* class, making sure the Java Descriptor is:
|
||||
* Lcom/facebook/react/defaults/DefaultComponentsRegistry;
|
||||
*/
|
||||
@DoNotStrip
|
||||
class DefaultComponentsRegistry
|
||||
@DoNotStrip
|
||||
private constructor(componentFactory: ComponentFactory) {
|
||||
|
||||
@DoNotStrip private val hybridData: HybridData = initHybrid(componentFactory)
|
||||
|
||||
@DoNotStrip private external fun initHybrid(componentFactory: ComponentFactory): HybridData
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@DoNotStrip
|
||||
fun register(componentFactory: ComponentFactory) = DefaultComponentsRegistry(componentFactory)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.ReactNativeHost
|
||||
import com.facebook.react.bridge.JSIModulePackage
|
||||
import com.facebook.react.bridge.JSIModuleProvider
|
||||
import com.facebook.react.bridge.JSIModuleSpec
|
||||
import com.facebook.react.bridge.JSIModuleType
|
||||
import com.facebook.react.bridge.JavaScriptContextHolder
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.UIManager
|
||||
import com.facebook.react.fabric.ComponentFactory
|
||||
import com.facebook.react.fabric.FabricJSIModuleProvider
|
||||
import com.facebook.react.fabric.ReactNativeConfig
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry
|
||||
|
||||
/**
|
||||
* A utility class that allows users to create a JSIModulePackage to use Fabric. This essentially
|
||||
* allows users to just provide C++ implementation for the methods of `DefaultComponentsRegistry`
|
||||
* without providing all the extra machinery for the New Architecture.
|
||||
*
|
||||
* `ReactNativeHost` is required to create Fabric's ViewManagers.
|
||||
*/
|
||||
class DefaultJSIModulePackage(private val reactNativeHost: ReactNativeHost) : JSIModulePackage {
|
||||
|
||||
override fun getJSIModules(
|
||||
reactApplicationContext: ReactApplicationContext,
|
||||
jsContext: JavaScriptContextHolder
|
||||
): List<JSIModuleSpec<UIManager>> =
|
||||
listOf<JSIModuleSpec<UIManager>>(JSIModuleForFabric(reactApplicationContext, reactNativeHost))
|
||||
|
||||
private inner class JSIModuleForFabric(
|
||||
private val reactApplicationContext: ReactApplicationContext,
|
||||
private val reactNativeHost: ReactNativeHost
|
||||
) : JSIModuleSpec<UIManager> {
|
||||
override fun getJSIModuleType(): JSIModuleType = JSIModuleType.UIManager
|
||||
override fun getJSIModuleProvider(): JSIModuleProvider<UIManager> {
|
||||
val componentFactory = ComponentFactory()
|
||||
|
||||
DefaultComponentsRegistry.register(componentFactory)
|
||||
|
||||
val viewManagers =
|
||||
reactNativeHost.getReactInstanceManager().getOrCreateViewManagers(reactApplicationContext)
|
||||
val viewManagerRegistry = ViewManagerRegistry(viewManagers)
|
||||
return FabricJSIModuleProvider(
|
||||
reactApplicationContext,
|
||||
componentFactory,
|
||||
ReactNativeConfig.DEFAULT_CONFIG,
|
||||
viewManagerRegistry)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 android.app.Application
|
||||
import com.facebook.react.ReactNativeHost
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate
|
||||
import com.facebook.react.bridge.JSIModulePackage
|
||||
|
||||
abstract class DefaultReactNativeHost protected constructor(application: Application) :
|
||||
ReactNativeHost(application) {
|
||||
|
||||
protected override fun getReactPackageTurboModuleManagerDelegateBuilder():
|
||||
ReactPackageTurboModuleManagerDelegate.Builder? =
|
||||
dynamicLibraryName?.let {
|
||||
// If the user provided a dynamic library name, we assume they want to load
|
||||
// the default ReactPackageTurboModuleManagerDelegate
|
||||
DefaultTurboModuleManagerDelegate.Builder(it)
|
||||
}
|
||||
|
||||
protected override fun getJSIModulePackage(): JSIModulePackage? =
|
||||
dynamicLibraryName?.let {
|
||||
// If the user provided a dynamic library name, we assume they want to load
|
||||
// the default JSIModulePackage
|
||||
DefaultJSIModulePackage(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the dynamic library used by app on the New Architecture. This is generally
|
||||
* "<applicationname>_appmodules"
|
||||
*
|
||||
* If null, we will assume you're not using the New Architecture and will not attempt to load any
|
||||
* dynamic library at runtime.
|
||||
*
|
||||
* If set, we'll take care of create a TurboModuleManagerDelegate that will load the library you
|
||||
* specified.
|
||||
*/
|
||||
protected open val dynamicLibraryName: String?
|
||||
get() = null
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.jni.HybridData
|
||||
import com.facebook.proguard.annotations.DoNotStrip
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.ReactPackageTurboModuleManagerDelegate
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.soloader.SoLoader
|
||||
|
||||
/**
|
||||
* A utility class that allows you to provide a TurboModuleManagerDelegate by just specifying the
|
||||
* name of the dynamic library. This class will take care of loading the dynamic library for you on
|
||||
* your behalf.
|
||||
*
|
||||
* Please note that you need to provide a native implementation for the method initHybrid for this
|
||||
* class, making sure the Java Descriptor is:
|
||||
* Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate;
|
||||
*/
|
||||
class DefaultTurboModuleManagerDelegate
|
||||
private constructor(
|
||||
dynamicLibraryName: String,
|
||||
context: ReactApplicationContext,
|
||||
packages: List<ReactPackage>
|
||||
) : ReactPackageTurboModuleManagerDelegate(context, packages) {
|
||||
|
||||
@DoNotStrip protected override external fun initHybrid(): HybridData?
|
||||
|
||||
init {
|
||||
maybeLoadOtherSoLibraries(dynamicLibraryName)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun maybeLoadOtherSoLibraries(dynamicLibraryName: String) {
|
||||
// Prevents issues with initializer interruptions.
|
||||
if (!isSoLibraryLoaded) {
|
||||
SoLoader.loadLibrary(dynamicLibraryName)
|
||||
isSoLibraryLoaded = true
|
||||
}
|
||||
}
|
||||
|
||||
class Builder(private val dynamicLibraryName: String) :
|
||||
ReactPackageTurboModuleManagerDelegate.Builder() {
|
||||
protected override fun build(context: ReactApplicationContext, packages: List<ReactPackage>) =
|
||||
DefaultTurboModuleManagerDelegate(dynamicLibraryName, context, packages)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Volatile private var isSoLibraryLoaded = false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user