用过debug的都知道,rn可以设置链接的调试服务器,大概张这个样子:
如果我们想在原生代码里修改呢?该怎么做?
答案可能会出乎你的想象的简单,这个链接是使用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”啦
谢谢阅览!