RN: 0.34 运行在 Android 的问题

今天闲来无事, 想使用 RN 工程在 Android 设备上面跑跑.

想看看运行效果怎么样?!

适合读者

  • 有 Android 开发基础.
  • 会使用 Android Studio.
  • 初级 React Native 的开发者.

开发环境和工具

  • Android Studio 2.2
  • ReactNative 0.34
  • Android 模拟器
  • Mac 操作系统

预期效果

不出所料, 真的不能一帆风顺的 Run.

在我的博客 ReactNative: 不一样的 HelloWorld 中展示了 RN 在 iOS 上面的运行情况.

今天还是这个例子, 部署和运行到 Android 上面.

效果如下:
1

在这个过程中, 遇到几个问题.

特此记录.

问题描述和解决

问题1: 直接运行 crash

log 描述(部分)

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mzrntutorial, PID: 5849
java.lang.RuntimeException:
Unable to start activity ComponentInfo{com.mzrntutorial/com.mzrntutorial.MainActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.facebook.react.ReactApplication
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)

解决方案:

Manifest.xml 配置 Application 名称

android:name=”.MainApplication”

问题2:

1
could not get batchedbridge make sure your bundle is packaged correctly

解决问题1后, 再次运行, 会报问题2.
该问题是因为没有启动本地的 server.

使用 Xcode 可以自动运行本地 server.
可以参考博客 React Native 如何启动 local server

解决方案:

手动启动 server.

cd 项目根目录

1
react-native start

问题3:

模拟器没有 menu 按键, 无法 Reload

这个其实不是什么大问题, 但是对于初学者, 也算是一个问题.

新版的 Android SDK 创建的模拟器没有 menu 按键了

解决方案:

连续按两次字母 r 即可刷新.

这些问题, FB 后面肯定会解决的.
阿门!

附录(代码)

index.ios.js

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import React, { Component } from 'react';
import {getPlatformString, isIOS} from './js/Generals/Utils/IDSRNPlatformUtil';
import MZButton from './js/ReactUIKit/MZButton'
import {
AppRegistry,
StyleSheet,
Text,
View,
Platform,
TouchableOpacity,
TouchableHighlight
} from 'react-native';
// 调用其他模块方法
var os = getPlatformString();
var iosPlatform = isIOS();//when run on 'ios' true
class MZRNTutorial extends Component {
constructor(props)
{
super(props);
this.state = {status:1};
}
customPressHandler = () => {
alert('当前状态: ' + this.state.status);
this.state.status = 2;
}
render() {
console.log('render ...');
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Near use React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.android.js
</Text>
<Text style={styles.instructions}>
Press 'R' twice to reload,{'\n'}
or shake for dev menu
</Text>
{/* 显示当前平台信息*/}
<Text style={styles.welcome}>
current os: {Platform.OS}
</Text>
{/*
<TouchableOpacity
style={styles.button}
onPress={this.customPressHandler}
>
<Text style={styles.buttonText}>确定</Text>
</TouchableOpacity>
*/}
<MZButton text="确定?" bgColor="green" dianjishijian={()=>{alert('居然点击确定?!')}}>
</MZButton>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
height: 40,
width: 150,
borderRadius: 20,
justifyContent: 'center',
backgroundColor: 'green',
overflow: 'hidden'
},
buttonText: {
textAlign: 'center',
color: 'white'
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
flowRight: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch'
},
});
AppRegistry.registerComponent('MZRNTutorial', () => MZRNTutorial);

MZButton.js

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
44
45
46
47
48
49
50
51
52
53
54
55
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Platform,
TouchableOpacity
} from 'react-native';
//-----------------------------------------------------
//外部使用该模块, ES6需要使用关键字 export default
//-----------------------------------------------------
export default class MZButton extends Component
{
constructor(props)
{
super(props);
this.state = {status:1};
}
costumPressHandler = () => {
alert('当前状态:' + this.state.status);
const {dianjishijian} = this.props;
dianjishijian();
};
// 使用属性值设置背景颜色
// style={[styles.button], {backgroundColor:this.props.beijingyanse}}
render() {
//解构
const {text, bgColor} = this.props;
return (
<TouchableOpacity
style={[styles.button], {backgroundColor:bgColor}}
onPress = {this.costumPressHandler}
>
<Text style={styles.buttonText}>
{/* 使用属性值 */}
{this.props.text}
</Text>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
button: {
height: 40,
width: 150,
borderRadius: 20,
justifyContent: 'center',
backgroundColor: 'green',
overflow: 'hidden'
},
buttonText: {
textAlign: 'center',
color: 'white'
}
});

IDSRNPlatformUtil.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React, { Component } from 'react';
import {
Platform
} from 'react-native';
export function getPlatformString()
{
console.log(Platform.OS);
return Platform.OS;
}
export function isIOS()
{
return Platform.OS === 'ios';
}
export function isAndroid()
{
return Platform.OS == 'android';
}
坚持原创技术分享!