【稀饭】react native 系列教程之已有项目接入React Native
来源:互联网 发布:黄金的价格怎么算法 编辑:程序博客网 时间:2024/04/29 07:36
概述
本文是基于目前公司的一个真实项目编写的,由于是边实践边记录,遇到什么问题和如何解决的,所以你看这篇文章的时候,可能有时候会觉得不是很流畅,特此说明。
引入React Native
build.gradle配置
- 1
- 1
react-native的res使用到了23sdk的资源,因此编译的sdk要求是23
- 1
- 2
- 1
- 2
但这样如果你项目中使用到了HttpClient这个类的话,由于sdk 23版本已经将其移除掉,所以要多加配置
- 1
- 2
- 3
- 1
- 2
- 3
项目原来的gradle版本是1.2.3,但这句配置需要升级到最新版本2.0.0
- 1
- 2
- 3
- 1
- 2
- 3
gradle-wrapper.properties
- 1
- 1
react-native的minSdkVersion是16
- 1
- 1
如果你在AndroidManifest.xml配置了该项,并且低于16,为了编译通过,需配置overrideLibrary
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
还需添加react native的DevSettingActivity
- 1
- 1
multiDex
然后试着编译运行,结果报错,原因是由于引进react-native,方法超出了64k限制,需要拆分dex。
再配置build.gradle
- 1
- 2
- 3
- 1
- 2
- 3
然后自己的Application继承MultiDexApplication,或者重写attachBaseContext方法
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
RN配置本地仓库
这下编译通过了,但是发现react-native版本是0.21,并不是最新版本的,所以这里我们要将项目目录修改为react-native项目目录。
创建了DX目录,将原来的项目Android移到二级目录,然后剩下的几个文件和node_modules可以从react-native初始项目中拷贝过来(也可以执行npm init&npm install命令,但是太慢了),修改package.json里面的name为项目名称。
react-native项目中android项目的文件夹名称是为‘android’,刚好和我们原来的android项目一致,但是是否一定要取名为‘android’有待验证。
接着,修改android项目的根目录下的build.gradle
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
添加了本地仓库,url填写的是node_modules目录下的react-native
好了,重新编译一下,react-native版本是0.31的了(目前官网最新的版本是0.34,本地还没有更新)。
本地打开RN界面
实现ReactApplication接口
首先需要在自己的Application,比如本项目中的ElnApplication实现ReactApplication接口,重写getReactNativeHost方法,给RN提供一个默认的ReactNativeHost
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
创建Activity继承ReactActivity
新建TestRnActivity类,并继承ReactActivity
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
编写js代码
接着打开项目的index.android.js,修改代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
然后和普通RN项目运行一样,运行项目,就看到可以打开RN界面了。
本地给RN界面传递参数
那在打开RN界面时,有时候需要传递参数,那该如何呢?
打开TestRnActivity.Java重写getLaunchOptions方法
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
然后js代码调用
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
这样就可以获取到des参数了。
打包
在我们开发完后,需要将应用进行打包,这里说明下RN和android项目混合开发的打包事项
混淆
按照官网的混淆配置还是报错
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
混淆配置增加这句
- 1
- 1
配置bundle gradle打包命令
在build.gradle配置
- 1
- 1
然后执行在项目下执行命令(dev环境)
- 1
- 1
遇到各种编译问题。。。。
执行gradlew assembleDevRelease命令异常
- 1
- 1
修改gradle.properties
- 1
- 1
和gradle版本
- 1
- 1
还是报错duplicate file。。。
开始排查定位错误因素。。。
- gradle 版本2.2.0,引入react.gradle,assembleRelease报错
- gradle 版本2.1.0-2.1.3,引入react.gradle,assembleRelease报错
- gradle 版本2.1.3,去掉react.gradle的引入,assembleRelease可以正常打包
在去掉脚本的引入因素之前,尝试修改buildTools和gradle版本号,还是报各种错。。。
无奈之下,先放弃使用脚本打包,转向手动打包。
使用bundle手动打包命令
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
目的是将bundle包生成放在android项目的assets文件夹下
然后项目去掉react.gradle脚本的引入,执行assembleDevRelease,成功打包,解压压缩包,在assets下可以看到多了两个bundle文件。
安装运行,也可以正常打开RN界面
多业务分模块
考虑到真实项目场景,可能不止一个RN入口,有多个业务模块需要使用到RN,但是它们的入口可能又不同,如一开始的图,比如在‘发现’大模块下,有两个小功能模块需要使用RN技术来实现,那么此时就需要各自打开各自的RN界面,那么这种需求如何实现呢?
单bundle
你可能想到了,那就是,一个新的入口,那么我就再建一个ReactActivity。没错的,那么我们创建下TestRnActivity2类。
同TestRnActivity一样,继承ReactActivity,但是getMainComponentName返回不同的名称,加以区别。
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
接着,js端,打开index.android.js,编写eln2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
可以看到我们registerComponent了两个组件,eln和eln2。
最后按上面的打包流程,在assets下生成bundle文件,再打包成apk,安装运行。
点击‘测试RN2’,进入第二个RN界面。
嗯,这样看起来好像初步实现了需求,但是在思考下,如果每次某个模块修改了,就需要更新整个bundle。是否可以这样:各自模块独立,更新也独立?
多bundle
使用多bundle的方案,首先需要让各自的模块加载自己的bundle文件。
修改TestRnActivity和TestRnActivity2,分别重写getReactNativeHost方法
TestRnActivity.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
TestRnActivity.java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
两个模块的bundle文件分别取名为eln1.android.bundle和eln2.android.bundle,它们的js入口文件分别为eln1.android.js和eln2.android.js
接着,需要在js层编写这两个文件。在RN项目目录下创建eln1.android.js和eln2.android.js(和之前的index.android.js同级)
eln1.android.js
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
eln2.android.js
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
然后使用react-native bundle命令分别生成这两个bundle文件
- 1
- 1
- 1
- 1
最后,打包、安装、运行即可。
但是,你会发现发现eln1和eln2这两个模块并没多少代码,它们的bundle文件就达到来的500多k了,那后面岂不是更大。是的,这是因为react-native在生成bundle文件的时候,会把你import到的模块都打包进去。比如eln1和eln2都使用到了react和react-native模块,那它们的bundle都打包了这两个模块文件。所以,如何优化bundle文件也是个问题,这里给出了58和携程对bundle拆分的方案,满满的干货。
- 基于 React Native 的 58 同城 App 开发实践
- React Native Bundle拆分
58是通过生成一个common bundle,然后和不同模块的bundle进行diff拆分,客户端再进行合并;而携程是直接修改react-native bundle脚本命令,过滤不需要的依赖模块。
总结
本文讲述了,在原有的android项目上集成RN,并就遇到的问题,自己摸索着,记录着,也有对项目多模块多业务方案的一点思考。而每个人的现有项目各不相同,遇到的问题也不尽相同,但就像和我一样,一步一步踩着坑过来,你也会成功的,踩坑的过程就是你成长的步伐。
- 【稀饭】react native 系列教程之已有项目接入React Native
- 【稀饭】react native 系列教程之已有项目接入React Native
- react native 系列教程之已有项目接入React Native (转载)
- 【稀饭】react native 实战系列教程之项目介绍
- 【稀饭】react native 实战系列教程之项目初始化
- 【稀饭】react native 实战系列教程之完成首页
- 【稀饭】react native 实战系列教程之自定义原生模块
- 【稀饭】react native 实战系列教程之数据存储
- 【稀饭】react native 实战系列教程之首页列表UI实现
- 【稀饭】react native 实战系列教程之影片数据获取并解析
- 【稀饭】react native 实战系列教程之Navigator实现页面跳转
- 【稀饭】react native 实战系列教程之自定义原生UI组件
- 【稀饭】react native 实战系列教程之热更新原理分析与实现
- [置顶] 【稀饭】react native 实战系列教程之热更新原理分析与实现
- React Native 之 教程
- Android原生项目接入React Native
- React Native系列之Native Modules
- React Native系列之Native Modules
- iOS批量自动打包和部署(Ⅲ)
- node.js中的cassandra-cql操作
- 启动mapreduce任务失败会报一下错误:
- 使用Echarts公司年会展示图
- win2003 克隆账号
- 【稀饭】react native 系列教程之已有项目接入React Native
- Asp.Net MVC控制器中Action的返回值类型
- PHP7 连接 MongoDB 语法如下
- vue.js
- 我的2016—勿忘初心,方得始终
- 【期末课程设计----通讯录系统】
- Win32 编程基础
- 创新不止 ▏Focussend荣获“2016中国(行业)十大创新企业”称号
- navigationController push动画 从下往上,类似于presentView的默认动画效果如何实现