RN系列:Android中遠程調試RN及混淆打包

【簡述RN集成到Android原生項目】
【RN系列:RN使用Android原生控件或自定義組件】
【React Native Linking與 Android原生頁面路由跳轉問題】
【RN系列: Android原生與RN如何交互通信】

  1. 手動修改React Native端口號
  2. Android程序遠程運行RN項目
  3. 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,
      }
      

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中添加以下代碼:
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    
    這時React Native 會給 Android應用提供一個設置調試屬性的頁面,首先我們先打開這個軟件,如果是真機調試的話在報錯頁面搖晃手機顯示菜單(如果是模擬器按菜單鍵或者command + M可顯示菜單),找到Dev Settings => 然後找到 Debug server host & port for device => 然後輸入RN服務對應的ip地址和端口 , 點擊返回 => 頁面是空白,再次點擊搖一搖,選擇Reload JS程序就顯示出來了,即可歡樂地進行遠程調試了。

3. RN項目與Android混合打包發佈

  1. 打離線包,手動將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
  2. 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.**
    
    
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章