react-native爬坑(1)————给现有的Android项目集成

公司项目需要频繁更新,因此考虑使用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 (
      <View style={styles.container}>
        <Text style={styles.hello}>HelloWorld,终于爬出坑了!</Text>
      </View>
    );
  }
}
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
                }
            }
        }
    }
}
 <!-- 联网权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <activity
            android:name=".MyReactActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        </activity>

如果需要访问 DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明:

 <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

这样就差不多了,在运行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代码才能生效。写的感觉比较详细了,接下来继续踩其他坑。

猜你喜欢

转载自blog.csdn.net/as36331233/article/details/84198069
今日推荐