通过上一篇《 React-Native Android 学习笔记——1,配置环境》下载了AwesomeProject项目并运行了 demo。如下图:
应该和你运行起来的相同,但是除了Welcome to React Native@H_404_5@的颜色。
一,index.android.js 文件
demo 默认展示在我们面前的这个页面其实是我们下载AwesomeProject@H_404_5@项目下的
index.android.js@H_404_5@,代码如下:
/** * Sample React Native App * https://github.com/facebook/react-native */
'use strict';
import React,{
AppRegistry,Component,StyleSheet,Text,View,} from 'react-native';
class AwesomeProject extends Component {
render() {
return (
<View style={styles.container}> <Text style={styles.welcome}> Welcome to React Native! </Text> <Text style={styles.instructions}> To get started,edit index.android.js </Text> <Text style={styles.instructions}> Shake or press menu button for dev menu </Text> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#F5FCFF',},welcome: { fontSize: 20,textAlign: 'center',margin: 10,color:'red' },instructions: { textAlign: 'center',color: '#333333',marginBottom: 5,}); AppRegistry.registerComponent('AwesomeProject',() => AwesomeProject);
可以看到我在 welcome 的 style 中设置了color:'red'@H_404_5@,让我的
Welcome to React Native@H_404_5@变成红色字体的。如下:
welcome: {
fontSize: 20,textAlign: 'center',margin: 10,color:'red'
},
下面我们来熟悉一下index.android.js@H_404_5@这个文件里面的 js 代码都是干什么的。
'use strict'@H_404_5@是启动当前文件的 js 代码的严格模式,可以使当前的 js 更严格的条件下运行。想了解的可以学习这篇文章《Javascript 严格模式详解》。
import React,} from 'react-native';
这段代码类似 java 的 import,把需要引用的 module 引入。
class AwesomeProject extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started,edit index.android.js
</Text>
<Text style={styles.instructions}>
Shake or press menu button for dev menu
</Text>
</View>
);
}
}
这段代码是渲染当前注册界面的布局,render@H_404_5@方法下的return 就是返回的当前布局。标签内的 style 对应下面这段代码,和 css 很像,等于 Android layout 文件下 view 的标签设置属性。
const styles = StyleSheet.create({
container: {
flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#F5FCFF',welcome: {
fontSize: 20,color:'red'
},instructions: {
textAlign: 'center',color: '#333333',marginBottom: 5,});
AppRegistry.registerComponent('AwesomeProject',() => AwesomeProject);
上面这段代码把我们 js 文件中的 class AwesomeProject@H_404_5@和我们 Android 项目中
Activity@H_404_5@中
getMainComponentName() { return "AwesomeProject"; }@H_404_5@的 Activity关联起来。
二,显示一个 Toast
React-Native 已经把我们常用的模块都已经封装好了,例如 Toast 在../AwesomeProject/node_modules/react-native/Libraries/Components/ToastAndroid/ToastAndroid.android.js@H_404_5@中。
我们来看 ToastAndroid 的源码:
/** * Copyright (c) 2015-present,Facebook,Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule ToastAndroid */
'use strict';
var RCTToastAndroid = require('NativeModules').ToastAndroid;
/** * This exposes the native ToastAndroid module as a JS module. This has a function 'show' * which takes the following parameters: * * 1. String message: A string with the text to toast * 2. int duration: The duration of the toast. May be ToastAndroid.SHORT or ToastAndroid.LONG */
var ToastAndroid = {
SHORT: RCTToastAndroid.SHORT,LONG: RCTToastAndroid.LONG,show: function ( message: string,duration: number ): void {
RCTToastAndroid.show(message,duration);
},};
module.exports = ToastAndroid;
我们可以直接在引包当中加入ToastAndroid。如下:
import React,ToastAndroid,} from 'react-native';
下面我们来用 ToastAndroid 弹出一个 Toast。在引包后加入代码ToastAndroid.show('Awesome',ToastAndroid.SHORT);@H_404_5@,下面来摇摆手机调出开发菜单,点击
Reload JS@H_404_5@。就会弹出Toast。
我们来分析一下ToastAndroid.android.js@H_404_5@这个 module。
var RCTToastAndroid = require('NativeModules').ToastAndroid;
这里是require@H_404_5@是加载
NativeModules@H_404_5@模块,并把
ToastAndroid@H_404_5@ 赋值给
RCTToastAndroid@H_404_5@。
var ToastAndroid = {
SHORT: RCTToastAndroid.SHORT,};
这段代码,创建一个对象赋值给ToastAndroid@H_404_5@,对象内分别设置了
Toast@H_404_5@的
SHORT@H_404_5@,
LONG@H_404_5@和
show@H_404_5@方法。
module.exports = ToastAndroid;@H_404_5@这里把
ToastAndroid@H_404_5@作为当前这个 Module 导出,提供给外部使用。
那么 JS 是如何 Android 代码关联起来的呢?下面我们来看一下Native 的代码。在 Android Studio 中搜索类 ToastModule@H_404_5@,代码如下:
public class ToastModule extends ReactContextBaseJavaModule {
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "ToastAndroid";
}
@Override
public Map<String,Object> getConstants() {
final Map<String,Object> constants = MapBuilder.newHashMap();
constants.put(DURATION_SHORT_KEY,Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY,Toast.LENGTH_LONG);
return constants;
}
@ReactMethod
public void show(String message,int duration) {
Toast.makeText(getReactApplicationContext(),message,duration).show();
}
}
这里getName()@H_404_5@方法的返回值对应 JS 中的
var RCTToastAndroid = require('NativeModules').ToastAndroid;@H_404_5@结尾处的
ToastAndroid@H_404_5@,正如 js 里的请求手机本地的 modules ,对应到类里的
getName()@H_404_5@返回值。
getConstants()@H_404_5@方法负责把类中的常量映射到 JS 中去。
show(String message,int duration)@H_404_5@方法正是我们要提供给 JS 的方法,方法的注释代表这个方法提供给 JS 调用。
三,自定义 Logger
这里我们来自定义一个 LoggerModule 来练练手。这里我先把代码贴出来了。
public class LoggerModule extends ReactContextBaseJavaModule {
private static final String MODULE_NAME = "Logger";
private static final String TAG_KEY = "TAG";
private static final String TAG_VALUE = "LoggerModule";
public LoggerModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Nullable
@Override
public Map<String,Object> getConstants() {
final Map<String,Object> constants = MapBuilder.newHashMap();
constants.put(TAG_KEY,TAG_VALUE);
return constants;
}
@Override
public String getName() {
return MODULE_NAME;
}
@ReactMethod
public void i(String tag,String msg) {
Log.i(tag,msg);
}
@ReactMethod
public void d(String tag,String msg) {
Log.d(tag,msg);
}
@ReactMethod
public void w(String tag,String msg) {
Log.w(tag,msg);
}
@ReactMethod
public void e(String tag,String msg) {
Log.e(tag,msg);
}
}
这里我把常量TAG@H_404_5@返回给 JS 调用,Module 命名为
Logger@H_404_5@,并且把 info,debug,warn,error 等 Log 方法加上
@ReactMethod@H_404_5@注释,提供给 JS调用。
这里还没有结束,我们还需要实现一个类,去注册我们自己写的 LoggerModule@H_404_5@。具体代码如下:
public class AppReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new LoggerModule(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
然后,把这个 AppReactPackage 注册到 Activity。如下:
public class MainActivity extends ReactActivity {
/** * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. */
@Override
protected String getMainComponentName() {
return "AwesomeProject";
}
/** * Returns whether dev mode should be enabled. * This enables e.g. the dev menu. */
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
/** * A list of packages used by the app. If the app uses additional views * or modules besides the default ones,add more packages here. */
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),new AppReactPackage()
);
}
}
java 代码到这里就结束了。
下面,我们在index.android.js@H_404_5@的同级目录创建一个 js 文件
log.js@H_404_5@。里面内容:
'use strict';
var RCTLogger = require('NativeModules').Logger;//加载本地 modules,Module#getName()
var LogAndroid = {
//添加定义的常量 Module#getConstants()
TAG: RCTLogger.TAG,//添加的方法 Module#d()
d: function(tag: string,msg: string):void{
RCTLogger.d(tag,msg);
},i: function(tag: string,msg: string):void{
RCTLogger.i(tag,w: function(tag: string,msg: string):void{
RCTLogger.w(tag,e: function(tag: string,msg: string):void{
RCTLogger.e(tag,msg);
}
}
module.exports = LogAndroid;//module 导出
这里不用多说了,无非就是创建一个 LogAndroid 对象获取 LoggerModule@H_404_5@java 类中的常量,方法等,并且导出。
下面我贴出完整的index.android.js@H_404_5@,里面显示如何引用:
/** * Sample React Native App * https://github.com/facebook/react-native */
'use strict';
import React,} from 'react-native';
var LogAndroid = require('./log');
LogAndroid.i(LogAndroid.TAG,"Awesome");
LogAndroid.d(LogAndroid.TAG,"Awesome");
LogAndroid.w(LogAndroid.TAG,"Awesome");
LogAndroid.e(LogAndroid.TAG,"Awesome");
ToastAndroid.show('Awesome',ToastAndroid.SHORT);
class AwesomeProject extends Component {
render() {
return (
<View style={styles.container}> <Text style={styles.welcome}> Welcome to React Native! </Text> <Text style={styles.instructions}> To get started,() => AwesomeProject);
重新编译并运行你的 app,看看 logcat 打印出了日志吗?