RN系列:Android中远程调试RN及混淆打包
2019-08-01 本文已影响3人
闲庭
【简述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.**