大家好,渣渣又又来了。说到React Native,我没想到我的第一个评论和迄今为止所有的留言都来源于React Native。之所以这方面内容更新间隔那么久,除了自己生病和工作进度的原因,还有就是各种bug把我搞得死去活来,这大概就是自己太渣渣的结果吧,希望读者也能给我一些帮助...
本次我们进行React Native移植原生的Android项目。
前期的具体配置,请点击查看上篇博文
Android项目配置:
首先,我们需要建立一个工程。在这里我是新建一个一个名为ReactNative的文件夹,再在当前当前文件夹里直接用Android Studio建立了一个名为android的工程。
其次,在我们项目的build.gradle中添加React Native依赖并同步,具体代码如下:
compile "com.facebook.react:react-native:+"
然后,在AndroidManifest.xml中添加网络权限,具体如下:
<uses-permission android:name="android.permission.INTERNET" />
此时注意,一定要在AndroidManifest.xml中,配置DevSettingsActivity,否则摇晃手机并打开开发者菜单后,点击Dev Setting,会直接Crash,具体如下:
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
添加原生代码:
在项目的MainActivity中,我们要启用调用React Native库,具体代码如下:
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "test";
}
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}}
添加JS:
在项目根目录打开cmd命令行,输入命令运行npm init,该命令会让你输入name,version等等,除了name小写输入,其余默认不输入即可,一路回车,创建一个package.json文件,比如我生成的文件内容如下:
{
"name": "native",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^15.1.0",
"react-native": "^0.27.2"
}
}
此时,在"scripts"标签添加如下代码:
"start": "node node_modules/react-native/local-cli/cli.js start"
然后在项目根目录下执行npm install安装依赖模块,生成node_modules文件
接着,在别的博文里都是执行curl -o .flowconfig https://raw.githubusercontent.com/facebook/react-native/master/.flowconfig 进行flow配置,但是作为Windows开发环境,我们没有curl命令去下载文件。最简单的方法,直接在浏览器里打开这段网址,会出现以下内容:
<span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">将浏览器打开的上面的内容复制,新建文本文档复制进去,将其名字(包含.txt)改名为o.flowconfig即可。</span>
[ignore]
# We fork some components by platform.
.*/*.android.js
# Ignore templates with `@flow` in header
.*/local-cli/generator.*
# Ignore malformed json
.*/node_modules/y18n/test/.*\.json
# Ignore the website subdir
<PROJECT_ROOT>/website/.*
# Ignore BUCK generated dirs
<PROJECT_ROOT>/\.buckd/
# Ignore unexpected extra @providesModule
.*/node_modules/commoner/test/source/widget/share.js
# Ignore duplicate module providers
# For RN Apps installed via npm, "Libraries" folder is inside node_modules/react-native but in the source repo it is in the root
.*/Libraries/react-native/React.js
.*/Libraries/react-native/ReactNative.js
.*/node_modules/jest-runtime/build/__tests__/.*
[include]
[libs]
Libraries/react-native/react-native-interface.js
flow/
[options]
module.system=haste
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
experimental.strict_type_args=true
munge_underscores=true
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-8]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-8]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version]
^0.28.0
此时,我们还要在gradle中配置下列代码使其加载我们最新库
allprojects {
repositories {
jcenter()
maven {
url "$projectDir/../../node_modules/react-native/android"
}
}
}
最后,就是创建我们的js文件,创建一下文件命名为:index.android.js,然后在里边添加如下代码:
'use strict';
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
class MyAwesomeApp extends React.Component {
render() {
return (
<View >
<Text style={styles.hello}>恭喜你已经完成React Native移植Android项目</Text>
</View>
)
}
}
var styles = StyleSheet.create({
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
AppRegistry.registerComponent('test', () => MyAwesomeApp);
运行App
这个时候基本代码就写完了,bug就要来了,还是如同上篇博文一样,使用如下命令即可:npm start开启服务器,然后再执行react-native run-android命令编译运行应用。
在这个阶段,你可能会遇到以下问题:
1.java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so
java.lang.RuntimeException: An error occured while executing doInBackground()
Caused by: java.lang.UnsatisfiedLinkError: could find DSO to load: libreactnativejni.so
打开应用直接闪退
解决方案:找不到so文件错误,在gradle文件的defaultConfig标签下添加如下代码:
ndk {
abiFilters "armeabi-v7a", "x86"
}
2.Error: NDK integration is deprecated in the current plugin
解决办法:打开gradle.properties文件,在文字最下面添加以下代码:
android.useDeprecatedNdk=true
3.你以为这回该好了吧,nonono,你甚至还可能遇到这个问题:java.lang.IllegalArgumentException: You cannot keep your settings in the secure settings.
解决方法:恭喜你,你的targetSdkVersion是不是23,是不是6.0的系统,往下降降版本吧,试试22?这个主要是6.0的权限检查问题
4.你以为这回好了吧?年轻人还得学习一个,魅族手机你还能遇到这个问题:com.android.ddmlib.InstallException:Failed to install .....
这个解决方法我就有点懵逼了,还希望读者也可以给我一个为什么:解决方案:
将gradle里的dependencies标签下的gradle版本号改为1.2.3,如下所示:
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
5.你是不是以为这就行了?native!你忘了上个版本里的我们设置的端口了吗?想想大明湖畔的柳岩,我们的ip是不是变了,大红屏是不是说网络连接失败?
解决方法:摇一摇手机,点击dev setting,设置端口。这个时候还记得前文所述在AndroidManifest里配置的activity,如果你没有配置,你会报下面的错误
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.zhangyu.android/com.facebook.react.devsupport.DevSettingsActivity}; have you declared this activity in your AndroidManifest.xml?
老老实实的在AndroidManifest里配置吧
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
终于终于,当我们看到下面类似的画面,开森的欢呼吧,这么多bug我已精疲力尽...
最后的最后,我想说,我要攒钱买个苹果本,Windows报的错真的太多了,我也想说安卓的国内厂商,一段代码在四个手机上报错都不一样,真的好心酸....
最后的最后的最后,谢谢您的阅览,欢迎斧正!