Android 集成React Native 到现有的项目踩坑记录

集成步骤

官方文档:https://facebook.github.io/react-native/docs/0.54/integration-with-existing-apps
借鉴博客:https://blog.csdn.net/u012455...node

(1)配置react-native的开发环境
(2)建立一个react-native 的项目
(3)把项目中的android目录里面的东西换成现有的项目
(4)配置android项目的build.gradle文件以及各类依赖
(5)运行项目,运行服务,设置ip端口调试。
(6)各类踩坑问题,好比不支持64位手机的so库问题,找不到服务,因为react native 版本问题致使的各类错误等等

官方文档的集成步骤;
一、安装 node.js python2 jdk 8
这个安装过程就不说了。网上一大堆
二、下载更新React Native CLI
命令:npm install -g react-native-cli
执行这行命令就可使用react-native 命令了。好比 使用命令运行
三、android 环境配置和模拟器或者手机链接
因为我是作android的,因此这些就跳过了,不清楚的看官方文档或者上网查
四、建立新的应用程序
重点来了,建立应用的时候执行命令:react-native init AwesomeProject 这里的AwesomeProject是项目名称能够随便换,可是必须以字母开头。 因为下载是在国外因此特别慢,因此咱们要添加如下国内镜像。python

npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist

这两个均可以,会显著提升下载速度。设置了镜像,而后再执行建立的命令。
五、运行新应用的采坑记录
指定react 和react-native 的版本。
项目目录下的 node_modules 文件夹是 reactnative 所依赖的js的一些东西。
若是没有,咱们能够再项目跟目录执行 npm install 命令下载
这个时候咱们要注意一下版本号,由于这里遇到坑了。目前最新的react--native多是0.56 会出现一个bug
好比最新版本react

react-native-cli: 2.0.1
react-native: 0.56.0

可是运行的时候出现 Unable to resolve module 'AccessibilityInfo' 这个错误,因此建议仍是版本低一点,这里使用稳定版
在这里插入图片描述android

切换步骤:
(1)先将旧版卸载git

npm uninstall -g react-native-cli
npm uninstall -g react-native

(2)再安装指定版本github

npm install -g react-native@0.55.4
npm install -g react-native-cli@1.2.0

能够再项目初始化的时候指定下,不指定的话,只要版本对也没问题,本身查看下npm

react-native init --version="0.55.4" myFirstApp

六、解决红屏错误:Module build failed: Error: Plugin 0 specified in “base” … provided an invalid property of “default”
若是出现上面错误执行下面命令json

npm install --save-dev babel-preset-react-native@2.1.0

七、解决 React_Native 没法运行再64位机器上
"/data/data/com.xxx.xxx/lib-main/libgnustl_shared.so" is 32-bit instead of 64-bit 这个错误
参考文章:https://blog.csdn.net/u013531824/article/details/53931307
Android不能同时加载32和64位本机库。 若是您至少有一个依赖库使用ARM64支持编译的扩展,而另一些依赖库仅支持ARM32,就会出现问题。 系统将检测ARM64依赖关系,加载它,而后拒绝加载仅ARM32的so库,就可能致使应用程序崩溃。
因此,要再项目中excute 64位的几个so库,使用32位的。
这个根据不一样项目设置,查一下本身项目用到了哪些64位的so库,都设置一遍
个人项目须要移除这些,而后就不报错了。Native Libs Monitor 这个软件很好用react-native

ndk {
            //设置支持的SO库架构
            abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
        }

        packagingOptions {
            exclude "lib/arm64-v8a/libgnustl_shared.so"
            exclude "lib/arm64-v8a/libijkffmpeg.so"
            exclude "lib/arm64-v8a/libijkplayer.so"
            exclude "lib/arm64-v8a/libijksdl.so"
            exclude "lib/arm64-v8a/libimagepipeline.so"
            exclude "lib/arm64-v8a/librtmp-jni.so"

        }

八、把android 原生项目拷贝到reactnative 项目的android 目录下
上面步骤能够运行一个react-native 的简单项目,接下来时怎么集成到现有的Android 项目
react-native 项目结构以下:
在这里插入图片描述
咱们作android的话,是用Android studio 打开 android 这个目录的。
六、修改gradle 的依赖配置
dependencies {}闭包下 全部的compile 替换位implementation 或者api由于个人Android studio是3.1.3,老报错说compile 2018年末要删除已废弃。另外个人gradle是4.4 build gradle 工具 是3.1.3
(1)Android 项目根目录的 build.gradle文件修改
以下:若是仍是不行,建议跟我同样,加上google(). .可能若是是最新版 jencter有问题,用的时候调整下顺序试一试。尽可能不要用最新版本的react-nativeapi

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
        //添加这个maven地址,否则没法下载 react-native库
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

再app 的build.gradle 中添加依赖
使用api 或者implementation 均可以, 这里我也制定了版本。

dependencies {
.........
api "com.facebook.react:react-native:0.55.4"
}

七、配置权限

<uses-permission android:name="android.permission.INTERNET" />
//我还要添加一个权限,建议也添加了
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

再调试的时候咱们通常须要访问DevSettingsActivity,因此也须要添加到AndroidManifest.xml:
手机摇一摇,或者菜单,设置 电脑服务的ip地址和端口要用到

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

八、代码集成
刚刚建立的最简单的react-native 已经有了。咱们就再咱们Android 项目中加载这个最简单的页面

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);
        //这里不加权限判断 6.0或以上机型会闪退
        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())
                //这是设置assets目录下的打包过的js文件名 这个文件可用命令生成 但调试期间咱们使用npm server动态注入 发布时才将它打进assets
                .setBundleAssetName("index.android.bundle")
                //这里设置js入口文件 旧一点的api多是setJSMainModuleName 但个人版本是0.51.0 取而代之的是setJSMainModulePath方法
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        // 注意这里的“FirstApp”必须
        // 对应index.js”中的“AppRegistry.registerComponent()”的第一个参数值
        // 对应“package.json”中的“name”属性值
        // 最好也将“app.json”中的“name”和“displayName”改为它
        mReactRootView.startReactApplication(mReactInstanceManager, "FirstApp", null);
        setContentView(mReactRootView);

    }

    @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)) {

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

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

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

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

以上是个人activity,大概意思和官网同样。。代码直接复制就行,须要注意的是:
代码制定的文件名必定要和 配置文件中的一致,要检查
app.json中的name和displayName属性值
ndex.js中registerComponent的第一个参数值
package.json中的name属性值
这几个值要保持一致

九、在真机上运行项目直接在 reat-native 项目根目录运行命令 react-native run-android , 跳转到上面activity而后运行起来若是是红屏,说是连不上服务,就摇一摇手机,选择 Debug server host 啥的,设置电脑的ip:8081 这样就能打开了。或者,直接用Android studio 运行本身的Android 项目, 跳转到上面react 的activity ,也能够是fragment的。 若是出现错误,继续百度谷歌解决。。。有坑是确定的嘛。先记录这些

相关文章
相关标签/搜索