RN,android原生修改debug模式,代码服务器地址方法及源码分析

用过debug的都知道,rn可以设置链接的调试服务器,大概张这个样子:

RN,android原生修改debug模式,代码服务器地址方法及源码分析
RN,android原生修改debug模式,代码服务器地址方法及源码分析

如果我们想在原生代码里修改呢?该怎么做?

答案可能会出乎你的想象的简单,这个链接是使用sharedPreferences保存的只要使用sharedPreferences修改key为”debug_http_host”的值就可以了~~~

不过我们还是深入了解一下源码的原理,可以帮助我们更好的理解RN,下面我来为您讲述一下:

首先要了解这个类,ReactInstanceManager,ReactInstanceManager非常重要,是RN的主控制器, 构建RN世界的运行环境,发送事件到JS世界, 驱动整个RN世界运转。

之后,ReactInstanceManager拥有一个DevSupportManager实例,这个类是debug模式相关功能的控制器,所以链接服务器当然也归他管啦~~

ReactInstanceManager初始化的时候会通过DevSupportManagerFactory创建mDevSupportManager实例,代码如下:

mDevSupportManager = DevSupportManagerFactory.create(

applicationContext,

mDevInterface,

mJSMainModulePath,

useDeveloperSupport,

redBoxHandler,

devBundleDownloadListener,

minNumShakes);

其中mDevInterface声明如下:

private final ReactInstanceDevCommandsHandler mDevInterface =

new ReactInstanceDevCommandsHandler() {

@Override

public void onReloadWithJSDebugger(JavaJSExecutor.Factory jsExecutorFactory) {

ReactInstanceManager.this.onReloadWithJSDebugger(jsExecutorFactory);

}

@Override

public void onJSBundleLoadedFromServer() {

ReactInstanceManager.this.onJSBundleLoadedFromServer();

}

@Override

public void toggleElementInspector() {

ReactInstanceManager.this.toggleElementInspector();

}

};

看到onJSBundleLoadedFromServer方法没有,这就是通过服务器获取bundle调用的方法,哈哈~

@ThreadConfined(UI)

private void onJSBundleLoadedFromServer() {

Log.d(ReactConstants.TAG,”ReactInstanceManager.onJSBundleLoadedFromServer()”);

recreateReactContextInBackground(

mJavaScriptExecutorFactory,

JSBundleLoader.createCachedBundleFromNetworkLoader(

mDevSupportManager.getSourceUrl(),mDevSupportManager.getDownloadedJSBundleFile()));

}

看最后一行,mDevSupportManager.getSourceUrl(),这里就是去拿我们保存的URL了。

DevSupportManager是一个接口类,DevSupportManagerImpl类才是真正的实现,DevSupportManagerImpl的getSourceUrl()如下:

@Override

public String getSourceUrl() {

if (mJSAppBundleName ==null) {

return “”;

}

return mDevServerHelper.getSourceUrl(Assertions.assertNotNull(mJSAppBundleName));

}

再看mDevServerHelper.getSourceUrl:

public String getSourceUrl(String mainModuleName) {

return createBundleURL(

mainModuleName,mSettings.isBundleDeltasEnabled() ? BundleType.DELTA : BundleType.BUNDLE);

}

createBundleURL的实现:

private String createBundleURL(String mainModuleID, BundleType type) {

return createBundleURL(

mainModuleID, type,mSettings.getPackagerConnectionSettings().getDebugServerHost());

}

private String createBundleURL(String mainModuleID, BundleType type, String host) {

return String.format(

Locale.US,

http://%s/%s.%s?platform=android&dev=%s&minify=%s“,

host,

mainModuleID,

type.typeID(),

getDevMode(),

getJSMinifyMode());

}

这里我们看到createBundleURL的参数host就是我们设置的URL了,是通过mSettings.getPackagerConnectionSettings().getDebugServerHost()方法得到,

而这个方法:

public String getDebugServerHost() {

// Check host setting first. If empty try to detect emulator type and use default

// hostname for those

String hostFromSettings =mPreferences.getString(PREFS_DEBUG_SERVER_HOST_KEY,null);

if (!TextUtils.isEmpty(hostFromSettings)) {

return Assertions.assertNotNull(hostFromSettings);

}

String host = AndroidInfoHelpers.getServerHost();

if (host.equals(AndroidInfoHelpers.DEVICE_LOCALHOST)) {

FLog.w(

TAG,

“You seem to be running on device. Run ‘adb reverse tcp:8081 tcp:8081’ ” +

“to forward the debug server’s port to the device.”);

}

return host;

}

我们看到了, String hostFromSettings =mPreferences.getString(PREFS_DEBUG_SERVER_HOST_KEY,null);,通过PREFS_DEBUG_SERVER_HOST_KEY从找到的,而PREFS_DEBUG_SERVER_HOST_KEY就是我们前文所说的”debug_http_host”啦

RN,android原生修改debug模式,代码服务器地址方法及源码分析

谢谢阅览!