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

用过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"啦


谢谢阅览!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容