公司项目需要频繁更新,因此考虑使用react-native给现有的Android项目进行功能补充。研究了2天,官网的资料坑太多,网上的博客也不适用最新的版本,跑不起来,网上翻了n多篇资料,终于能够运行起来。现在将react-native集成的详细跳坑步骤写一下;
(1)前提:需要按照官网的步骤,搭建环境先,还没搭建好的可以参考中文官网的,这个没坑:https://reactnative.cn/docs/getting-started/
(2)使用的react-native版本:0.57.5
下面开始给我们的现有Android项目集成react-native
1、用Androidstudio打开我们的Android项目,打开下方的 Terminal 命令窗口,默认是我们的工程根目录;使用yarn init命令创建package.json文件,需要填写响应的信息,这里我填了name后全部回车跳过,最后生成。
2、接下来需要安装依赖和 node_modules,还是在根目录下,输入yarn add react-native,安装 React 和 React Native 模块。等待几分钟后,可以看到完成的信息。
往上滚动,看上面的信息,会有warning提示的一句话:
意思就是react-native0.57.5版本需要依赖react的版本是16.6.1,官网说要保持一致性,既然警告了,就安装对应的版本呗,接下来运行yarn add [email protected],这次安装的很快,提示完成的如下
要注意:我现在安装的版本是0.57.5,如果以后更新了这个版本,对应的react版本应该也会更改,所以要记得要去看warning信息,查看对应的react版本。
看一下我们的package.json文件,出现了刚才我们安装的版本,如果版本号前有^符号,把它去掉,固定一下版本;
3、在build.gradle添加仓库:这里记得不要按官网添加的路径,有坑。直接复制下面的就行了
allprojects {
repositories {
maven { url "https://maven.google.com" }
jcenter()
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/node_modules/react-native/android"
}
}
}
dependencies {
compile 'com.facebook.react:react-native:+'
}
4、创建js文件,我直接用了官网的例子,js文件默认要放在根目录下,实际开发不同。
import React from "react";
import { AppRegistry, StyleSheet, Text, View } from "react-native";
class HelloWorld extends React.Component {
render() {
return (
HelloWorld,终于爬出坑了!
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center"
},
hello: {
fontSize: 20,
textAlign: "center",
margin: 10
}
});
AppRegistry.registerComponent("MyReactNativeApp", () => HelloWorld);
5、创建MyReactActivity
public class MyReactActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
private final int OVERLAY_PERMISSION_REQ_CODE = 1; // 任写一个值
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}
}
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")//绑定的是app/src/main/assets中的bundle文件
.setJSMainModulePath("index")//js文件名
.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
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);
}
@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
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
// SYSTEM_ALERT_WINDOW permission not granted
}
}
}
}
}
如果需要访问 DevSettingsActivity
界面(即开发者菜单),则还需要在 AndroidManifest.xml
中声明:
这样就差不多了,在运行Android项目前,我们需要生成bundle文件,也就是编译js代码。
5、构建bundle文件;这里是我爬了最久的坑,官网和网上的资料都说要运行yarn start命令,但是我一直会卡在
就不动了。于是找了很久的资料,才发现其实不需要运行这个start命令,而是在package.json文件中添加另外一句bundle-android命令;
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"bundle-android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/"
}
该命令有2个文件夹路径,其实就是我们的assets文件夹(要保证项目的assets路径和命令中的文件夹路径一致,不然会报找no such file or directory),bundle文件会在这个命令之后在assets文件下生成,我们在app/src/main下创建assets文件夹,然后直接在Terminal窗口执行这个命令:yarn bundle-android
6、运行我们的Android项目到真机或模拟器。需要权限,这里点击允许。
点击跳转到MyReactActivity页面,发现报错了。
是因为我们没有添加ndk的支持,在build.gradle文件中添加
defaultConfig {
ndk{
abiFilters "armeabi-v7a","x86"
}
}
然后编译,重新运行到真机,成功了!
总结:虽然过程比较艰辛,但是现在总结看来其实也不难弄,要注意的是,如果修改了js文件,要重新运行yarn bundle-android命令新的js代码才能生效。写的感觉比较详细了,接下来继续踩其他坑。