React-Native Android 学习笔记——2,自定义 logger

前端之家收集整理的这篇文章主要介绍了React-Native Android 学习笔记——2,自定义 logger前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

通过上一篇《 React-Native Android 学习笔记——1,配置环境》下载了AwesomeProject项目并运行了 demo。如下图:

应该和你运行起来的相同,但是除了Welcome to React Native的颜色。

一,index.android.js 文件

demo 默认展示在我们面前的这个页面其实是我们下载AwesomeProject项目下的index.android.js代码如下:

/** * 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',让我的Welcome to React Native变成红色字体的。如下:

welcome: {
  fontSize: 20,textAlign: 'center',margin: 10,color:'red'
},

下面我们来熟悉一下index.android.js这个文件里面的 js 代码都是干什么的。

'use strict'是启动当前文件的 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方法下的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,});

标签的具体规范可以看这里TextView

AppRegistry.registerComponent('AwesomeProject',() => AwesomeProject);

上面这段代码把我们 js 文件中的 class AwesomeProject和我们 Android 项目中 ActivitygetMainComponentName() { return "AwesomeProject"; }的 Activity关联起来。

二,显示一个 Toast

React-Native 已经把我们常用的模块都已经封装好了,例如 Toast 在../AwesomeProject/node_modules/react-native/Libraries/Components/ToastAndroid/ToastAndroid.android.js中。
我们来看 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);,下面来摇摆手机调出开发菜单,点击Reload JS。就会弹出Toast。
我们来分析一下ToastAndroid.android.js这个 module。

var RCTToastAndroid = require('NativeModules').ToastAndroid;

这里是require是加载NativeModules模块,并把 ToastAndroid 赋值给 RCTToastAndroid

var ToastAndroid = {

  SHORT: RCTToastAndroid.SHORT,};

这段代码,创建一个对象赋值给ToastAndroid,对象内分别设置了ToastSHORTLONGshow方法
module.exports = ToastAndroid;这里把ToastAndroid作为当前这个 Module 导出,提供给外部使用。
那么 JS 是如何 Android 代码关联起来的呢?下面我们来看一下Native 的代码。在 Android Studio搜索ToastModule代码如下:

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()方法的返回值对应 JS 中的var RCTToastAndroid = require('NativeModules').ToastAndroid;结尾处的ToastAndroid,正如 js 里的请求手机本地的 modules ,对应到类里的getName()返回值。
getConstants()方法负责把类中的常量映射到 JS 中去。
show(String message,int duration)方法正是我们要提供给 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返回给 JS 调用,Module 命名为Logger,并且把 info,debug,warn,error 等 Log 方法加上@ReactMethod注释,提供给 JS调用
这里还没有结束,我们还需要实现一个类,去注册我们自己写的 LoggerModule。具体代码如下:

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的同级目录创建一个 js 文件log.js。里面内容

'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 对象获取 LoggerModulejava 类中的常量,方法等,并且导出。
下面我贴出完整的index.android.js,里面显示如何引用:

/** * 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 打印出了日志吗?

猜你在找的React相关文章