RN,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”啦

这里写图片描述

谢谢阅览!

如果你想在 React Native 中调用原生方法,可以使用 React Native 提供的 Native Modules。 首先,在原生代码中创建一个方法,然后将其导出到 React Native 中。例如在 iOS 项目中,可以在 `AppDelegate.m` 文件中添加以下方法: ``` #import <React/RCTBridge.h> #import <React/RCTBridgeModule.h> @interface MyModule : NSObject <RCTBridgeModule> @end @implementation MyModule RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(myMethod:(NSString *)myArgument callback:(RCTResponseSenderBlock)callback) { // 在这里实现你的方法逻辑 NSString *myResponse = @"这是我的响应"; callback(@[[NSNull null], myResponse]); } @end ``` 在上面的代码中,我们定义了一个名为 `myMethod` 的方法,并将其导出到 React Native 中。此方法接受一个字符串参数 `myArgument` 和一个回调函数 `callback`,并在回调函数中返回一个响应字符串。 接下来,在 React Native 中调用这个方法。可以使用 `NativeModules` 模块来访问原生方法。例如: ``` import { NativeModules } from 'react-native'; const { MyModule } = NativeModules; MyModule.myMethod('这是我的参数', (error, response) => { if (error) { console.error(error); } else { console.log(response); } }); ``` 在上面的代码中,我们使用 `NativeModules` 访问原生模块 `MyModule`,并调用其中的 `myMethod` 方法。此方法接受一个字符串参数和一个回调函数,该回调函数在方法完成后被调用,并传递错误对象和响应字符串作为参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值