react-native实践记录(02)

###0.前言

开发环境:windows10 + vscode + react-native 0.57 + Android模拟器

本文主要记录原生项目中引入react-native的步骤和注意项。(Android方向)

###1.android项目创建与配置
通过AndroidStudio创建一个原生项目,也可以使用现成的项目。

####1.1配置

  1. app项目目录下,添加react-native的架包

    //android/app/build.gradle文件
    dependencies {
        ...
        implementation "com.facebook.react:react-native:+"  // From node_modules
    }
    
  2. 项目根目录下的build.gradle添加react-native支持库引用

    //android/build.gradle
    allprojects {
        repositories {
            google()
            jcenter()
            maven {
                // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
                url "$rootDir/../node_modules/react-native/android"
            }
        }
    }
    
  3. 创建assets资源文件夹

    assets文件夹

    主要作用是用于存放react-native生成的离线文件,即图中的index.android.bundle.(下面会讲解如何生成)

  4. Application的实现ReactApplication接口

    //application类
    public class NowyApp extends Application implements ReactApplication {
        @Override
        public ReactNativeHost getReactNativeHost() {
            return mReactNativeHost;
        }
        private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
            @Override
            public boolean getUseDeveloperSupport() {
                return BuildConfig.DEBUG;
            }
    
            @Override
            protected List<ReactPackage> getPackages() {
                return Arrays.<ReactPackage>asList(//高级应用:JS调原生模块
                        new MainReactPackage()
                );
            }
        //JS调原生模块:https://reactnative.cn/docs/native-modules-android/
    
            //对应react-native项目的入口文件的名称,此项目为index.js
            @Override
            protected String getJSMainModuleName() {
                return "index";
            }
        };
    }
    
  5. 创建承载react-native界面的activity

    //ReactAty类
    public class ReactAty extends ReactActivity {
        /**
         * Returns the name of the main component registered from JavaScript.
         * This is used to schedule rendering of the component.
         */
        @Override
        protected String getMainComponentName() {
            //对应AppRegistry.registerComponent(appName, () => Test);中的appName,此处为ReactNativeApp
            return "ReactNativeApp";
        }
    }
    
  6. 其他配置

    • ndk配置,项目中使用ndk

      • gradle.properties中添加android.useDeprecatedNdk=true

      • android/app/build.gradle的defaultConfig节点里添加ndk {
        abiFilters “armeabi-v7a”, “x86”
        }

    • 权限配置

    • AndroidManifest.xml注册ReactAty组件

###2.react-native环境引入

####2.1.生成react-native环境
本项目是在Android项目外部添加一个文件夹作为整个项目的根目录:

../ReactNativeApp/android (android为完整的Android项目空间)

  1. 在旧的react-native项目拷贝package.json到项目ReactNativeApp目录下,代码大体如下

    //package.json文件
    {
      "name": "ReactNativeApp", //你的项目名,需要修改
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start", //配置启动脚本
      },
    //简单的方法是通过react-native init "项目名"创建后拷贝package.json文件
    }
    
  2. ReactNativeApp目录下使用cmd执行npm install react react-native --save,引入reactreact-native
    成果图片

    ReactNativeApp目录下生成node_modules文件夹

  3. 配置react-native项目入口文件index.js

    在react-native的0.57版本,使用react-native init 初始化的项目有index.jsapp.jsonApp.js3个文件:

    • app.json:记录react-native项目的项目名和显示名称
    • App.js:项目代码文件,类似Android里面的activity(App.js只是一个示例,可以应用其他组件的js)
    • index.js:入口注册文件,声明react-native项目的名称和入口文件(采用上面2个文件的内容),类似Android的AndroidManifest.xml声明入口activity

      示例

      上图中,项目注册的appName是引用自app.json的name.组件Test是引用app/src/Test.js文件

  4. react-native功能实现

    //Test.js核心代码 此处是在UI上显示一张图片
    export default class Test extends React.Component{
        constructor(props){
            super(props);
        }
        render(){
            return(
                // 显示一张图片
                <View style={styles.container}> 
                    <Image source={
                        require('../images/ic_user_avatar_def.png')}
                        style={styles.img}
                    />
                </View>
            );
        }
    
    }
    
  5. 输出bundle文件,存放于assets中

    bundle文件:代码文件,类似Android中的dex

    在当前目录下,通过命令行cmd执行下列语句:

1
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
bundle命令的相关参数说明:
1. --platform:指定平台(android、ios)
2. --dev:开发模式
3. --entry-file:指定项目入口文件,通常是index.js。(老版本是index.android.js或者index.ios.js)
4. --bundle-output:bundle文件生成的目录(通常是在assets目录下)
5. --assets-dest:资源文件生成的目录(会在Android 项目下生产一个文件夹:`drawable-mdpi`)

###3.运行与编译

####3.1 运行

  1. 通过AndroidStudio运行
  2. 通过命令行cmd执行 react-native run-android 运行

####3.2 编译

  1. 编写react-native代码可以通过2.5中的命令重新生成新的index.android.bundle文件
  2. 编写Android代码直接在Android项目中编写(记得rebuild)
  3. Android如果开启混淆,需要把react和react-native项目保持
#proguard-rules.pro文件
# React Native

# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip

# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.proguard.annotations.DoNotStrip class *
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
    @com.facebook.proguard.annotations.DoNotStrip *;
    @com.facebook.common.internal.DoNotStrip *;
}

-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
  void set*(***);
  *** get*();
}

-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
-keepclassmembers class *  { @com.facebook.react.uimanager.UIProp <fields>; }
-keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
-keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }

-dontwarn com.facebook.react.**

###4.其他
项目的提交记得编写忽略文件,将node_modules等文件忽略。
如在git项目根目录下添加.gitignore文件。

测试项目地址:点击这里

END

– Nowy

– 2018.11.10

分享到