安卓原生嵌入ReactNative页面

新建原生项目

原生项目目录下初始化RN环境

  • 打开git bash依次输入如下命令:

    1. npm init

    其中字段name不能出现大写字母,不能出现数字;entry point字段代表入口文件名,默认为index.js,改为任意你喜欢的xxx.js都OK。其他字段按需填写

    此命令之后会在根目录生成一个package.json的配置文件,打开后在scripts节点内添加node node_modules/react-native/local-cli/cli.js start,添加脚手架

    2. npm install –save react react-native

    在目录下引入react-native

    3. curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig

    window可能用不了curl的命令,解决办法:

    我们在windows下要使用curl命令比较麻烦。解决方法就是我们用下载工具从这里这里这里把.flowconfig下载下来复制到项目根目录,或者是在项目根目录下新建一个.flowconfig文件用浏览器访问这个网址其中的内容把其中的内容复制到文件当中。

  • 新建’index.js’文件,或者是你自己取得名字’xxx.js’

    将下面这段代码copy进去:

      'use strict';
    
      import React from 'react';
      import {
        AppRegistry,
        StyleSheet,
        Text,
        View
      } from 'react-native';
    
      class HelloWorld extends React.Component {
            render() {
              return (
                <View style={styles.container}>
                  <Text style={styles.hello}>Welcome!</Text>
                </View>
              )
            }
      }
    
      var styles = StyleSheet.create({
            container: {
              flex: 1,
              justifyContent: 'center',
            },
            hello: {
              fontSize: 20,
              textAlign: 'center',
              margin: 10,
            },
      });
    
      AppRegistry.registerComponent('HelloWorld', () => HelloWorld);//强行标注!后边的HelloWorld!!
    

添加依赖

  • 在项目的build.gradle中添加:

      allprojects {
          repositories {
              jcenter()
              maven {
                  //添加react native依赖,url路径根据实际的来写,本文的如下:
                  url "$rootDir/node_modules/react-native/android"
              }
          }
      }
    
  • 在app的build.gradle中添加:

      dependencies {
          ...
          compile "com.facebook.react:react-native:+"  // From node_modules
      }
    
  • 编译

    可能遇到的问题:jsr305缺失

    解决:app.gradle中添加:

      configurations.all {
          resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.2'
      }
    

新建MyRNActivity的两种写法

  1. 第一种写法

     public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
         private ReactRootView mReactRootView;
         private ReactInstanceManager mReactInstanceManager;
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
    
             mReactRootView = new ReactRootView(this);
             mReactInstanceManager = ReactInstanceManager.builder()
                 .setApplication(getApplication())
                 .setBundleAssetName("index.android.bundle")
                 .setJSMainModuleName("index") //对应index.js
                 .addPackage(new MainReactPackage())
                 //.setUseDeveloperSupport(BuildConfig.DEBUG) //开发者支持,BuildConfig.DEBUG的值默认是false,无法使用开发者菜单
                 .setUseDeveloperSupport(true) //开发者支持,开发的时候要设置为true,不然无法使用开发者菜单
                 .setInitialLifecycleState(LifecycleState.RESUMED)
                 .build();
             //这里的ReactNativeView对应index.js中AppRegistry.registerComponent('ReactNativeView', () => ReactNativeView)的ReactNativeView
             mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);
             //上边的HelloWorld必须和前文提到的强行标注的HelloWorld一致!当然你换其他名也可以
             setContentView(mReactRootView);
         }
    
         @Override
         public void invokeDefaultOnBackPressed() {
             super.onBackPressed();
         }
    
         @Override
         protected void onPause() {
             super.onPause();
    
             if (mReactInstanceManager != null) {
                 mReactInstanceManager.onHostPause(this);
             }
         }
    
         @Override
         protected void onResume() {
             super.onResume();
    
             if (mReactInstanceManager != null) {
                 mReactInstanceManager.onHostResume(this, this);
             }
         }
    
         @Override
         protected void onDestroy() {
             super.onDestroy();
    
             if (mReactInstanceManager != null) {
                 mReactInstanceManager.onHostDestroy(this);
             }
         }
    
         @Override
         public void onBackPressed() {
             if (mReactInstanceManager != null) {
                 mReactInstanceManager.onBackPressed();
             } else {
                 super.onBackPressed();
             }
         }
    
         @Override
         public boolean onKeyUp(int keyCode, KeyEvent event) {
             //当我们点击菜单的时候打开发者菜单,一个弹窗(此处需要悬浮窗权限才能显示)
             if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
                 mReactInstanceManager.showDevOptionsDialog();
                 return true;
             }
             return super.onKeyUp(keyCode, event);
         }
     }
    
  2. 第二种写法

     public class MyReactNativeActivity extends ReactActivity {
         /**
          * 这里的ReactNativeView对应index.js中AppRegistry.registerComponent    ('ReactNativeView', () => Root)的ReactNativeView
          */
         @Override
         protected String getMainComponentName() {
             return "HelloWorld";
             //同前强行标注
         }
     }
    

两种写法的区别

写法1:可以将布局通过原生View的addView添加到原生界面内部

写法2:不能实现以上效果,这里是单独一个Activity内的界面。但是这里写法非常简单

manifest.xml配置

  1. 权限
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 悬浮窗权限用于调试弹窗,摇一摇手机~~! -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  1. 调试activity
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
  1. 直接跑起来吧!(记得给悬浮窗权限)

可能遇到的坑

问题:有可能会因为cpu架构的不同,32bit、64bit的so库,导致有些机器跑不起来(大概是这么个理由吧)

解决:在app下的build.gradle中的defaultConfig内添加:

ndk {
            abiFilters "armeabi-v7a", "x86"
        }

问题:react-native-android-failed-to-load-js-bundle

解决:在app/src/main下新建assets文件夹

如果还不行,试试下面这样更新一下,然后rebuild一下项目:

This error happens when someone upgrade react-native version.

$ npm install -g react-native-git-upgrade

$ npm install react-native@latest --save

$ react-native-git-upgrade

如果还是不行!问搜索引擎吧….

机智的提示

有坑的时候,可以先参照纯react-native的demo中的android项目来进行配置,如果解决不了再找搜索引擎。(一般对比后都能搞定)