您的位置:首页 > Web前端 > React

我在集成ReactNative过程中踩过的那些坑

2016-03-15 19:17 585 查看

1、react-native init 命令创建的项目不能以数字开头

例如react-native init 58RNProject非法,react-native init WubaRNProject合法

2、依赖react-native后,也sync过了为什么找不到react-native相关类

需添加apply from: “react.gradle”及compile ‘com.facebook.react:react-native:0.20.+’并在defaultConfig中配置ndk

这里我碰到了第一个坑,sync完整个项目中依然找不到com.facebook.react.*。然后尝试build一下,build完后就可以看到com.facebook.react中的类了。

3、依赖react-native后sync工程特别慢,甚至出现AS OOM的情况

在我踩坑过程中,发现加入compile ‘com.facebook.react:react-native:0.20.+’后,sync工程及其的慢,而且最终报unable to save settings failed to save settings. please restart android studio。但在一个新项目或代码量较小的项目中没有问题,估计是目前58NA的体量太大导致的。这个问题花费了我一整天的时间调试或重新安装Android studio来定位问题。

通过查阅stackoverflow,发现是Android Studio内存问题。修改Contents/bin/studio.vmoptions

-Xms2048m
-Xmx2048m
-XX:MaxPermSize=1280m
-XX:ReservedCodeCacheSize=512m
-XX:+UseCompressedOops


虽然sync过程中还会出现卡顿,但起码不会再报unable to save settings错误

4、build/intermediates/res/merged/release/values-v23/values-v23.xml:3 : AAPT: Error retrieving parent for item: No resource found that matches the given name ‘android:TextAppearance.Material.Widget.Button.Inverse’.

将项目的compileSdkVersion修改为23即可

5、将compileSdkView修改为23后找不到org.apache.http下的类

这是因为23以上的API已不提供org.apache.http相关类,如果这个问题涉及的逻辑不太多建议还是与时俱进修改下逻辑吧,如果不想改,好吧,给你一剂良方。

在gradle中添加

android{
useLibrary 'org.apache.http.legacy'
}


6、修改compileSdkVersion为23后,如果项目中有使用Notification,需改成NotificationCompat.Builder实现

7、编译时bundleDebugJsAndAssets/bundleReleaseJsAndAssets执行失败

若在build工程中出现bundleDebugJsAndAssets任务或bundleReleaseJsAndAssets任务执行失败,需要修改react.gradle中的bundleDebugJsAndAssets/bundleReleaseJsAndAssets任务。这两个任务的核心是执行react-native bundle命令。

修改前:

if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine "cmd", "/c", "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}",
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
} else {
commandLine "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}",
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
}


修改后:

if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine "cmd", "/c", "node", "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
} else {
commandLine "node", "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}",
"--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
}


详情参考:https://github.com/facebook/react-native/pull/6272

8、自定义View使用时报错renderToHardwareTextureAndroid of native type
boolean

修改js文件,以我测试用的EditText为例

'use strict';
import React, {
requireNativeComponent,
PropTypes
} from 'react-native';

var View = React.View;

var iface = {
name : 'EditText',
propTypes : {
...View.propTypes,
hint : PropTypes.string,
text : PropTypes.string
},
};

module.exports = requireNativeComponent('RCTEditText',iface);


增加var View = React.View后在propTypes中增加..View.propTypes

9、自定义View的属性不生效

使用ReactProp注解声明方法时,误用成

com.facebook.react.uimanager.ReactProp


应该使用

com.facebook.react.uimanager.annotations.ReactProp


10、so文件如何打包

RN只提供了armeabi-v7a和x86的so文件,而现项目中其他so文件都是armeabi的。armeabi-v7a能够兼容armeabi,所以理论上将项目中的armeabi下的so文件全部编译成armeabi-v7a或直接放到armeabi-v7a目录下可以打包成功,但却不能完全避免因为so文件找不到而引起的崩溃。那么换个思路,将RN的armeabi-v7a的所有so文件放到项目中的armeabi目录下就可以了。

首先,需要知道RN都提供了哪些so文件?

我懒得去翻RN的aar,直接将原始已经集成RN的apk包以zip解压看lib下都有哪些so文件,然后将所有armeabi-v7a下的so拷贝到项目中的armeabi目录下,同时修改gradle脚本,增加:

sourceSets {
main {
jniLibs.srcDirs = ['libs']
}


编译时却报.so文件重复。

原来RN引用的一些其他框架,例如fresco已经提供了armeabi。



然后我把刚刚拷贝到armeabi下的所有RN引用的第三方框架已经提供的so文件全部删除,最终剩下



编译后可以正常运行并成功调用RN。

为了减小安装包的体积,58同城摒弃了RN提供的x86文件,在application的gradle脚本中增加

defaultConfig {
ndk {
abiFilters "armeabi"
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: