资讯专栏INFORMATION COLUMN

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

cnio / 2750人阅读

摘要:运行新应用的采坑记录指定和的版本。这个软件很好用设置支持的库架构把原生项目拷贝到项目的目录下上面步骤可以运行一个的简单项目,接下来时怎么集成到现有的项目项目结构如下我们做的话,是用打开这个目录的。

集成步骤

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

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

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

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

这两个都可以,会显著提高下载速度。设置了镜像,然后再执行创建的命令。
5、运行新应用的采坑记录
指定react 和react-native 的版本。
项目目录下的 node_modules 文件夹是 reactnative 所依赖的js的一些东西。
如果没有,我们可以再项目跟目录执行 npm install 命令下载
这个时候我们要注意一下版本号,因为这里遇到坑了。目前最新的react--native可能是0.56 会出现一个bug
比如最新版本

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

但是运行的时候出现 Unable to resolve module "AccessibilityInfo" 这个错误,所以建议还是版本低一点,这里使用稳定版

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

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

(2)再安装指定版本

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

可以再项目初始化的时候指定下,不指定的话,只要版本对也没问题,自己查看下

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

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

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

7、解决 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 这个软件很好用

     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"

        }

8、把android 原生项目拷贝到reactnative 项目的android 目录下
上面步骤可以运行一个react-native 的简单项目,接下来时怎么集成到现有的Android 项目
react-native 项目结构如下:

我们做android的话,是用Android studio 打开 android 这个目录的。
6、修改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-native

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"
}

7、配置权限


//我还要添加一个权限,建议也添加了

再调试的时候我们一般需要访问DevSettingsActivity,所以也需要添加到AndroidManifest.xml:
手机摇一摇,或者菜单,设置 电脑服务的ip地址和端口要用到

8、代码集成
刚刚创建的最简单的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属性值
这几个值要保持一致

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96410.html

相关文章

  • react native 实现类似QQ的侧滑列表效果

    摘要:因而对于现有的普通列表界面,要替换成侧滑列表,改动相对小些。如果想要实现类似那样的侧滑效果,就不能给每个按钮都设置背景色,需要稍微投机取巧下。相关代码有分组的侧滑列表无分组的侧滑列表 如果列表行数据需要更多的操作,使用侧滑菜单是移动端比较常见的方式,也符合用户的操作习惯,对app的接受度自然会相对提高点。最近得空就把原来的react-native项目升级了侧滑操作,轻轻松松支持andr...

    张巨伟 评论0 收藏0

发表评论

0条评论

cnio

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<