Android原生项目集成React Native

时间:2024-03-26 08:16:26

最近听说最多的是Android岗位坑很少,不然就是坑少的同时没坑跳。哎,程序员道路艰辛,且行且珍惜呀~

今天给大家分享一篇关于混合开发的文章: 如何在现有的android项目中集成React Native。如果此时你还没有跳入RN的坑,那么这篇文章可能对你来说有些锦上添花了,哈哈~~

ok,坐稳我们开车。

我会以流水账的形式来向大家详细介绍如何实现,仔细看清楚步骤即可。

1.创建Android工程:ReactNativeApp

    关于如何创建Android工程就不再多述了。

2.工程创建完毕后,切换到Android Studio左下角的Terminal窗口,执行npm init命令。

    Android原生项目集成React Native

    Android原生项目集成React Native

    Android原生项目集成React Native

    npm init 命令的作用是生成package.json文件,即RN的配置文件,当输入npm init命令回车后,会提示让你输入一些基本的信息,选择填写即可。

3.执行install --save react react-native 命令

   Android原生项目集成React Native

   install --save react react-native命令用于安装 React、React Native 相关文件。

4.创建.flowconfig文件

   .flowconfig文件可以facebook的github上复制,然后在工程的根目录创建.flowconfig文件,将其内容复制进去即可。

    Android原生项目集成React Native

5.此时,你的工程中已经生成了package.json文件,然后将“start": "node node_modules/react-native/local-cli/cli.js start"添加到scripts节点下

    Android原生项目集成React Native

6.添加index.android.js文件,也就是你的RN界面到根目录下

   Android原生项目集成React Native

7.在App的build.gradle文件下添加facebook react 依赖包

   Android原生项目集成React Native

    注意最新版本中支持的是23,即需要你修改编辑SDK的版本为23,以及appcompat-v7:23.0.1,同时将minSDK改为16.

8.在project的build.gradle文件下添加如下

  Android原生项目集成React Native

9.添加网络权限管理

  Android原生项目集成React Native

10.添加NDK的支持

  Android原生项目集成React Native

  Android原生项目集成React Native

11.在App的build.gradle文件的android节点下添加:

   Android原生项目集成React Native


12.以上配置完成后,React Native就算集成到了我们现有的项目,接下来需要用Activity来展示RN,所以需要编写如下代码:

     RN旧版本中,主要使用了两个类来完成界面的渲染工作:ReactRootView,ReactInstanceManager。顾名思义,ReactRootView代表了加载进来的RN界面,ReactInstanceManager用来构建React运行环境,管理React的属性配置。

有两点需要注意:

        (1)调试模式下,需要将setUseDeveloperSupport的值设置为true,否则报错。

        (2)startReactApplication中的第二个参数,名称需要与index.android.js中AppRegister的名称相同。


新版本RN中只需要自定义一个Activity,并继承ReactActivity,实现getMainComponentName方法,在getMainComponentName方法中返回RN注册的名称即可,名称需要与index.android.js中AppRegister的名称相同。通过源码可以看到,其实在ReactActivity中已经帮助我们实现了ReactRoow的添加和ReactInstanceManager的默认配置。

[java] view plain copy
  1. /** 
  2.  * Created by Song on 2017/2/13. 
  3.  */  
  4. public class MyReactActivity extends ReactActivity {  
  5.   
  6.     @Nullable  
  7.     @Override  
  8.     protected String getMainComponentName() {  
  9.         return "HotRN";  
  10.     }  
  11.   
  12. }  
然后创建Application,去初始化ReactNativeHost。自定义Application需要继承ReactApplication,在源码loadApp方法中,会将当前Activity的Application强转为ReactApplication,所以这是必须的步骤。

[java] view plain copy
  1. public class MainApplication extends Application implements ReactApplication {  
  2.   
  3.     private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {  
  4.         @Override  
  5.         protected boolean getUseDeveloperSupport() {  
  6.             return BuildConfig.DEBUG;  
  7.         }  
  8.   
  9.         @Override  
  10.         protected List<ReactPackage> getPackages() {  
  11.             return Arrays.<ReactPackage>asList(  
  12.                     new MainReactPackage()  
  13.             );  
  14.         }  
  15.   
  16.     };  
  17.   
  18.     @Override  
  19.     public ReactNativeHost getReactNativeHost() {  
  20.         return mReactNativeHost;  
  21.     }  
  22.   
  23.     @Override  
  24.     public void onCreate() {  
  25.         super.onCreate();  
  26.         SoLoader.init(this,false);  
  27.     }  
  28.   
  29. }  

OK,如果以上步骤集成顺利的话,那么就大功告成啦!!

13.继续切换到Terminal窗口,执行npm start来启动

      如果出现错误,则基本可以定位为没有bundle文件。此时需要我们手动来生成bundle文件,并放在assets目录下(app/src/main/assets)。

      手动生成bundle文件,需要我们执行如下命令:

       react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/

       (1)--platform:平台

       (2) --dev:开发模式

       (3) --entry-file:条目文件

       (4)--bundle-output:bundle文件生成的目录

       (5)--assets-dest:资源文件生成的目录

    Android原生项目集成React Native

此时运行你的Android工程,可以看到RN已经被我们完美的集成进来啦~

Android原生项目集成React Native

可以明显看到,第一次进入的时候,由于加载JsBundle,导致有一些延迟,但是当我们第二次进入的时候,就会瞬间加载完成并显示出来。此类问题的解决方案我单独写了一篇博客来介绍:基于最新版本React Native实现JsBundle预加载,界面秒开优化


如果你的项目要开启混淆策略,可以在proguard下添加如下

[java] view plain copy
  1. # React Native  
  2.   
  3. # Keep our interfaces so they can be used by other ProGuard rules.  
  4. # See http://sourceforge.net/p/proguard/bugs/466/  
  5. -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip  
  6. -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters  
  7. -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip  
  8.   
  9. # Do not strip any method/class that is annotated with @DoNotStrip  
  10. -keep @com.facebook.proguard.annotations.DoNotStrip class *  
  11. -keep @com.facebook.common.internal.DoNotStrip class *  
  12. -keepclassmembers class * {  
  13.     @com.facebook.proguard.annotations.DoNotStrip *;  
  14.     @com.facebook.common.internal.DoNotStrip *;  
  15. }  
  16.   
  17. -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {  
  18.   void set*(***);  
  19.   *** get*();  
  20. }  
  21.   
  22. -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }  
  23. -keep class * extends com.facebook.react.bridge.NativeModule { *; }  
  24. -keepclassmembers,includedescriptorclasses class * { native <methods>; }  
  25. -keepclassmembers class *  { @com.facebook.react.uimanager.UIProp <fields>; }  
  26. -keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }  
  27. -keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }  
  28.   
  29. -dontwarn com.facebook.react.**  
  30.   
  31. # okhttp  
  32.   
  33. -keepattributes Signature  
  34. -keepattributes *Annotation*  
  35. -keep class okhttp3.** { *; }  
  36. -keep interface okhttp3.** { *; }  
  37. -dontwarn okhttp3.**  
  38.   
  39. # okio  
  40.   
  41. -keep class sun.misc.Unsafe { *; }  
  42. -dontwarn java.nio.file.*  
  43. -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement  
  44. -dontwarn okio.**  

OK,今天的内容就到这里了,下一篇博客我将和大家分享如何实现热更新,敬请期待!

源码已分享到github,感兴趣的大家可以flow,star哈~

源码下载