我们一起学ReactNative(四):原有Android项目引入ReactNative

上面的文章,介绍了怎样创建一个React Native项目,不过实际中,很少直接开一个React Native空项目进行开发,都是在原有Android项目中引入React Native开发,那应该怎样进行配置呢?

原有Android项目引入React Native

正常来说,在公司开发中,Android和iOS不同端是在不同的目录下,不同的SVN权限。React Navite作为跨平台,放在任意一个目录下都不行,那么需要创建ReactNavite目录和其他项目同级。目录结构如下:

  • AndroidRNStudy存放原有的Android项目
  • IOSRNStudy存放原有的IOS项目
  • RNStudy存放接下来要开发的RN代码

参考了网上的不同文章,觉得或多或少都存在问题,毕竟,React Native现在还在不停更新,稍后变化就会导致出错,所以,建议,参考第一篇文章,先创建一个最新的React Native,然后,再通过对比拷贝不同的文件到该项目中,就可以减少错误,又保持最新,出错的时候还可以对比一下!

创建Android项目模拟原有项目

需要记住创建的项目名称,后续会使用到

创建React Native所需文件

新建package.json文件

package.json配置了React Native所需的依赖库以及一些脚本语,由于我们RN项目是放在一个单独文件下的,所以,该文件需要放在RNStudy文件下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
// name修改和项目的名称一样
"name": "AndroidRNStudy",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.3.1",
"react-native": "0.55.4"
},
"devDependencies": {
"babel-jest": "22.4.3",
"babel-preset-react-native": "4.0.0",
"jest": "22.4.3",
"react-test-renderer": "16.3 .1"
},
"jest": {
"preset": "react-native"
}
}

#### 添加react和react-native 模块

在RNStudy文件下执行如下命令

1
➜  RNStudy npm install --save react react-native

执行完成后,会创建node_modules文件夹以及package-lock.json,存放各种文件,有则表示添加成功。

新建index.js文件

该文件是RN程序的入口文件,这个内容基本都是拷贝第一篇创建项目中的内容,再进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import React, { Component } from 'react';
import {
AppRegistry, // 查看是否有import该值,没有会楚翔找不到变量:AppRegistry
Platform,
StyleSheet,
Text,
View
} from 'react-native';

const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});

type Props = {};
class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit App.js
</Text>
<Text style={styles.instructions}>
{instructions}
</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});

AppRegistry.registerComponent('AndroidRNStudy', () => App);

Android项目中引入RN

在Android项目中配置ReactNative依赖

在app的build.gradle文件中添加react-native依赖库

1
compile "com.facebook.react:react-native:+"

在project的build.gradle文件中添加上面react-native依赖库的本地仓库地址,这样,就会直接在RNStudy目录下的node_modules的android文件夹中进行查找。如果地址写错,就使得去jcenter()仓库下载依赖,但是其存放的是旧版,没有再进行更新了,会导致接下来找不到ReactApplication等错误的出现。

1
2
3
maven { 
url "$rootDir/../RNStudy/node_modules/react-native/android"
}

编译一下,看看react-native的版本是否为新的,而且还是和上面的package.json版本是否一致。

use a compatible library with a minSdk of at most 15
引用React Native的依赖库,编译的时候,会提示支持最低的sdk版本为16,修改minSdk为16或者在AndroidManifest.xml中强制使用,但可能会在运行在发生异常,下面的修改方法,但是,还是建议采用方法一。

创建RN视图承载的Activity

1
2
3
4
5
6
7
8
9
10
11
package com.guidongyuan.androidrnstudy;

import com.facebook.react.ReactActivity;

public class MainActivity extends ReactActivity {

@Override
protected String getMainComponentName() {
return "AndroidRNStudy";// 这个和在AppRegistry中的项目名字要保持一致
}
}

创建Application实现ReactApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MyApplication extends Application implements ReactApplication {

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
// 检出一下,是否为true,false的话,接下来不能进入调试模式
return BuildConfig.DEBUG;
}

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

@Override
protected String getJSMainModuleName() {
return "index"; // 获取JS的主入口,为index.js,老版本的为index.android.js,区分好,否则运行的时候,会提示找不到该文件。这个也是新版本做的修改,看一些教程,该文件内是不一样的,保持和最新创建的空项目一致就没问题。
}
};

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

@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}

修改AndroidManifest.xml

添加响应的权限以及声明Application和Activity

1
2
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
1
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>

运行调试

在RNStudy目录下,执行该命令

1
➜  RNStudy react-native start

哈哈哈,是不是终端在Loading dependency graph, done.就一直不动了。这里只是重现一下,因为我就在这里被坑到,还坑了很久,揪心。

上面的命令,是启动调试服务器,应用都还没有安装,怎样进行调试呢?只好,先按Ctrl + C停止终端。在Android Studio中执行Run App,把应用安装到手机上。

编译到手机,是不是出现错误呢?出现内容如下

174007

这个错误的出现,频率特别高,后来又因为另外一种原因,导致出现了,这里重新进行编辑错误的解决办法,出现错误的原因,就是找不到bundle包,解决办法就两种:

  • 打bundle数据包到项目中,后期编写了React Native代码后,发包发出去,也是需要打bundle数据包到项目中的。

    创建assets文件

    1
    ➜  ReactNativeMix mkdir ./AndroidRNStudy/app/src/main/assets

    生成index.android.bundle文件

    ➜  ReactNativeMix react-native bundle --platform android --dev false --entry-file index.js --bundle-output ./AndroidRNStudy/app/src/main/assets/index.android.bundle --assets-dest ./AndroidRNStudy/app/src/main/res/
    
  • 启动调试服务器,然后在线去加载服务器里面的bundle数据包。

    1
    ➜  RNStudy react-native start

选择第二种方式,启动调试服务器。

又出现错误,错误内容如下,可以仔细看提示,就是端口问题,应该设置和电脑一样的端口,错误那里要告知怎样修改了。

175249

重新设置一下

1
➜  RNStudy adb reverse tcp:8081 tcp:8081

重新执行react-native start命令,如果还是卡住,摇晃手机,调出设置悬浮窗,点击Reload就可以成功加载到数据了,如果还是不行,在Android Studio中重新编译运行App,就可以了。

184105

看到这个界面,表示一切正常了!感觉要重视网络测试这方面,避免容易出现很多坑,第一篇文章也被网络方面花费很多时间,这次也有!接下来,又继续回到真正的开发而不是配置各种环境。

参考资料

公众号:亦袁非猿

欢迎关注,交流学习