- Add DevSetting native module (making it cross-platform) (#24441)
Summary: React Native has a `NativeModule` to manipulate programmatically the dev menu options (live reload, hot reload, remote debugging, etc), called [`DevSettings`](https://github.com/facebook/react-native/blob/master/React/Modules/RCTDevSettings.mm#L120). However this module is only available for iOS. This PR brings the same `DevSettings` for Android, making it a cross-platform NativeModule. Motivation: Right now if your app needs to programmatically reload RN, one option is to install [`react-native-restart`](https://www.npmjs.com/package/react-native-restart). It's a tiny dependency, but it's annoying to have to install it, while the code to do so is inside RN codebase. According to NPM, react-native-restart has ~12k weekly downloads, shows it's a recurring feature for many apps (my case). Thus making `NativeModules.DevSettings` is a small increment in the codebase, just exposing the dev menu methods, to improve the Development Experience [Android] [Added] - Add DevSetting native module (making it cross-platform) With expection of `setIsShakeToShowDevMenuEnabled`, the following methods will be available for both platforms: * reload * setHotLoadingEnabled * setIsDebuggingRemotely * setIsShakeToShowDevMenuEnabled * setLiveReloadEnabled * setProfilingEnabled * toggleElementInspector Pull Request resolved: https://github.com/facebook/react-native/pull/24441 Differential Revision: D14932751 Pulled By: cpojer fbshipit-source-id: 465e6a89c3beb5fd1ea22e80ea02e9438f596a09
This commit is contained in:
Родитель
62ff7d6863
Коммит
e76a7df5b5
|
@ -23,6 +23,7 @@ import com.facebook.react.modules.core.ExceptionsManagerModule;
|
||||||
import com.facebook.react.modules.core.Timing;
|
import com.facebook.react.modules.core.Timing;
|
||||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||||
import com.facebook.react.modules.core.HeadlessJsTaskSupportModule;
|
import com.facebook.react.modules.core.HeadlessJsTaskSupportModule;
|
||||||
|
import com.facebook.react.modules.debug.DevSettingsModule;
|
||||||
import com.facebook.react.modules.debug.SourceCodeModule;
|
import com.facebook.react.modules.debug.SourceCodeModule;
|
||||||
import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
|
import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
|
||||||
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
import com.facebook.react.modules.systeminfo.AndroidInfoModule;
|
||||||
|
@ -49,6 +50,7 @@ import static com.facebook.react.bridge.ReactMarkerConstants.*;
|
||||||
AndroidInfoModule.class,
|
AndroidInfoModule.class,
|
||||||
DeviceEventManagerModule.class,
|
DeviceEventManagerModule.class,
|
||||||
DeviceInfoModule.class,
|
DeviceInfoModule.class,
|
||||||
|
DevSettingsModule.class,
|
||||||
ExceptionsManagerModule.class,
|
ExceptionsManagerModule.class,
|
||||||
HeadlessJsTaskSupportModule.class,
|
HeadlessJsTaskSupportModule.class,
|
||||||
SourceCodeModule.class,
|
SourceCodeModule.class,
|
||||||
|
@ -93,6 +95,7 @@ import static com.facebook.react.bridge.ReactMarkerConstants.*;
|
||||||
AndroidInfoModule.class,
|
AndroidInfoModule.class,
|
||||||
DeviceEventManagerModule.class,
|
DeviceEventManagerModule.class,
|
||||||
DeviceInfoModule.class,
|
DeviceInfoModule.class,
|
||||||
|
DevSettingsModule.class,
|
||||||
ExceptionsManagerModule.class,
|
ExceptionsManagerModule.class,
|
||||||
HeadlessJsTaskSupportModule.class,
|
HeadlessJsTaskSupportModule.class,
|
||||||
SourceCodeModule.class,
|
SourceCodeModule.class,
|
||||||
|
@ -138,6 +141,8 @@ import static com.facebook.react.bridge.ReactMarkerConstants.*;
|
||||||
return new AndroidInfoModule(reactContext);
|
return new AndroidInfoModule(reactContext);
|
||||||
case DeviceEventManagerModule.NAME:
|
case DeviceEventManagerModule.NAME:
|
||||||
return new DeviceEventManagerModule(reactContext, mHardwareBackBtnHandler);
|
return new DeviceEventManagerModule(reactContext, mHardwareBackBtnHandler);
|
||||||
|
case DevSettingsModule.NAME:
|
||||||
|
return new DevSettingsModule(mReactInstanceManager.getDevSupportManager());
|
||||||
case ExceptionsManagerModule.NAME:
|
case ExceptionsManagerModule.NAME:
|
||||||
return new ExceptionsManagerModule(mReactInstanceManager.getDevSupportManager());
|
return new ExceptionsManagerModule(mReactInstanceManager.getDevSupportManager());
|
||||||
case HeadlessJsTaskSupportModule.NAME:
|
case HeadlessJsTaskSupportModule.NAME:
|
||||||
|
|
|
@ -1040,6 +1040,90 @@ public class DevSupportManagerImpl implements
|
||||||
mDevServerHelper.closeInspectorConnection();
|
mDevServerHelper.closeInspectorConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHotModuleReplacementEnabled(final boolean isHotModuleReplacementEnabled) {
|
||||||
|
if (!mIsDevSupportEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiThreadUtil.runOnUiThread(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mDevSettings.setHotModuleReplacementEnabled(isHotModuleReplacementEnabled);
|
||||||
|
handleReloadJS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRemoteJSDebugEnabled(final boolean isRemoteJSDebugEnabled) {
|
||||||
|
if (!mIsDevSupportEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiThreadUtil.runOnUiThread(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mDevSettings.setRemoteJSDebugEnabled(isRemoteJSDebugEnabled);
|
||||||
|
handleReloadJS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReloadOnJSChangeEnabled(final boolean isReloadOnJSChangeEnabled) {
|
||||||
|
if (!mIsDevSupportEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiThreadUtil.runOnUiThread(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mDevSettings.setReloadOnJSChangeEnabled(isReloadOnJSChangeEnabled);
|
||||||
|
handleReloadJS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFpsDebugEnabled(final boolean isFpsDebugEnabled) {
|
||||||
|
if (!mIsDevSupportEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiThreadUtil.runOnUiThread(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mDevSettings.setFpsDebugEnabled(isFpsDebugEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toggleElementInspector() {
|
||||||
|
if (!mIsDevSupportEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiThreadUtil.runOnUiThread(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mDevSettings.setElementInspectorEnabled(!mDevSettings.isElementInspectorEnabled());
|
||||||
|
mReactInstanceManagerHelper.toggleElementInspector();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private void reload() {
|
private void reload() {
|
||||||
UiThreadUtil.assertOnUiThread();
|
UiThreadUtil.assertOnUiThread();
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,31 @@ public class DisabledDevSupportManager implements DevSupportManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHotModuleReplacementEnabled(boolean isHotModuleReplacementEnabled) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRemoteJSDebugEnabled(boolean isRemoteJSDebugEnabled) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReloadOnJSChangeEnabled(boolean isReloadOnJSChangeEnabled) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFpsDebugEnabled(boolean isFpsDebugEnabled) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toggleElementInspector() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getDevSupportEnabled() {
|
public boolean getDevSupportEnabled() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -45,6 +45,11 @@ public interface DevSupportManager extends NativeModuleCallExceptionHandler {
|
||||||
void handleReloadJS();
|
void handleReloadJS();
|
||||||
void reloadJSFromServer(final String bundleURL);
|
void reloadJSFromServer(final String bundleURL);
|
||||||
void isPackagerRunning(PackagerStatusCallback callback);
|
void isPackagerRunning(PackagerStatusCallback callback);
|
||||||
|
void setHotModuleReplacementEnabled(final boolean isHotModuleReplacementEnabled);
|
||||||
|
void setRemoteJSDebugEnabled(final boolean isRemoteJSDebugEnabled);
|
||||||
|
void setReloadOnJSChangeEnabled(final boolean isReloadOnJSChangeEnabled);
|
||||||
|
void setFpsDebugEnabled(final boolean isFpsDebugEnabled);
|
||||||
|
void toggleElementInspector();
|
||||||
@Nullable File downloadBundleResourceFromUrlSync(
|
@Nullable File downloadBundleResourceFromUrlSync(
|
||||||
final String resourceURL,
|
final String resourceURL,
|
||||||
final File outputFile);
|
final File outputFile);
|
||||||
|
|
|
@ -12,6 +12,7 @@ rn_android_library(
|
||||||
react_native_dep("third-party/java/jsr-305:jsr-305"),
|
react_native_dep("third-party/java/jsr-305:jsr-305"),
|
||||||
react_native_target("java/com/facebook/react/bridge:bridge"),
|
react_native_target("java/com/facebook/react/bridge:bridge"),
|
||||||
react_native_target("java/com/facebook/react/common:common"),
|
react_native_target("java/com/facebook/react/common:common"),
|
||||||
|
react_native_target("java/com/facebook/react/devsupport:interfaces"),
|
||||||
react_native_target("java/com/facebook/react/module/annotations:annotations"),
|
react_native_target("java/com/facebook/react/module/annotations:annotations"),
|
||||||
react_native_target("java/com/facebook/react/modules/core:core"),
|
react_native_target("java/com/facebook/react/modules/core:core"),
|
||||||
react_native_target("java/com/facebook/react/modules/debug:interfaces"),
|
react_native_target("java/com/facebook/react/modules/debug:interfaces"),
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* 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.modules.debug;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.BaseJavaModule;
|
||||||
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||||
|
import com.facebook.react.module.annotations.ReactModule;
|
||||||
|
import com.facebook.react.bridge.UiThreadUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module that exposes the URL to the source code map (used for exception stack trace parsing) to JS
|
||||||
|
*/
|
||||||
|
@ReactModule(name = DevSettingsModule.NAME)
|
||||||
|
public class DevSettingsModule extends BaseJavaModule {
|
||||||
|
|
||||||
|
public static final String NAME = "DevSettings";
|
||||||
|
|
||||||
|
private final DevSupportManager mDevSupportManager;
|
||||||
|
|
||||||
|
public DevSettingsModule(DevSupportManager devSupportManager) {
|
||||||
|
mDevSupportManager = devSupportManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void reload() {
|
||||||
|
if (mDevSupportManager.getDevSupportEnabled()) {
|
||||||
|
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mDevSupportManager.handleReloadJS();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void setHotLoadingEnabled(boolean isHotLoadingEnabled) {
|
||||||
|
mDevSupportManager.setHotModuleReplacementEnabled(isHotLoadingEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void setIsDebuggingRemotely(boolean isDebugginRemotelyEnabled) {
|
||||||
|
mDevSupportManager.setRemoteJSDebugEnabled(isDebugginRemotelyEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void setLiveReloadEnabled(boolean isLiveReloadEnabled) {
|
||||||
|
mDevSupportManager.setReloadOnJSChangeEnabled(isLiveReloadEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void setProfilingEnabled(boolean isProfilingEnabled) {
|
||||||
|
mDevSupportManager.setFpsDebugEnabled(isProfilingEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void toggleElementInspector() {
|
||||||
|
mDevSupportManager.toggleElementInspector();
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче