mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Introduce BaseReactPackage class (#40775)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/40775 In this diff I'm introducing the BaseReactPackage class to the public API of React Native Android. the goal is for this class to replace TurboReactPackage, which will be Deprecated in the New Architecture changelog: [internal] internal Reviewed By: christophpurrer Differential Revision: D50128456 fbshipit-source-id: a65e1eb0d81b94e442799226784f73f489eabb73
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7b7f128968
commit
7a31ecd665
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.ModuleHolder;
|
||||
import com.facebook.react.bridge.ModuleSpec;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.module.model.ReactModuleInfo;
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import javax.inject.Provider;
|
||||
|
||||
/** Abstract class that supports lazy loading of NativeModules by default. */
|
||||
public abstract class BaseReactPackage implements ReactPackage {
|
||||
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
||||
throw new UnsupportedOperationException(
|
||||
"createNativeModules method is not supported. Use getModule() method instead.");
|
||||
}
|
||||
|
||||
/**
|
||||
* The API needed for TurboModules. Given a module name, it returns an instance of {@link
|
||||
* NativeModule} for the name
|
||||
*
|
||||
* @param name name of the Native Module
|
||||
* @param reactContext {@link ReactApplicationContext} context for this
|
||||
*/
|
||||
@Override
|
||||
public abstract @Nullable NativeModule getModule(
|
||||
@NonNull String name, @NonNull ReactApplicationContext reactContext);
|
||||
|
||||
/**
|
||||
* This is a temporary method till we implement TurboModules. Once we implement TurboModules, we
|
||||
* will be able to directly call {@link BaseReactPackage#getModule(String,
|
||||
* ReactApplicationContext)} This method will be removed when TurboModule implementation is
|
||||
* complete
|
||||
*
|
||||
* @param reactContext
|
||||
* @return
|
||||
*/
|
||||
/** package */
|
||||
Iterable<ModuleHolder> getNativeModuleIterator(final ReactApplicationContext reactContext) {
|
||||
final Set<Map.Entry<String, ReactModuleInfo>> entrySet =
|
||||
getReactModuleInfoProvider().getReactModuleInfos().entrySet();
|
||||
final Iterator<Map.Entry<String, ReactModuleInfo>> entrySetIterator = entrySet.iterator();
|
||||
// This should ideally be an IteratorConvertor, but we don't have any internal library for it
|
||||
return () ->
|
||||
new Iterator<ModuleHolder>() {
|
||||
@Nullable Map.Entry<String, ReactModuleInfo> nextEntry = null;
|
||||
|
||||
private void findNext() {
|
||||
while (entrySetIterator.hasNext()) {
|
||||
Map.Entry<String, ReactModuleInfo> entry = entrySetIterator.next();
|
||||
ReactModuleInfo reactModuleInfo = entry.getValue();
|
||||
|
||||
// This Iterator is used to create the NativeModule registry. The NativeModule
|
||||
// registry must not have TurboModules. Therefore, if TurboModules are enabled, and
|
||||
// the current NativeModule is a TurboModule, we need to skip iterating over it.
|
||||
if (ReactFeatureFlags.useTurboModules && reactModuleInfo.isTurboModule()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nextEntry = entry;
|
||||
return;
|
||||
}
|
||||
nextEntry = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (nextEntry == null) {
|
||||
findNext();
|
||||
}
|
||||
return nextEntry != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleHolder next() {
|
||||
if (nextEntry == null) {
|
||||
findNext();
|
||||
}
|
||||
|
||||
if (nextEntry == null) {
|
||||
throw new NoSuchElementException("ModuleHolder not found");
|
||||
}
|
||||
|
||||
Map.Entry<String, ReactModuleInfo> entry = nextEntry;
|
||||
|
||||
// Advance iterator
|
||||
findNext();
|
||||
String name = entry.getKey();
|
||||
ReactModuleInfo reactModuleInfo = entry.getValue();
|
||||
return new ModuleHolder(reactModuleInfo, new ModuleHolderProvider(name, reactContext));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Cannot remove native modules from the list");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext react application context that can be used to create View Managers.
|
||||
* @return list of module specs that can create the View Managers.
|
||||
*/
|
||||
protected List<ModuleSpec> getViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
||||
List<ModuleSpec> viewManagerModuleSpecs = getViewManagers(reactContext);
|
||||
if (viewManagerModuleSpecs == null || viewManagerModuleSpecs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<ViewManager> viewManagers = new ArrayList<>();
|
||||
for (ModuleSpec moduleSpec : viewManagerModuleSpecs) {
|
||||
viewManagers.add((ViewManager) moduleSpec.getProvider().get());
|
||||
}
|
||||
return viewManagers;
|
||||
}
|
||||
|
||||
public abstract ReactModuleInfoProvider getReactModuleInfoProvider();
|
||||
|
||||
private class ModuleHolderProvider implements Provider<NativeModule> {
|
||||
|
||||
private final String mName;
|
||||
private final ReactApplicationContext mReactContext;
|
||||
|
||||
public ModuleHolderProvider(String name, ReactApplicationContext reactContext) {
|
||||
mName = name;
|
||||
mReactContext = reactContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable NativeModule get() {
|
||||
return getModule(mName, mReactContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-148
@@ -7,153 +7,8 @@
|
||||
|
||||
package com.facebook.react;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.bridge.ModuleHolder;
|
||||
import com.facebook.react.bridge.ModuleSpec;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.module.model.ReactModuleInfo;
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import javax.inject.Provider;
|
||||
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
|
||||
|
||||
/** This will eventually replace {@link LazyReactPackage} when TurboModules are finally done. */
|
||||
public abstract class TurboReactPackage implements ReactPackage {
|
||||
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
throw new UnsupportedOperationException(
|
||||
"createNativeModules method is not supported. Use getModule() method instead.");
|
||||
}
|
||||
|
||||
/**
|
||||
* The API needed for TurboModules. Given a module name, it returns an instance of {@link
|
||||
* NativeModule} for the name
|
||||
*
|
||||
* @param name name of the Native Module
|
||||
* @param reactContext {@link ReactApplicationContext} context for this
|
||||
*/
|
||||
@Override
|
||||
public abstract @Nullable NativeModule getModule(
|
||||
@NonNull String name, @NonNull ReactApplicationContext reactContext);
|
||||
|
||||
/**
|
||||
* This is a temporary method till we implement TurboModules. Once we implement TurboModules, we
|
||||
* will be able to directly call {@link TurboReactPackage#getModule(String,
|
||||
* ReactApplicationContext)} This method will be removed when TurboModule implementation is
|
||||
* complete
|
||||
*
|
||||
* @param reactContext
|
||||
* @return
|
||||
*/
|
||||
/** package */
|
||||
Iterable<ModuleHolder> getNativeModuleIterator(final ReactApplicationContext reactContext) {
|
||||
final Set<Map.Entry<String, ReactModuleInfo>> entrySet =
|
||||
getReactModuleInfoProvider().getReactModuleInfos().entrySet();
|
||||
final Iterator<Map.Entry<String, ReactModuleInfo>> entrySetIterator = entrySet.iterator();
|
||||
// This should ideally be an IteratorConvertor, but we don't have any internal library for it
|
||||
return () ->
|
||||
new Iterator<ModuleHolder>() {
|
||||
@Nullable Map.Entry<String, ReactModuleInfo> nextEntry = null;
|
||||
|
||||
private void findNext() {
|
||||
while (entrySetIterator.hasNext()) {
|
||||
Map.Entry<String, ReactModuleInfo> entry = entrySetIterator.next();
|
||||
ReactModuleInfo reactModuleInfo = entry.getValue();
|
||||
|
||||
// This Iterator is used to create the NativeModule registry. The NativeModule
|
||||
// registry must not have TurboModules. Therefore, if TurboModules are enabled, and
|
||||
// the current NativeModule is a TurboModule, we need to skip iterating over it.
|
||||
if (ReactFeatureFlags.useTurboModules && reactModuleInfo.isTurboModule()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nextEntry = entry;
|
||||
return;
|
||||
}
|
||||
nextEntry = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (nextEntry == null) {
|
||||
findNext();
|
||||
}
|
||||
return nextEntry != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleHolder next() {
|
||||
if (nextEntry == null) {
|
||||
findNext();
|
||||
}
|
||||
|
||||
if (nextEntry == null) {
|
||||
throw new NoSuchElementException("ModuleHolder not found");
|
||||
}
|
||||
|
||||
Map.Entry<String, ReactModuleInfo> entry = nextEntry;
|
||||
|
||||
// Advance iterator
|
||||
findNext();
|
||||
String name = entry.getKey();
|
||||
ReactModuleInfo reactModuleInfo = entry.getValue();
|
||||
return new ModuleHolder(reactModuleInfo, new ModuleHolderProvider(name, reactContext));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Cannot remove native modules from the list");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext react application context that can be used to create View Managers.
|
||||
* @return list of module specs that can create the View Managers.
|
||||
*/
|
||||
protected List<ModuleSpec> getViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
List<ModuleSpec> viewManagerModuleSpecs = getViewManagers(reactContext);
|
||||
if (viewManagerModuleSpecs == null || viewManagerModuleSpecs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<ViewManager> viewManagers = new ArrayList<>();
|
||||
for (ModuleSpec moduleSpec : viewManagerModuleSpecs) {
|
||||
viewManagers.add((ViewManager) moduleSpec.getProvider().get());
|
||||
}
|
||||
return viewManagers;
|
||||
}
|
||||
|
||||
public abstract ReactModuleInfoProvider getReactModuleInfoProvider();
|
||||
|
||||
private class ModuleHolderProvider implements Provider<NativeModule> {
|
||||
|
||||
private final String mName;
|
||||
private final ReactApplicationContext mReactContext;
|
||||
|
||||
public ModuleHolderProvider(String name, ReactApplicationContext reactContext) {
|
||||
mName = name;
|
||||
mReactContext = reactContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeModule get() {
|
||||
return getModule(mName, mReactContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@DeprecatedInNewArchitecture(message = "Use BaseReactPackage instead")
|
||||
public abstract class TurboReactPackage extends BaseReactPackage {}
|
||||
|
||||
Reference in New Issue
Block a user