1.设置目录结构

创建一个空目录用于存放 React Native 项目,然后在其中创建一个/android子目录,把你现有的 Android 项目拷贝到/android子目录中。

2.安装javascript依赖包

在项目根目录下创建一个名为package.json的空文本文件,然后填入以下内容:

{
  "name": "rntestthree",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "16.8.3",
    "react-native": "^0.59.5"
  }
}

scripts中是用于启动 packager 服务的命令。dependencies中的 react 和 react-native 的版本取决于你的具体需求。一般来说我们推荐使用最新版本。你可以使用npm info reactnpm info react-native来查看当前的最新版本。另外,react-native 对 react 的版本有严格要求,高于或低于某个范围都不可以。本文无法在这里列出所有 react native 和对应的 react 版本要求,只能提醒读者先尝试执行 npm install,然后注意观察安装过程中的报错信息,例如require react@某.某.某版本, but none was installed,然后根据这样的提示,执行npm i -S react@某.某.某版本。如果你使用多个第三方依赖,可能这些第三方各自要求的 react 版本有所冲突,此时应优先满足react-native所需要的react版本。其他第三方能用则用,不能用则只能考虑选择其他库。

接下来我们使用 npm(node 包管理器,Node package manager)来安装 React 和 React Native 模块。 请打开一个终端/命令提示行,进入到项目目录中(即包含有 package.json 文件的目录),然后运行下列命令来安装:

$ npm install

这些模块会被安装到项目根目录下的node_modules/目录中(所有通过 npm install 命令安装的模块都会放在这个目录中。这个目录我们原则上不复制、不移动、不修改、不上传,随用随装)。

3.把React Native项目添加到你的应用中

3.1 在你的 app 中 build.gradle 文件中添加 React Native 依赖:

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

如果想要指定特定的 React Native 版本,可以用具体的版本号替换 +,当然前提是你从 npm 里下载的是这个版本 。

在项目的 build.gradle 文件中为 React Native 添加一个 maven 依赖的入口,必须写在 "allprojects" 代码块中:

