Android项目接入React Native详细分析及跳坑

RN嵌入app所踩的坑

本篇文章不会包括RN中的相关概念,生命周期等内容,
只包括在接入过程中所遇到的一些问题,
接入RN的平台为Android,开发环境为mac.

官方文档

首当其冲抛出官方文档,接入是基于官方文档的.
下面会列出接入的步骤以及所遇到的问题.
官方文档

问题及注意点汇总

先描述接入过程中遇到的问题及注意事项,后面会在接入过程中给出相关解决办法.

  1. android项目依赖的RN版本不对.
  2. react 引入版本不对.
  3. 真机调试
  4. 运行时libgnustl_shared.so使用的版本不对

接入步骤

创建android项目

正常使用Android Studio创建Android项目.
目前创建的项目就是常规的项目,跟RN还没有任何关系.

添加RN相关依赖

使用npm命令创建项目并添加依赖

按照顺序在项目根目录执行下面的命令

//初始化package.json
$ npm init
//安装react react-native并保存.此处可能会导致一些问题,参见后面的问题
$ npm install --save react react-native
//获取.flow的配置文件
$ curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig

上面三步是项目接入RN的基础,因为需要通过npm来下载RN相关的环境依赖.

需要注意如下几点

  1. 初始化项目,需要注意根目录的位置,也就是执行npm init时所在的目录,
    此处是我遇到的第一个坑,导致问题1的产生.无论时我们创建的项目本身,还是用到的RN的第三方库,
    都需要引用RN框架,RN框架的引入是通过本地maven库的方式引入的,而对RN项目引入的路径是在build.gradle中写死的(引入的第三方库).
    所以如果RN的初始化的目录不对,会导致找不到RN框架,或者RN框架的版本不对.(因为不指定本地库的话,默认时从jcenter中拉取的,但是RN的最新版本是没有提交到jcenter的,所以会出错,或者拉取的版本不对).
    下图为目录结构图,reactnativeintergration为root目录.android目录下,是我们创建的android项目的代码.我们的项目及第三方的RN库对RN本身的依赖都是通过$rootDir/../node_modules/react-native/android来查找的.所以如果相对路径不对,则会出现该问题Failed to resolve: com.facebook.react:react-native.

目录结构图

按照这样的目录结构,我们执行npm init的位置应该是在reactnativeintegration目录下.

2.由于执行npm install时未指定RN以及react的版本,所以获取的版本并不一定是我们需要的.
此处遇到了另外的坑,也就是问题2.
未指定版本时,使用默认安装的,则react安装的版本为15.x.
而使用15.x是会报该错误的Unable to resolve module react/lib/ReactDebugCurrentFrame
解决的办法就是指定依赖的react版本为16.xx.

npm install -save react@~16.0.0-alpha.6

参考文章
3.flow的作用.
第三个命令时复制flow的配置文件,没什么问题.
flow是Facebook用来给js添加静态类型的库,
详细可以参考flow官网

添加运行命令

在package.json中的的scripts标签下添加如下命令.
添加之后可以直接运行npm start启动bundle server.

"start": "node node_modules/react-native/local-cli/cli.js start"

创建index.android.js文件

此处是添加一个RN的页面.具体代码不贴,参照代码index.android.js.

为Android项目中添加RN依赖

RN在native层是需要项目进行依赖的.所以需要在build.gradle中添加项目依赖.
示例项目中是依赖RN0.43.4版本的.需要注意的是,对于本地maven库的添加,如果不指定maven库的地址则会通过jcenter仓库去获取,但是RN最新版本的库是没有传到jcenter中的.所以需要在build.gradle中添加maven中心库,添加的maven库需要指向node_modules中,就是因为这个原因,所以需要在第一步通过npm init初始化项目时,将目录位置指定正确,否则就会遇到问题1

//添加RN库的依赖,指定版本
//app/build.gradle
dependencies {
    ...
    compile "com.facebook.react:react-native:0.43.4" // From node_modules.
}
//添加maven本地库
//root/build.gradle
allprojects {
    repositories {
        ...
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
    ...
}

添加权限

访问网络的权限时必须的.
<uses-permission android:name="android.permission.INTERNET" />
overlay的权限根据不同的target api进行不同的处理.
我的示例中的target-api设置的为22.所以没有适配新的权限系统.
也就是说,如果你是22以上的项目,则需要动态获取下在其他界面之上绘制内容的权限.
添加权限

添加Native代码

RN是需要一个运行渲染环境的,我的代码中将这些操作放在一个Activity中,
当然也可以放在Fragment中.此处需要注意的是,Activity的theme需要设置为@style/Theme.AppCompat.Light.NoActionBar,因为有些第三方的组件依赖该theme.
具体代码参考示例RNContainerActivity类.

运行app

1.正常安装app
2.执行adb reverse tcp:8081 tcp:8081
这么做是为了做端口转发,端口转发后,当手机访问http://localhost:8081时,
会被转发到执行该命令的电脑上的8081端口.
从而访问到bundle.js文件.此处对应问题3.
推荐一篇文章关于reverse命令的
3.运行时提示出现so找不到的问题.
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/reactnative.com.yftx.reactnativeintegration/lib-main/libgnustl_shared.so" is 32-bit instead of 64-bit
我的测试手机时pixel xl,由于cpu架构不同,会导致找不到so库,
因为在初始化创建项目时,没有指定需要包含哪些cpu架构的so文件.
通过参照通过react-native init创建的项目中的build.gradle添加上相关so依赖即可.

总结及代码

接入过程总体来说不是很复杂,暂时先写这么多.
只需要注意一下上面提到的几个问题就行了.
欢迎关注我的这个项目,技术含量没有,但是后面会有比较详细的接入的注释.
项目代码

未完成的部分

1.RN项目同Native项目之间通讯.
2.Native类容器ReactInstanceManager的使用.
3.bundle的打包及部署.
4.热更新的方式.
5.RN的裁剪.
上面几块会分别写还是更新改文档还不确定,欢迎大家关注.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容