1.新建Android原生项目
为了测试,我先用Android Studio新建一个android原生项目,在MainActivity(主视图,应用启动加载的第一个activity)的界面文件中增加一个跳转到RN界面的按钮。
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.qyp.testrn.MainActivity"> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击进入RN页面" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
主界面如下:
2.安装JavaScript依赖包
在Android项目的根目录下新建package.json,并写入以下内容
{ "name": "MyReactNativeApp", "version": "0.0.1", "private": true, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start" }, "dependencies": { "react": "16.0.0-alpha.6", "react-native": "0.44.3" } }
然后在package.json文件所在目录运行以下命令来安装
npm install
3.将ReactNative添加到你的原生应用中
3.1 修改app/build.gradle文件
如下图
3.2 在项目的 build.gradle 文件中为 React Native 添加一个 maven 依赖的入口
必须写在 "allprojects" 代码块中:
url "$rootDir/node_modules/react-native/android"
4.配置权限
在AndroidManifest.xml清单文件中声明网络权限
<uses-permission android:name="android.permission.INTERNET" />
如果需要访问开发者菜单界面,在AndroidManifest.xml中申明
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
5.代码集成
5.1 编写index.android.js
在android项目目录下新建index.android.js文件(在0.49版本之后是index.js文件)
编写你的RN入口代码:
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}>Hello, ReactNative</Text> </View> ) } } var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', }, hello: { fontSize: 20, textAlign: 'center', margin: 10, }, }); AppRegistry.registerComponent('MyRNApp', () => HelloWorld);
5.2 编写从原生界面跳转到RN界面的Activity
我们还需要添加一些原生代码来启动React Native的运行时环境并让它开始渲染。首先需要在一个Activity中创建一个ReactRootView对象,然后在这个对象之中启动React Native应用。代码如下:
package com.example.qyp.testrn; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; 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; /** * Copyright (c) [email protected]. All rights reserved. */ public class MyReactActivity extends AppCompatActivity 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.android")//根目录下index.android.js文件 .addPackage(new MainReactPackage())//如果为true,则会启用诸如JS重新加载和调试之类的开发人员选项.反之打包 .setUseDeveloperSupport(true) .setInitialLifecycleState(LifecycleState.RESUMED) .build(); Intent intent = this.getIntent(); // 注意这里的 MyRNApp 必须对应“index.android.js”中的 // “AppRegistry.registerComponent()”的第一个参数 mReactRootView.startReactApplication(mReactInstanceManager, "MyRNApp", null); setContentView(mReactRootView); } @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 boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { mReactInstanceManager.showDevOptionsDialog(); return true; } return super.onKeyUp(keyCode, event); } //我们还需要把后退按钮事件传递给React Native: @Override public void invokeDefaultOnBackPressed() { super.onBackPressed(); } }
注意:需要将MyReactActivity在AndroidManifest.xml中申明
5.3 修改主视图MainActivity.java
添加按钮点击事件,跳转到RN界面,如下:
import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(),MyReactActivity.class); startActivity(intent); } }); } }
6.测试集成结果
6.1 运行packager
在项目的根目录下执行
npm start
6.2 运行你的应用
保持packager的窗口运行不要关闭,然后像往常一样编译运行你的Android应用。
注意:
1.在手机的应用权限管理中开启“显示悬浮窗”的权限
2.在开发者菜单的“Dev Settings”中设置 “Debug server host & port for device”,即本机地址+端口号,如:192.167.31.107:8081
3.如果你是使用Android Studio来编译运行,有可能会导致packager报错退出。这种情况下你需要安装watchman。但是watchman目前没有稳定的Windows版本,所以在Windows下这种崩溃情况暂时没有特别好的解决方案。packager很容易出现报错退出的情况,一般重新执行 npm start 即可。