mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Support custom DevSupportManager (#31841)
Summary: to open possibilities for some DX enhancement, the pr introduces `DevSupportManagerFactory` customization. applications could implement a different DevSupportManager in ReactNativeHost. ## Changelog [Internal] [Added] - Support custom DevSupportManager Pull Request resolved: https://github.com/facebook/react-native/pull/31841 Test Plan: this pr just introduces some new interfaces and should not break existing functionalities. Reviewed By: RSNara Differential Revision: D30878134 Pulled By: yungsters fbshipit-source-id: ccdf798caa322b07a876da8312b97002da057388
This commit is contained in:
committed by
Facebook GitHub Bot
parent
88021894f2
commit
369b28ce01
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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.devsupport;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
import com.facebook.react.packagerconnection.RequestHandler;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple factory that creates instances of {@link DevSupportManager} implementations. Uses
|
||||
* reflection to create BridgeDevSupportManager if it exists. This allows ProGuard to strip that
|
||||
* class and its dependencies in release builds. If the class isn't found, {@link
|
||||
* DisabledDevSupportManager} is returned instead.
|
||||
*/
|
||||
public class DefaultDevSupportManagerFactory implements DevSupportManagerFactory {
|
||||
|
||||
private static final String DEVSUPPORT_IMPL_PACKAGE = "com.facebook.react.devsupport";
|
||||
private static final String DEVSUPPORT_IMPL_CLASS = "BridgeDevSupportManager";
|
||||
|
||||
public DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceDevHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
boolean enableOnCreate,
|
||||
int minNumShakes) {
|
||||
|
||||
return create(
|
||||
applicationContext,
|
||||
reactInstanceDevHelper,
|
||||
packagerPathForJSBundleName,
|
||||
enableOnCreate,
|
||||
null,
|
||||
null,
|
||||
minNumShakes,
|
||||
null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceManagerHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
boolean enableOnCreate,
|
||||
@Nullable RedBoxHandler redBoxHandler,
|
||||
@Nullable DevBundleDownloadListener devBundleDownloadListener,
|
||||
int minNumShakes,
|
||||
@Nullable Map<String, RequestHandler> customPackagerCommandHandlers) {
|
||||
if (!enableOnCreate) {
|
||||
return new DisabledDevSupportManager();
|
||||
}
|
||||
try {
|
||||
// ProGuard is surprisingly smart in this case and will keep a class if it detects a call to
|
||||
// Class.forName() with a static string. So instead we generate a quasi-dynamic string to
|
||||
// confuse it.
|
||||
String className =
|
||||
new StringBuilder(DEVSUPPORT_IMPL_PACKAGE)
|
||||
.append(".")
|
||||
.append(DEVSUPPORT_IMPL_CLASS)
|
||||
.toString();
|
||||
Class<?> devSupportManagerClass = Class.forName(className);
|
||||
Constructor constructor =
|
||||
devSupportManagerClass.getConstructor(
|
||||
Context.class,
|
||||
ReactInstanceDevHelper.class,
|
||||
String.class,
|
||||
boolean.class,
|
||||
RedBoxHandler.class,
|
||||
DevBundleDownloadListener.class,
|
||||
int.class,
|
||||
Map.class);
|
||||
return (DevSupportManager)
|
||||
constructor.newInstance(
|
||||
applicationContext,
|
||||
reactInstanceManagerHelper,
|
||||
packagerPathForJSBundleName,
|
||||
true,
|
||||
redBoxHandler,
|
||||
devBundleDownloadListener,
|
||||
minNumShakes,
|
||||
customPackagerCommandHandlers);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"Requested enabled DevSupportManager, but BridgeDevSupportManager class was not found"
|
||||
+ " or could not be created",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-72
@@ -12,39 +12,10 @@ import androidx.annotation.Nullable;
|
||||
import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
import com.facebook.react.packagerconnection.RequestHandler;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple factory that creates instances of {@link DevSupportManager} implementations. Uses
|
||||
* reflection to create BridgeDevSupportManager if it exists. This allows ProGuard to strip that
|
||||
* class and its dependencies in release builds. If the class isn't found, {@link
|
||||
* DisabledDevSupportManager} is returned instead.
|
||||
*/
|
||||
public class DevSupportManagerFactory {
|
||||
|
||||
private static final String DEVSUPPORT_IMPL_PACKAGE = "com.facebook.react.devsupport";
|
||||
private static final String DEVSUPPORT_IMPL_CLASS = "BridgeDevSupportManager";
|
||||
|
||||
public static DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceDevHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
boolean enableOnCreate,
|
||||
int minNumShakes) {
|
||||
|
||||
return create(
|
||||
applicationContext,
|
||||
reactInstanceDevHelper,
|
||||
packagerPathForJSBundleName,
|
||||
enableOnCreate,
|
||||
null,
|
||||
null,
|
||||
minNumShakes,
|
||||
null);
|
||||
}
|
||||
|
||||
public static DevSupportManager create(
|
||||
public interface DevSupportManagerFactory {
|
||||
DevSupportManager create(
|
||||
Context applicationContext,
|
||||
ReactInstanceDevHelper reactInstanceManagerHelper,
|
||||
@Nullable String packagerPathForJSBundleName,
|
||||
@@ -52,45 +23,5 @@ public class DevSupportManagerFactory {
|
||||
@Nullable RedBoxHandler redBoxHandler,
|
||||
@Nullable DevBundleDownloadListener devBundleDownloadListener,
|
||||
int minNumShakes,
|
||||
@Nullable Map<String, RequestHandler> customPackagerCommandHandlers) {
|
||||
if (!enableOnCreate) {
|
||||
return new DisabledDevSupportManager();
|
||||
}
|
||||
try {
|
||||
// ProGuard is surprisingly smart in this case and will keep a class if it detects a call to
|
||||
// Class.forName() with a static string. So instead we generate a quasi-dynamic string to
|
||||
// confuse it.
|
||||
String className =
|
||||
new StringBuilder(DEVSUPPORT_IMPL_PACKAGE)
|
||||
.append(".")
|
||||
.append(DEVSUPPORT_IMPL_CLASS)
|
||||
.toString();
|
||||
Class<?> devSupportManagerClass = Class.forName(className);
|
||||
Constructor constructor =
|
||||
devSupportManagerClass.getConstructor(
|
||||
Context.class,
|
||||
ReactInstanceDevHelper.class,
|
||||
String.class,
|
||||
boolean.class,
|
||||
RedBoxHandler.class,
|
||||
DevBundleDownloadListener.class,
|
||||
int.class,
|
||||
Map.class);
|
||||
return (DevSupportManager)
|
||||
constructor.newInstance(
|
||||
applicationContext,
|
||||
reactInstanceManagerHelper,
|
||||
packagerPathForJSBundleName,
|
||||
true,
|
||||
redBoxHandler,
|
||||
devBundleDownloadListener,
|
||||
minNumShakes,
|
||||
customPackagerCommandHandlers);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"Requested enabled DevSupportManager, but BridgeDevSupportManager class was not found"
|
||||
+ " or could not be created",
|
||||
e);
|
||||
}
|
||||
}
|
||||
@Nullable Map<String, RequestHandler> customPackagerCommandHandlers);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user