mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
rewrite RNTesterApplication to kotlin (#39557)
Summary: Rewrite `RNTesterApplication` to Kotlin as per [Help us Kotlin-ify React Native tests - Round 2](https://github.com/facebook/react-native/issues/38825) ## Changelog: [ANDROID] [CHANGED] - Rewrite RNTesterApplication to Kotlin, add AnnotationTarget property. Pull Request resolved: https://github.com/facebook/react-native/pull/39557 Test Plan: `yarn && yarn android` ✅ The only thing I'm kinda unsure of is whether `AnnotationTarget.PROPERTY` should be added, but it didn't let me annotate `reactHostInterface` without that and didn't compile. <img width="637" alt="image" src="https://github.com/facebook/react-native/assets/33528752/8bc84870-f3f2-4a46-b076-6ee7e38bd735"> cortinico mdvacca Reviewed By: cortinico Differential Revision: D49598401 Pulled By: mdvacca fbshipit-source-id: 105ae0c13c93dae0eeb2b6fa9040f03f42d2736a
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@
|
||||
package com.facebook.react.common.annotations
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
|
||||
@RequiresOptIn(
|
||||
level = RequiresOptIn.Level.ERROR,
|
||||
message = "This API is experimental and is likely to change or to be removed in the future")
|
||||
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
/*
|
||||
* 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.uiapp;
|
||||
|
||||
import android.app.Application;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.facebook.fbreact.specs.SampleLegacyModule;
|
||||
import com.facebook.fbreact.specs.SampleTurboModule;
|
||||
import com.facebook.react.JSEngineResolutionAlgorithm;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.TurboReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
|
||||
import com.facebook.react.common.assets.ReactFontManager;
|
||||
import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.defaults.DefaultComponentsRegistry;
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.react.flipper.ReactNativeFlipper;
|
||||
import com.facebook.react.interfaces.ReactHost;
|
||||
import com.facebook.react.interfaces.exceptionmanager.ReactJsExceptionHandler;
|
||||
import com.facebook.react.module.model.ReactModuleInfo;
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
import com.facebook.react.runtime.ReactHostImpl;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import com.facebook.react.uiapp.component.MyLegacyViewManager;
|
||||
import com.facebook.react.uiapp.component.MyNativeViewManager;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class RNTesterApplication extends Application implements ReactApplication {
|
||||
|
||||
private ReactHostImpl mReactHost;
|
||||
|
||||
private final ReactNativeHost mReactNativeHost =
|
||||
new DefaultReactNativeHost(this) {
|
||||
@Override
|
||||
public String getJSMainModuleName() {
|
||||
return "js/RNTesterApp.android";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBundleAssetName() {
|
||||
return "RNTesterApp.android.bundle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(),
|
||||
new TurboReactPackage() {
|
||||
public NativeModule getModule(
|
||||
final String name, final ReactApplicationContext reactContext) {
|
||||
if (!ReactFeatureFlags.useTurboModules) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (SampleTurboModule.NAME.equals(name)) {
|
||||
return new SampleTurboModule(reactContext);
|
||||
}
|
||||
|
||||
if (SampleLegacyModule.NAME.equals(name)) {
|
||||
return new SampleLegacyModule(reactContext);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Note: Specialized annotation processor for @ReactModule isn't configured in OSS
|
||||
// yet. For now, hardcode this information, though it's not necessary for most
|
||||
// modules.
|
||||
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
||||
return new ReactModuleInfoProvider() {
|
||||
public Map<String, ReactModuleInfo> getReactModuleInfos() {
|
||||
final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
|
||||
if (ReactFeatureFlags.useTurboModules) {
|
||||
moduleInfos.put(
|
||||
SampleTurboModule.NAME,
|
||||
new ReactModuleInfo(
|
||||
SampleTurboModule.NAME,
|
||||
"SampleTurboModule",
|
||||
false, // canOverrideExistingModule
|
||||
false, // needsEagerInit
|
||||
false, // isCxxModule
|
||||
true // isTurboModule
|
||||
));
|
||||
|
||||
moduleInfos.put(
|
||||
SampleLegacyModule.NAME,
|
||||
new ReactModuleInfo(
|
||||
SampleLegacyModule.NAME,
|
||||
"SampleLegacyModule",
|
||||
false, // canOverrideExistingModule
|
||||
false, // needsEagerInit
|
||||
false, // isCxxModule
|
||||
false // isTurboModule
|
||||
));
|
||||
}
|
||||
return moduleInfos;
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
new ReactPackage() {
|
||||
@NonNull
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(
|
||||
@NonNull ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(
|
||||
@NonNull ReactApplicationContext reactContext) {
|
||||
List<ViewManager> viewManagers = new ArrayList<>();
|
||||
viewManagers.add(new MyNativeViewManager());
|
||||
viewManagers.add(new MyLegacyViewManager(reactContext));
|
||||
return viewManagers;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNewArchEnabled() {
|
||||
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean isHermesEnabled() {
|
||||
return BuildConfig.IS_HERMES_ENABLED_IN_FLAVOR;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
ReactFontManager.getInstance().addCustomFont(this, "Rubik", R.font.rubik);
|
||||
super.onCreate();
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
DefaultNewArchitectureEntryPoint.load();
|
||||
}
|
||||
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
||||
// TODO: initialize Flipper for Bridgeless
|
||||
} else {
|
||||
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
||||
throw new RuntimeException("Should not use ReactNativeHost when Bridgeless enabled");
|
||||
}
|
||||
return mReactNativeHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
@UnstableReactNativeAPI
|
||||
public ReactHost getReactHost() {
|
||||
if (mReactHost == null) {
|
||||
// Create an instance of ReactHost to manager the instance of ReactInstance,
|
||||
// which is similar to how we use ReactNativeHost to manager instance of ReactInstanceManager
|
||||
RNTesterReactHostDelegate reactHostDelegate =
|
||||
new RNTesterReactHostDelegate(getApplicationContext());
|
||||
RNTesterReactJsExceptionHandler reactJsExceptionHandler =
|
||||
new RNTesterReactJsExceptionHandler();
|
||||
|
||||
ComponentFactory componentFactory = new ComponentFactory();
|
||||
DefaultComponentsRegistry.register(componentFactory);
|
||||
mReactHost =
|
||||
new ReactHostImpl(
|
||||
this.getApplicationContext(),
|
||||
reactHostDelegate,
|
||||
componentFactory,
|
||||
true,
|
||||
reactJsExceptionHandler,
|
||||
true);
|
||||
if (BuildConfig.IS_HERMES_ENABLED_IN_FLAVOR) {
|
||||
mReactHost.setJSEngineResolutionAlgorithm(JSEngineResolutionAlgorithm.HERMES);
|
||||
} else {
|
||||
mReactHost.setJSEngineResolutionAlgorithm(JSEngineResolutionAlgorithm.JSC);
|
||||
}
|
||||
reactHostDelegate.setReactHost(mReactHost);
|
||||
}
|
||||
return mReactHost;
|
||||
}
|
||||
|
||||
@UnstableReactNativeAPI
|
||||
public static class RNTesterReactJsExceptionHandler implements ReactJsExceptionHandler {
|
||||
public void reportJsException(ReadableMapBuffer errorMap) {}
|
||||
}
|
||||
};
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.uiapp
|
||||
|
||||
import android.app.Application
|
||||
import com.facebook.fbreact.specs.SampleLegacyModule
|
||||
import com.facebook.fbreact.specs.SampleTurboModule
|
||||
import com.facebook.react.JSEngineResolutionAlgorithm
|
||||
import com.facebook.react.ReactApplication
|
||||
import com.facebook.react.ReactNativeHost
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.TurboReactPackage
|
||||
import com.facebook.react.bridge.NativeModule
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
||||
import com.facebook.react.common.assets.ReactFontManager
|
||||
import com.facebook.react.common.mapbuffer.ReadableMapBuffer
|
||||
import com.facebook.react.config.ReactFeatureFlags
|
||||
import com.facebook.react.defaults.DefaultComponentsRegistry.Companion.register
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||
import com.facebook.react.fabric.ComponentFactory
|
||||
import com.facebook.react.flipper.ReactNativeFlipper.initializeFlipper
|
||||
import com.facebook.react.interfaces.ReactHost
|
||||
import com.facebook.react.interfaces.exceptionmanager.ReactJsExceptionHandler
|
||||
import com.facebook.react.module.model.ReactModuleInfo
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider
|
||||
import com.facebook.react.runtime.ReactHostImpl
|
||||
import com.facebook.react.shell.MainReactPackage
|
||||
import com.facebook.react.uiapp.component.MyLegacyViewManager
|
||||
import com.facebook.react.uiapp.component.MyNativeViewManager
|
||||
import com.facebook.react.uimanager.ViewManager
|
||||
import com.facebook.soloader.SoLoader
|
||||
|
||||
class RNTesterApplication : Application(), ReactApplication {
|
||||
override val reactNativeHost: ReactNativeHost by lazy {
|
||||
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
||||
throw RuntimeException("Should not use ReactNativeHost when Bridgeless enabled")
|
||||
}
|
||||
object : DefaultReactNativeHost(this) {
|
||||
public override fun getJSMainModuleName(): String = "js/RNTesterApp.android"
|
||||
|
||||
public override fun getBundleAssetName(): String = "RNTesterApp.android.bundle"
|
||||
|
||||
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
|
||||
|
||||
public override fun getPackages(): List<ReactPackage> {
|
||||
return listOf(
|
||||
MainReactPackage(),
|
||||
object : TurboReactPackage() {
|
||||
override fun getModule(
|
||||
name: String,
|
||||
reactContext: ReactApplicationContext
|
||||
): NativeModule? {
|
||||
if (!ReactFeatureFlags.useTurboModules) {
|
||||
return null
|
||||
}
|
||||
if (SampleTurboModule.NAME == name) {
|
||||
return SampleTurboModule(reactContext)
|
||||
}
|
||||
if (SampleLegacyModule.NAME == name) {
|
||||
return SampleLegacyModule(reactContext)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// Note: Specialized annotation processor for @ReactModule isn't configured in OSS
|
||||
// yet. For now, hardcode this information, though it's not necessary for most
|
||||
// modules.
|
||||
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider =
|
||||
ReactModuleInfoProvider {
|
||||
if (ReactFeatureFlags.useTurboModules) {
|
||||
mapOf(
|
||||
SampleTurboModule.NAME to
|
||||
ReactModuleInfo(
|
||||
SampleTurboModule.NAME,
|
||||
"SampleTurboModule",
|
||||
false, // canOverrideExistingModule
|
||||
false, // needsEagerInit
|
||||
false, // isCxxModule
|
||||
true // isTurboModule
|
||||
),
|
||||
SampleLegacyModule.NAME to
|
||||
ReactModuleInfo(
|
||||
SampleLegacyModule.NAME,
|
||||
"SampleLegacyModule",
|
||||
false, // canOverrideExistingModule
|
||||
false, // needsEagerInit
|
||||
false, // isCxxModule
|
||||
false // isTurboModule
|
||||
))
|
||||
} else {
|
||||
emptyMap()
|
||||
}
|
||||
}
|
||||
},
|
||||
object : ReactPackage {
|
||||
override fun createNativeModules(
|
||||
reactContext: ReactApplicationContext
|
||||
): List<NativeModule> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun createViewManagers(
|
||||
reactContext: ReactApplicationContext
|
||||
): List<ViewManager<*, *>> =
|
||||
listOf(MyNativeViewManager(), MyLegacyViewManager(reactContext))
|
||||
})
|
||||
}
|
||||
|
||||
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
||||
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED_IN_FLAVOR
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
ReactFontManager.getInstance().addCustomFont(this, "Rubik", R.font.rubik)
|
||||
super.onCreate()
|
||||
SoLoader.init(this, /* native exopackage */ false)
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
load()
|
||||
}
|
||||
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
||||
// TODO: initialize Flipper for Bridgeless
|
||||
} else {
|
||||
initializeFlipper(this, reactNativeHost.reactInstanceManager)
|
||||
}
|
||||
}
|
||||
|
||||
@UnstableReactNativeAPI
|
||||
override val reactHost: ReactHost by lazy {
|
||||
// Create an instance of ReactHost to manager the instance of ReactInstance,
|
||||
// which is similar to how we use ReactNativeHost to manager instance of ReactInstanceManager
|
||||
val reactHostDelegate = RNTesterReactHostDelegate(applicationContext)
|
||||
val reactJsExceptionHandler = RNTesterReactJsExceptionHandler()
|
||||
val componentFactory = ComponentFactory()
|
||||
register(componentFactory)
|
||||
ReactHostImpl(
|
||||
this.applicationContext,
|
||||
reactHostDelegate,
|
||||
componentFactory,
|
||||
true,
|
||||
reactJsExceptionHandler,
|
||||
true)
|
||||
.apply {
|
||||
jsEngineResolutionAlgorithm =
|
||||
if (BuildConfig.IS_HERMES_ENABLED_IN_FLAVOR) {
|
||||
JSEngineResolutionAlgorithm.HERMES
|
||||
} else {
|
||||
JSEngineResolutionAlgorithm.JSC
|
||||
}
|
||||
reactHostDelegate.reactHost = this
|
||||
}
|
||||
}
|
||||
|
||||
@UnstableReactNativeAPI
|
||||
class RNTesterReactJsExceptionHandler : ReactJsExceptionHandler {
|
||||
override fun reportJsException(errorMap: ReadableMapBuffer?) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user