【簡述RN集成到Android原生項目】
【RN系列:RN使用Android原生控件或自定義組件】
【React Native Linking與 Android原生頁面路由跳轉問題】
【RN系列: Android原生與RN如何交互通信】
- 手動修改React Native端口號
- Android程序遠程運行RN項目
- RN項目與Android一起混淆打包發佈
不清楚Android項目如何集成RN,見【簡述RN集成到Android原生項目】
在Android原生項目中集成RN項目場景,這裏主要圍繞以下幾個方面簡單描述一下:
運行React Native會啓動一個默認端口號爲8081的本地服務,當端口號被本地其他服務佔用,那麼就啓動不成功了,那就要手動修改端口號了;當開啓RN服務時,Android項目又如何遠程調試?那就去設置加載的地址IP+端口號;當調試好了,如何將RN項目跟隨app測試發版?那就將RN項目打包成離線bundle文件,放到Android本地或者遠程服務器上即可。
1. 手動修改React Native端口號
-
修改React Native Server端口號
運行一個React Native項目的時候,React Native會啓動一個默認端口號爲8081的本地服務,該8081的服務就是React Native項目的一個本地服務器,用於提供JSBundle包和一些靜態資源。- 臨時修改Server端口號
在Terminal中執行yarn start --port=8082
或者npm run start --port=8082
. - 永久修改Server端口號
在你的項目名稱/node_modules/react-native/local-cli/server/server.js
找到server.js
文件,打開後找到module.exports -> options -> command: '--port [number]'
修改對應的default的值。
修改前:
修改後:{ command: '--port [number]', parse: (val: string) => Number(val), default: (config: ConfigT) => config.server.port, }
{ command: '--port [number]', parse: (val: string) => Number(val), default: 8082, }
- 臨時修改Server端口號
2. Android連接RN服務進行遠程調試
-
方案一:
代碼中在application或者主activity中做如下設置:@Override public void onCreate() { super.onCreate(); SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); mPreferences.edit().putString("debug_http_host","localhost:8082").commit(); }
-
方案二:
在Android應用的AndroidManifest
中添加以下代碼:
這時React Native 會給 Android應用提供一個設置調試屬性的頁面,首先我們先打開這個軟件,如果是真機調試的話在報錯頁面搖晃手機顯示菜單(如果是模擬器按菜單鍵或者command + M可顯示菜單),找到<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
Dev Settings
=> 然後找到Debug server host & port for device
=> 然後輸入RN服務對應的ip地址和端口 , 點擊返回 => 頁面是空白,再次點擊搖一搖,選擇Reload JS
程序就顯示出來了,即可歡樂地進行遠程調試了。
3. RN項目與Android混合打包發佈
-
打離線包,手動將RN項目生成 bundle文件及圖片資源保存到assets 文件夾下或者本地存儲文件夾中。最終將bundle文件放入Android項目的assets目錄中,將圖片資源放入drawable目錄下即可
(遠程動態加載則不需要)
。react-native bundle --entry-file index.android.js --platform android --dev false --bundle-output ./app/src/main/assets/index.android.bundle --assets-dest ./app/src/main/res/
- --platform:平臺
- --dev:開發模式
- --entry-file:加載入口文件
- --bundle-output:bundle文件名稱及保存到對應的目錄
- --assets-dest:資源文件生成的目錄
備註:
react-native bundle --entry-file index.js --platform android --dev false --bundle-output ./app/src/main/assets/index.android.bundle --assets-dest ./app/src/main/res/
不同業務對應的entry-file
文件不一樣(有的是index.js,有的是index.android.js),打包時填寫正確的入口文件名,並且bundle-output
輸出的文件名也需要根據業務區分,有的路徑是./android/app/XXX
,有的是./app/xxx
,若路徑下面沒有assets
文件夾需手動創建。
查看打包命令
react-native bundle -h
-
Android項目集成RN混淆代碼
-keep,allowobfuscation,includedescriptorclasses @interface com.facebook.proguard.annotations.DoNotStrip -keep,allowobfuscation,includedescriptorclasses @interface com.facebook.proguard.annotations.KeepGettersAndSetters -keep,allowobfuscation,includedescriptorclasses @interface com.facebook.common.internal.DoNotStrip # SoLoader -keep class com.facebook.soloader.** { *; } -keepclassmembers class com.facebook.soloader.SoLoader { static <fields>; } # Do not strip any method/class that is annotated with @DoNotStrip -keep,includedescriptorclasses @com.facebook.proguard.annotations.DoNotStrip class * -keep,includedescriptorclasses @com.facebook.common.internal.DoNotStrip class * -keepclassmembers,includedescriptorclasses class * { @com.facebook.proguard.annotations.DoNotStrip *; @com.facebook.common.internal.DoNotStrip *; } -keepclassmembers,includedescriptorclasses @com.facebook.proguard.annotations.KeepGettersAndSetters class * { void set*(***); *** get*(); } -keep,includedescriptorclasses class * { native <methods>; } -keep,includedescriptorclasses class * { @com.facebook.react.uimanager.UIProp <fields>; } -keep,includedescriptorclasses class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; } -keep,includedescriptorclasses class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; } -keep,includedescriptorclasses class com.facebook.react.uimanager.UIProp { *; } -keep,includedescriptorclasses class * extends com.facebook.react.bridge.JavaScriptModule { *; } -keep,includedescriptorclasses class * extends com.facebook.react.bridge.NativeModule { *; } -keep,includedescriptorclasses class com.facebook.react.bridge.CatalystInstanceImpl { *; } -keep,includedescriptorclasses class com.facebook.react.bridge.JavaScriptExecutor { *; } -keep,includedescriptorclasses class com.facebook.react.bridge.queue.NativeRunnable { *; } -keep,includedescriptorclasses class com.facebook.react.bridge.ExecutorToken { *; } -keep,includedescriptorclasses class com.facebook.react.bridge.ReadableType { *; } -dontwarn com.facebook.react.** -dontnote com.facebook.** # TextLayoutBuilder uses a non-public Android constructor within StaticLayout. # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details. -dontwarn android.text.StaticLayout # okhttp -keepattributes Signature -keepattributes *Annotation* -keep class okhttp3.** { *; } -keep interface okhttp3.** { *; } -dontwarn okhttp3.** # okio -keep class sun.misc.Unsafe { *; } -dontwarn java.nio.file.* -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement -dontwarn okio.**