Android Studio Android项目内嵌入React Native混合开发

简介:React Native使你能够在JavaScript和React的基础上获得完全一致的开发体验,构建世界一流的原生APP。
React Native着力于提高多平台开发的开发效率 —— 仅需学习一次,编写任何平台。(Learn once, write
anywhere) Facebook已经在多项产品中使用了React Native,并且将持续地投入建设React Native。


摘自——React Native 中文官网

站在巨人的肩膀上(感谢那些战斗在技术最前沿的大佬们)

创建项目(已有项目跳过)

新建项目

点击下一步

设置最小API

下一步

选择EmptyActivity 作为项目的MainActivity的模板

下一步

项目创建完成

到这一步项目创建完成

下面要将React Native集成到上面的Android项目中

环境搭建

  • Python 2 安装

python下载安装

下载安装完成之后,要添加环境变量

python环境变量配置

node.js安装

召唤出cmd:输入:python 回车提示你版本号就是安装成功了

同样Node.js需要环境配置

步骤一

步骤二

召唤出cmd:输入:node -v 回车提示你版本号就是安装成功了

  • React Native生成相应配置文件

    terminal中输入命令

按顺序执行下边命令

npm init

npm install –save react react-native

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

init 主要根据提醒生成package.json文件

install –save react react-native 安装React 和React Native

curl -o .flowconfig
https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig 下载.flowconfig文件

第一步:npm init 主要是填写各种信息,生成package.json
一步一步操作;
这里只贴一张图下边直接给出整个生成文件

图片

D:\studioworkspace\ReactDemoOne>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (ReactDemoOne) reactdemoone
version: (1.0.0) 1.0.0
description: react demo first
entry point: (index.js) index.android.js
test command: no
git repository: no
keywords: no
author: yaodonglv
license: (ISC) ISC
About to write to D:\studioworkspace\ReactDemoOne\package.json:

{
  "name": "reactdemoone",
  "version": "1.0.0",
  "description": "react demo first",
  "main": "index.android.js",
  "scripts": {
    "test": "no"
  },
  "repository": {
    "type": "git",
    "url": "no"
  },
  "keywords": [
    "no"
  ],
  "author": "yaodonglv",
  "license": "ISC"
}


Is this ok? (yes) yes

第二步:npm install –save react react-native

此处可能很卡一直卡在某个地方
解决方法:
设置npm淘宝镜像,在terminal中执行:
npm config set registry “https://registry.npm.taobao.org

下载node_modules

执行结束会多一个node_modules文件夹

react node_modules

第三步:添加.flowconfig文件

第一种方式执行:
curl -o .flowconfig
https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig 下载.flowconfig文件

第二种:(适用于第一种方法不能自动下载或出现问题的可以使用第二种)
首先在项目根目录新建一个名字是.flowconfig的文件
https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig
然后,直接访问以上链接复制其中的内容,复制到创建的.flowconfig文件中OK
生成.flowconfig文件

  • 文件内容配置

添加”start”: “node node_modules/react-native/local-cli/cli.js start” 到package.json 文件下 scripts标签

{
  "name": "reactdemoone",
  "version": "1.0.0",
  "description": "react demo first",
  "main": "index.android.js",
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "repository": {
    "type": "git",
    "url": "no"
  },
  "keywords": [
    "no"
  ],
  "author": "yaodonglv",
  "license": "ISC",
  "dependencies": {
    "react": "^15.4.2",
    "react-native": "^0.41.2"
  }
}

添加 index.android.js 到项目中去(中间的android开头小写,编辑器直接给我改成大写了)

'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}>Hello, World</Text>
       </View>
     )
   }
 }
 var styles = StyleSheet.create({
   container: {
     flex: 1,
     justifyContent: 'center',
   },
   hello: {
     fontSize: 20,
     textAlign: 'center',
     margin: 10,
   },
 });
 AppRegistry.registerComponent('HelloWorld', () => HelloWorld);