allprojects { repositories { ... maven { // All of React Native (JS, Android binaries) is installed from npm url "$rootDir/../node_modules/react-native/android" } } ... }

3.2  屏蔽某些平台产生的错误

在app的build.gradle中的defaultConfig配置

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

一些SDK版本也可能产生错误,minSdkVersion 16以上

android {    compileSdkVersion 28    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    defaultConfig {        applicationId "com.example.wind.my_react_app"        minSdkVersion 16        targetSdkVersion 28        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        ndk {            abiFilters "armeabi-v7a", "x86"        }    }    packagingOptions {        exclude "lib/arm64-v8a/librealm-jni.so"    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    implementation fileTree(dir: 'libs', include: ['*.jar'])    implementation 'com.android.support:appcompat-v7:28.0.0'    compile "com.facebook.react:react-native:+"    testImplementation 'junit:junit:4.12'    androidTestImplementation 'com.android.support.test:runner:1.0.2'    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'}

3.2 配置权限:

接着,在 AndroidManifest.xml 清单文件中声明网络权限:

如果需要访问 DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明:

4. 代码集成:

4.1 React Native 组件

创建一个index.js文件

首先在项目根目录中创建一个空的index.js文件。(注意在 0.49 版本之前是 index.android.js 文件)

index.js是 React Native 应用在 Android 上的入口文件。而且它是不可或缺的!它可以是个很简单的文件,简单到可以只包含一行require/import导入语句。本教程中为了简单示范,把全部的代码都写到了index.js

import React from "react";import { AppRegistry, StyleSheet, Text, View } from "react-native";class HelloWorld extends React.Component {  render() {    return (              Hello, World          );  }}var styles = StyleSheet.create({  container: {    flex: 1,    justifyContent: "center"  },  hello: {    fontSize: 20,    textAlign: "center",    margin: 10  }});AppRegistry.registerComponent("MyReactNativeApp", () => HelloWorld);

4.2 配置运行RN的原生activity

我们还需要添加一些原生代码来启动 React Native 的运行时环境并让它开始渲染。首先需要在一个Activity中创建一个ReactRootView对象,然后在这个对象之中启动 React Native 应用,并将它设为界面的主视图。

如果你想在安卓 5.0 以下的系统上运行,请用 com.android.support:appcompat 包中的 AppCompatActivity 代替 Activity

import android.content.Context;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.KeyEvent;import com.facebook.react.ReactInstanceManager;import com.facebook.react.ReactRootView;import com.facebook.react.common.LifecycleState;import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;import com.facebook.react.shell.MainReactPackage;public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {    private ReactRootView mReactRootView;    private ReactInstanceManager mReactInstanceManager;    public static void start(Context context) {        context.startActivity(new Intent(context, MyReactActivity.class));    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mReactRootView = new ReactRootView(this);        mReactInstanceManager = ReactInstanceManager.builder()                .setApplication(getApplication())                .setCurrentActivity(this)                .setBundleAssetName("index.android.bundle")                .setJSMainModulePath("index")                .addPackage(new MainReactPackage())                .setUseDeveloperSupport(BuildConfig.DEBUG)                .setInitialLifecycleState(LifecycleState.RESUMED)                .build();        // 注意这里的MyReactNativeApp必须对应“index.js”中的        // “AppRegistry.registerComponent()”的第一个参数        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);        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);        }        if (mReactRootView != null) {            mReactRootView.unmountReactApplication();        }    }    @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);    }}

如果你使用的是 Android Studio , 可以使用Alt + Enter快捷键来自动为 MyReactActivity 类补上缺失的 import 语句。注意BuildConfig应该是在你自己的包中自动生成,无需额外引入。千万不要从com.facebook...的包中引入!

我们需要把 MyReactActivity 的主题设定为 Theme.AppCompat.Light.NoActionBar ,因为里面有许多组件都使用了这一主题。

5.测试集成结果

5.1 启动开发服务器:

运行应用首先需要启动开发服务器(Packager)。你只需在项目根目录中执行以下命令即可:

$ npm start

如果Packager服务器启动成功,则http://localhost:8081/index.android.bundle?platform=android

能看到如下信息:

var __DEV__=true,__BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),process=this.process||{};process.env=process.env||{};process.env.NODE_ENV="development";(function (global) {  "use strict";  global.__r = metroRequire;  global.__d = define;  global.__c = clear;  global.__registerSegment = registerSegment;  var modules = clear();  var EMPTY = {};  var _ref = {},      hasOwnProperty = _ref.hasOwnProperty;  function clear() {    modules = Object.create(null);    return modules;  }  if (__DEV__) {    var verboseNamesToModuleIds = Object.create(null);    var initializingModuleIds = [];  }

否则,会出现错误信息。

可以重置包服务器:

adb reverse tcp:8081 tcp:8081

npm start

 

5.2 运行应用:

保持 packager 的窗口运行不要关闭,然后像往常一样编译运行你的 Android 应用(在命令行中执行./gradlew installDebug或是在 Android Studio 中编译运行)。

如果你是使用 Android Studio 来编译运行,有可能会导致 packager 报错退出。这种情况下你需要安装watchman。但是 watchman 目前没有稳定的 Windows 版本,所以在 Windows 下这种崩溃情况暂时没有特别好的解决方案。

编译执行一切顺利进行之后,在进入到 MyReactActivity 时应该就能立刻从 packager 中读取 JavaScript 代码并执行和显示:

更多相关文章

  1. android 权限定义的文件,位置
  2. Android Studio中src/main/res/values中strings.xml文件中字符串
  3. 【Android开源项目分析】android轻量级开源缓存框架——ASimpleC
  4. android 应用自身检测版本并下载
  5. Android之SDK、NDK、JNI和so文件
  6. Android:系统信息(内存、cpu、sd卡、电量、版本)的获取
  7. android通过chmod命令实现文件权限修改
  8. Android心得3.2--用SAX解析器解析xml文件内容
  9. Android 用style简化layout布局文件

随机推荐

  1. 常用排序算法复杂度,稳定性相关(记忆贴)
  2. 美团面试官:生成订单后一段时间不支付订单
  3. 【前端词典】进阶必备的网络基础
  4. Zookeeper面试常见11个连环炮
  5. Ansible 之 配置远程主机访问
  6. C语言 循环结构和选择结构(1)
  7. HCIA-以太网帧结构-OSI模型
  8. 5个小技巧彻底搞懂JVM内存模型【针对3年
  9. 【前端词典】Vue 响应式原理其实很好懂
  10. 华为HCIA-传输介质简介