1. 程式人生 > >RN,android原生修改debug模式,程式碼伺服器地址方法及原始碼分析

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,

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

這裡寫圖片描述

謝謝閱覽!