React Native for android 初体验

React Native 是什么

“学习一次,到处编写。用 React 构建移动应用程序”—— 官网描述
简而言之, RN(ReactNative)是一种在 Android 和 IOS 上开发跨平台应用的技术。当然不是完全和真正的跨平台,是指的一套 RN 代码,多个平台使用,大致就是这样。听上去很强势的解决了多平台开发的高成本问题。 所以这项技术趋势很明显,有很多大公司产品用的 RN,甚至包括国内的 QQ 和手机百度。
并且我身为一个 React 狂热的爱好者兼安卓开发者,不得不尝试一下这个技术了。虽然有点晚了,但真的早就想尝试了,那么体验开始:

安装

  1. CLI 工具

    npm i -g react-native-cli
              

    终端会多出一个 react-native 命令。

  2. Yarn

    参考这篇文章,react-native 需要 yarn 初始化和管理项目依赖。

创建项目

提供了 CLI 工具,自然要通过它来创建项目了:

react-native init AwesomeProject
          

项目结构

.
          ├── android
          │   ├── app
          │   ├── build.gradle
          │   ├── gradle
          │   ├── gradle.properties
          │   ├── gradlew
          │   ├── gradlew.bat
          │   ├── keystores
          │   └── settings.gradle
          ├── index.android.js
          ├── index.ios.js
          ├── ios
          │   ├── AwesomeProject
          │   ├── AwesomeProjectTests
          │   └── AwesomeProject.xcodeproj
          ├── node_modules
          │   ├── abab
          │   ├── abbrev
          │   ├── absolute-path
          │   ├── ......
          │   └── yeoman-welcome
          ├── package.json
          ├── __tests__
          │   ├── index.android.js
          │   └── index.ios.js
          └── yarn.lock
          
          

启动项目

首先安装应用(cd 到 AwesomeProject 目录):

react-native run-android
          

也可以将 android 目录导入 AndroidStudio,然后用 AS 的 run 按钮安装。

安装完成以后需要发布 JS 部分:

react-native start
          

对着模拟器界面按两下 R 键就可以热更新 ReactJs 的内容了。例如我把 init 时候创建的 index.android.js 修改成了下面这个样子:

/**
           * Sample React Native App
           * https://github.com/facebook/react-native
           * @flow
           */
          
          //noinspection JSUnresolvedVariable
          import React, {Component} from 'react';
          //noinspection JSUnresolvedVariable
          import {
              AppRegistry,
              StyleSheet,
              Text,
              View,
              TextInput,
              ToastAndroid
          } from 'react-native';
          
          export default class AwesomeProject extends Component {
              constructor(props){
                  super(props);
                  this.onInput = this.onInput.bind(this);
              }
          
              onInput(text){
                  ToastAndroid.show(text, ToastAndroid.SHORT);
              }
              render() {
                  return (
                      <View style={styles.container}>
                          <Text style={styles.welcome}>
                              欢迎体验 React Native!
                          </Text>
                          <Text style={styles.instructions}>
                              首先,编辑 index.android.js
                          </Text>
                          <Text style={styles.instructions}>
                              按两下 R 键刷新,{'\n'}
                              Shake or press menu button for dev menu
                          </Text>
                          <TextInput onChangeText={text => this.onInput(text)} style={styles.input} />
                      </View>
                  );
              }
          }
          
          const styles = StyleSheet.create({
              container: {
                  flex: 1,
                  justifyContent: 'center',
                  alignItems: 'center',
                  backgroundColor: '#F5FCFF',
                  borderColor: 'red',
                  borderWidth: 2
              },
              welcome: {
                  fontSize: 20,
                  textAlign: 'center',
                  margin: 10,
              },
              instructions: {
                  textAlign: 'center',
                  color: '#333333',
                  marginBottom: 5,
              },
              input :{
                  width : 150,
                  height: 40
              }
          });
          
          AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
          

可能会遇到的问题

init 项目的时候会由 yarn 安装非常多的 node 依赖,而启动项目的时候会由 gradle 下载一些 Java 的依赖。

这里要注意几点:

  • gradle

    1. 第一次的情况下,gradle 需要通过网络下载,配置地址在 gradle/wrapper/gradle-wrapper.properties 中,跟 AndroidStudio 集成 gradle 的结构是一样的。如果出现网络问题,请自行修改下载地址。
    2. 版本必须是 2.x,我之前改成了最新的 3.2,结果是项目构建失败。提示必须是 2.2 版本(2.x 的最新版2.14也行,但是不能上 3 版本)。
    3. 拉取依赖太慢,自行修改 gradle.properties 文件,加入代理配置,例如:

      systemProp.https.nonProxyHosts=127.0.0.1, localhost
                systemProp.https.proxyPort=8118
                systemProp.https.proxyHost=127.0.0.1
                systemProp.http.nonProxyHosts=127.0.0.1, localhost
                systemProp.http.proxyPort=8118
                systemProp.http.proxyHost=127.0.0.1
                
  • android-sdk

    1. 环境变量,要求必须添加一个 ANDROID_HOME 的变量。我的变量名是 ANDROID_SDK_HOME,很久以前配置的,不想改了,于是采取了方案2,当然我也推荐方案2。
    2. 在 android 根目录下添加 local.properties 文件,写入:

      sdk.dir=${ANDROID_SDK_HOME}
                

      变量自行替换成路径。推荐这个的理由是团队开发时不是每个人都配置正确了环境变量,留一个配置可供修改。

  • Build Tools

    1. 默认 gradle 配置的版本是23.0.1(我发这篇文章时是这个版本),所以你需要打开 Android Sdk Manager 下载安装该版本。
    2. 如果你不想安装这个旧版本,可以修改配置(android/app/build.gradle):

      android {
                    //...
                    buildToolsVersion "${your_version}"
                    //...
                }
                
  • 启动一个 Android(Android Emulator 或者虚拟机、真机有线/无线都行,它会自动使用 adb 连接)

上述全部问题解决完成,即可启动成功。

我基于 React Native 写了一个 Demo。这里还有一篇 Kotlin 开发安卓的文章。

关于 React

如果有比较关注前端技术的朋友看到我博客,就会发现我的博客的前端就是 React 构建的,包括我也发过跟 React 有间接关系的文章
如果你是一个安卓开发者,抵触 React 这个 Web 前端技术那真的大错特错了,因为 React 真的非常棒。

最后

这篇文章只是个试水,在这之外的 React Native 我都未了解。不过我感觉有戏,正好我也不是职业安卓开发者,以后我会逐渐从原生换成这些新技术。反正,随我怎么玩。