在macOS系统使用React Native的踩坑过程

最近做公司项目时使用到了React Native,首先需要在公司电脑上配置React Native的开发环境。公司电脑是mac本,那就按照React Native中文网站一步步配置macOS开发平台的开发环境。中间遇到了很多问题,总结一下解决方法把它们一一记录下来。

问题1:必须安装的依赖有:Node、Watchman 和 React Native 命令行工具以及 JDK 和 Andriod Studio。官方推荐使用Homebrew来安装 Node 和 Watchman,安装Homebrew的命令是:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 。
需要访问github网站,但是由于安全性的原因,公司电脑禁止访问github网站,导致安装Homebrew这一步就进行不下去了,在这个地方折腾了很久,后来经过跟同事讨论找到了一种解决方案。从已经安装好react native开发环境的另外一台电脑上拷贝以下文件
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
到公司电脑上。这样brew命令便可正常使用,算是曲线救国吧!

问题2:由于之前已经安装过watchman,所以再次通过brew来安装时有冲突。执行brew install watchman
提示:Warning: watchman 4.9.0 is already installed, it's just not linked. You can use brew link watchman to link this version.
解决方案是:先执行brew uninstall watchman,再执行brew install --HEAD watchman,watchman安装成功。

问题3:通过react-native start启动server时,提示8081端口被占用。
解决方案:修改端口号的方法,参考文章:https://www.jianshu.com/p/ef00ec56507c

问题4:编译项目时提示jcenter中的依赖包下载超时(还是因为公司网络安全策略问题)
解决方法是:在根目录下的build.gradle中修改jcenter的url


222.png

问题5:添加环境变量时需要注意,.bash_profile添加多个PATH时,后面的PATH在最前面都要加上$PATH:,否则会覆盖前面的PATH。


屏幕快照 2018-10-09 下午4.58.04.png

如何实现android原生模块和react native函数的互调?
问题6:react native调用Android原生模块
1.我们首先来创建一个原生模块。一个原生模块是一个继承了ReactContextBaseJavaModule的 Java 类,它可以实现一些 JavaScript 所需的功能。
例如:public class ToastModule extends ReactContextBaseJavaModule
2.要导出一个方法给 JavaScript 使用,Java 方法需要使用注解@ReactMethod。方法的返回类型必须为void。
3.在 Java 这边要做的最后一件事就是注册这个模块。我们需要在应用的 Package 类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在 JavaScript 中被访问到。
4.这个 package 需要在MainApplication.java文件的getPackages方法中提供。这个文件位于你的 react-native 应用文件夹的 android 目录中。
5.原生模块还支持一种特殊的参数——回调函数。它提供了一个函数来把返回值传回给 JavaScript。

问题7:Android原生模块调用react native函数
原生模块可以在没有被调用的情况下往 JavaScript 发送事件通知。最简单的办法就是通过RCTDeviceEventEmitter,这可以通过ReactContext来获得对应的引用,像这样:
...
private void sendEvent(ReactContext reactContext,
String eventName,
@Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
...
WritableMap params = Arguments.createMap();
...
sendEvent(reactContext, "keyboardWillShow", params);

问题8:在android手机上运行react-native项目时,报错:unable to load script from assets 'index.android bundle' , make sure your bundle is packaged correctly or youu're runing a packager server。
解决方案:
第一步:在 android/app/src/main 目录下创建一个 assets空文件夹
第二步:在项目根目录下执行下面这段命令
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
会发现 assets文件夹下生成index.android.bundle文件
第三步:重新执行 react-native run-android
总结:这个index.android.bundle毫无疑问就是用来调用原生控件的js脚本,每次当你改变了index.js,你都需要使用上面的代码片段,来及时的更新index.android.bundle,然后打包才可以把新的index.js应用上,所以当没有index.android.bundle文件时,RN是无法运行的。

问题9:React Native版本无法升级到0.20.1以上版本的原因
Android项目默认的依赖包的源jcenter(),打开网址https://bintray.com/bintray/jcenter/com.facebook.react:react-native/view
发现jcenter()上并不包含最新版的React Native(官方只更新到0.20.1)。
在React Native项目中,Android 项目需要在android/app/build.gradle文件中,添加React Native依赖:compile "com.facebook.react:react-native:+" // From node_modules,默认使用的是node_modules/react-native/android/com/facebook/react/react-native目录下的react native版本。然而Android原生项目中并不存在node_modules目录,如何才能引用到最新的react native版本呢?经过各种尝试,终于找到了一种解决方案。
将node_modules/react-native/android/com/facebook/react/react-native目录下下载的react-native-0.xx.x.aar包加入到Android工程的libs目录下,并引用该aar包,但是你编译时会发现报错提示你缺少XXX等等,为什么呢?这是因为这个aar中还依赖了其它的jar or aar,所以我们需要把这些包也给implementation进来,我们看下具体有哪些包?打开node_modules/react-native/android/com/facebook/react/react-native中的pom文件,里面就是所有的依赖,在build.gradle中配置依赖如下:
implementation 'javax.inject:javax.inject:1'
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.facebook.fbui.textlayoutbuilder:textlayoutbuilder:1.0.0'
implementation 'com.facebook.fresco:fresco:1.3.0'
implementation 'com.facebook.fresco:imagepipeline-okhttp3:1.3.0'
implementation 'com.facebook.soloader:soloader:0.1.0'
implementation 'com.google.code.findbugs:jsr305:3.0.0'
implementation 'com.squareup.okhttp3:okhttp:3.6.0'
implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.6.0'
implementation 'com.squareup.okio:okio:1.13.0'
implementation 'org.webkit:android-jsc:r174650'

先总结到这里,后续开发中遇到新的问题再更新。

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

推荐阅读更多精彩内容