添加后

APP中gradle配置

gradle第一步配置

React Native 支持23,23之上自己有兴趣可以配置一下

图中标记1处compileSdkVersion使用版本23
图中标记2处buildToolsVersion使用版本23.0.1
图中标记3处 minSdkVersion使用版本16
图中标记4处targetSdkVersion使用版本23
图中标记5处6处增加ndk支持

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

packagingOptions {
   exclude "lib/arm64-v8a"
}

解决
java.lang.UnsatisfiedLinkError: dlopen failed: “/data/data/com.microcity.reactdemoone/lib-main/libgnustl_shared.so”is 32-bit instead of 64-bit
找不到so我见问题
图中标记7处
使用

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

解决错误Conflict with dependency’com.google.code.findbugs:jsr305’的问题

gradle2

如果你的和这个不一样修改如下

compile 'com.android.support:appcompat-v7:23.0.1'
compile "com.facebook.react:react-native:+" //此处可写具体版本号更好

整个项目中的 build.gradle

项目Gradle

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

添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
到AndroidManifest.xml

确保这里的react native是最新版本
react native

出现了问题如果版本低于正常版本非常多检查:

maven {
    `url "$rootDir/../node_modules/react-native/android"`//地址是否正确
} 
修改url "$rootDir*/..*/node_modules/react-native/android"为
url "$rootDir/node_modules/react-native/android"

添加Native Code (正式嵌入React Native)

之前官方提供的代码要自己手写很多容易出现很多错误:

public class MainActivity 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.js")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);

        setContentView(mReactRootView);
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy();
        }
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }

    @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);
    }

}

现在官网直接给出一个ReactActivity的基类,我们直接继承就好了

package com.microcity.reactdemoone;
import com.facebook.react.ReactActivity;
import javax.annotation.Nullable;

public class MyReactActivity extends ReactActivity {
    @Nullable
    @Override
    protected String getMainComponentName() {
       return "HelloWorld";//这个在Registry.registerComponent注册
    }
}

是不是很简单

接下来还要添加一个Application,不添加会报错

package com.microcity.reactdemoone;
import android.app.Application;
import com.facebook.react.*;
import com.facebook.react.BuildConfig;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Darksiderl on 2017/2/27.
 */
public class App extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage()
            );
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

}

在AndroidManifest.xml中添加

android:name=".App"

AndroidManifest.xml

这里我没有直接将MyReactActivity做入口,而是从MainActivity点击跳转过去的。

我们这里不用npm start 因为容易卡在

Loading dependency graph, done.

这句话,不知道你们有没有遇到

所以直接去运行你的项目

但是他会报一个这样的错误:

Could not get BatchedBridge, make sure your bundle is packaged
correctly

表示他找不到bundle文件

解决方法

  1. 先去你的文件的main(android/app/src/main)下新建assets文件夹
  2. 然后执行:
$>react-native start
$>react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/

运行的时候可能会出现问题:
‘react-native’ 不是内部或外部命令,也不是可运行的程序
或批处理文件。

解决

terminal 中 执行 npm install -g react-native-cli

然后再去试一下上边的命令,就可以了
另外:

react-native bundle –platform android –dev false –entry-file
index.android.js –bundle-output
app/src/main/assets/index.android.bundle –assets-dest
app/src/main/res/

这个命令中的app/src/main/assets/index.android.bundle路径一定要写对否则会报错不会生成这个bundle文件

个人感觉这个是最行之有效的
其他还有两种方法参考文末的文章

如果是真机(模拟器)的话还要运行

adb reverse tcp:8081 tcp:8081

以上运行的图片

然后再次运行基本就没什么问题了,现在你就可以去搞混合开发了

如果是模拟器参考文末文章的末尾处有介绍此处只介绍真机

本文参考史上最详细的Android原生APP中添加ReactNative 进行混合开发教程

发布了27 篇原创文章 · 获赞 11 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章