为了把 React Native 集成到 Android 原生项目中, 踩了很多坑, 因为作为 web 前端开发, 本来就不熟悉安卓, 参考了网上很多文章, 但是都很旧了, 而 React Native 已经升级到了 0.55 版本了, 入口文件已经合成了一个 index.js, 下面的内容也是基于这个版本实践的.
环境搭建
已经搭建好 React Native 环境的可以跳过, 还没有的可以参考 React Native 中文网的 搭建教程, 比较详细.
创建 Android 原生项目
安卓开发者自然很熟悉这个步骤, 然而对于 web 前端开发者还是比较迷茫的. 可以参考一下 使用 Android Studio 创建一个新的 Android 工程, 创建一个 Empty Activity, 接下来会比较好操作.
集成 React Native
步骤一: 安装相关依赖
在项目根目录下执行 npm init 命令, 生成 package.json 文件, 添加以下命令
- "scripts": {
- "start": "node node_modules/react-native/local-cli/cli.js start"
- }
执行 npm i react react-native -S 安装 react 和 react-native
步骤二: 配置 maven
在你的 app/ 目录下的 build.gradle 文件中的 dependencies 里添加 React Native 依赖:
- dependencies {
- ...
- compile "com.facebook.react:react-native:+"
- }
在项目根目录下的 build.gradle 文件中为 React Native 添加一个 maven 依赖的入口, 必须写在 "allprojects" 代码块中:
- allprojects {
- repositories {
- ...
- maven {
- url "$rootDir/node_modules/react-native/android"
- }
- }
- }
步骤三: 代码集成, 创建我们的 react-native 组件, 在根目录下创建 index.js,(在 react-native 0.49.0 版本以前, 是 index.android.js 和 index.ios.js 作为入口文件, 现在合成一个 index.js 文件了)
- import React, {Component} from 'react';
- import {AppRegistry,View,Text} from 'react-native';
- class App extends Component{
- render(){
- return (
哈哈哈
- )
- }
- }
- AppRegistry.registerComponent('ReactNativeView', () => App);
然后创建 MyReactActivity,Activity 是安卓中基本的页面单元, 简单的说, 可以看做 web 开发中的一个 html 页面.
在上面创建安卓项目的时候, 已经创建了一个 MainActivity, 在它的同级目录下, 在 Android Studio 右键新建一个 Activity, 命名为 MyReactActivity, 然后把内容改为如下:
- package com.example.administrator.androidreactnative;
- import javax.annotation.Nullable;
- import com.facebook.react.ReactActivity;
- public class MyReactActivity extends ReactActivity {
- @Nullable
- @Override
- protected String getMainComponentName() {
- return "ReactNativeView";
- }
- }
接着创建 MainApplication
- package com.example.administrator.androidreactnative;
- import android.app.Application;
- import com.facebook.react.ReactApplication;
- import com.facebook.react.ReactNativeHost;
- import com.facebook.react.ReactPackage;
- import com.facebook.react.shell.MainReactPackage;
- import com.facebook.soloader.SoLoader;
- import java.util.Arrays;
- import java.util.List;
- public class MainApplication extends Application implements ReactApplication {
- private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
- @Override
- public boolean getUseDeveloperSupport() {
- return BuildConfig.DEBUG;
- }
- @Override
- protected List getPackages() {
- return Arrays.asList(
- new MainReactPackage()
- );
- }
- };
- @Override
- public ReactNativeHost getReactNativeHost() {
- return mReactNativeHost;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- SoLoader.init(this,false);
- }
- }
最后在 app/src/main/AndroidManifest.xml 文件中, 添加一些权限, 以及声明 MainApplication 跟 MyReactActivity
- package="com.example.administrator.androidreactnative">
- android:name=".MainApplication"
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:supportsRtl="true"
- android:theme="@style/AppTheme">
- android:name=".MyReactActivity"
- android:label="@string/app_name"
- android:theme="@style/AppTheme">
原生页面跳转到 react-native 页面
在 MainActivity 添加一个按钮跳转到 MyReactActivity, 首先在 app/src/main/res/layout 下的 activity_main.xml 添加一个按钮元素
- android:id="@+id/btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="点击跳转到 RN 界面"/>
然后在 MainActivity 里添加点击跳转事件
- package com.example.administrator.androidreactnative;
- import android.support.v7.app.AppCompatActivity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- public class MainActivity extends AppCompatActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- // 点击按钮跳转到 react-native 页面
- findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- startActivity(new Intent(MainActivity.this,MyReactActivity.class));
- }
- });
- }
- }
然后在 Android Studio 的模拟器中打开就可以看到以下页面:
同时执行 npm start 启动本地服务器, 点击按钮, 出现了红屏, 也就是错误页面.
从错误信息 error: bundling failed: NotFoundError: Cannot find entry file index.android.js in any of the roots 我们可以看出找不到入口文件 index.android.js, 而我们的入口文件是 index.js, 因此我们需要另外加一些配置让它知道我们的入口文件其实是 index.js
解决方法参考 react-native/issues/16517. 在 app/ 目录下的 build.gradle 文件中最上面添加
- apply plugin: 'com.android.application' // 这时原来存在的
- apply from: "../node_modules/react-native/react.gradle"
- project.ext.react = [
- entryFile: "index.js"
- ]
然后在 MainApplication 的 ReactNativeHost 类中添加:
- private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
- ...
- // 这是需要添加的
- @Override
- protected String getJSMainModuleName() {
- return "index";
- }
- }
重新在模拟器中运行, 就可以正常跳转到 react-native 的页面了.
[本文为 51CTO 专栏作者 "林鑫" 的原创稿件, 转载请通过微信公众号联系作者获取授权]
戳这里, 看该作者更多好文
来源: http://zhuanlan.51cto.com/art/201806/576177.htm