[Android] Ubuntuで始めるReact Native
これはなに?
React Nativeを使ってAndroidアプリ開発環境を構築したメモです。
お目汚し失礼します。
React Nativeのバージョンは 0.56 です。
あらかじめ必要なもの
- Node 8.3以降とnpm
- JDK 8以降
- Android Studio
Android SDK
順番にインストールしていきます。
Node 8.3以降とnpm
nodesourceからインストールします。
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get update
sudo apt-get install nodejs
参考: https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
JDK 8以降
sudo apt-get install openjdk-8-jdk
sudo update-java-alternatives --set java-1.8.0-openjdk-amd64
Android Studio
snap
を使用してインストールします。
snap install --classic android-studio
snapの外へアクセスできるようにするため--classic
オプションを付けます。
Android SDK
Getting Startedに書いてある以下のものは不要みたいです。
- Android 6.0 (Marshmallow
- Google APIs
- Android SDK Platform 23
- Intel x86 Atom_64 System Image
- Google APIs Intel x86 Atom_64 System Image
- Android SDK Build-Tools
- 23.0.1
環境変数も設定しなくてOKです。
やっと準備が整いました。
React Nativeを始める
CLIをインストール
CLIをインストールします。
sudo npm install -g create-react-native-app
ドキュメントによってはreact-native-cliを使っています。正解は?
プロジェクトを作成
CLIを使ってさくっと。
create-react-native-app AwesomeProject
こんなファイル達ができました。
App.js
app.json
App.test.js
.babelrc
.gitignore
node_modules/
package.json
package-lock.json
README.md
.watchmanconfig
App.js
の中身はこれだけです。
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Text>Changes you make will automatically reload.</Text>
<Text>Shake your phone to open the developer menu.</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
package.json
にある依存性はこれだけです。
"expo": "^27.0.1",
"react": "16.3.1",
"react-native": "~0.55.2"
ここにあるExpoはこういうものらしいです。
Expo is a set of tools, libraries and services which let you build native iOS and Android apps by writing JavaScript.
JavaScriptでネイティブアプリを作るためのツール集ですね。
実行
npm
コマンドから実行します。
npm start
ターミナルにこんなメッセージが出ました。
端末にExpoクライアントをインストールして、QRコードを読めばプログラムが動くようです。QRコードが出るって新しいかも。
自分はエミュレータで動かします。Android Studioからエミュレータを起動します。
エミュレータが起動したら、先ほどのターミナルでa
キーを押します。
こんなメッセージが出ました。
よくわからないですが設定を有効にして再度a
キーを押したらアプリが動きました。
プログラムを少し修正
メッセージと色を変えてみました。
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>こんにちは!リアクトネイティブ</Text>
<Text>Changes you make will automatically reload.</Text>
<Text>Shake your phone to open the developer menu.</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ccf',
alignItems: 'center',
justifyContent: 'center',
},
});
即座に反映されました。
落ち穂拾い
create-react-native-app
とreact-native-cli
Create React Native App(CRNA)は、Expoサービスを使うようにできているそうです。
EJECTING.mdによりますと、App StoreやPlay Storeへ配置するにはCRNAから脱却しないといけないそうです。
CRNAからの脱却
脱却先は2つあります。
- いつものReact Native
- ExpoKit
いつものReact Nativeのほうでは、react-native
コマンドを使って作業するようになります。
ExpoKitのほうでは、Expoのサービスを使い続けられます。
脱却してみる
いつものReact Nativeに脱却してみます。
npm run eject
React NativeにするかExpoKitにするか質問が表示されますので、React Nativeを選びます。
さらにいくつかの質問に答えると、いろいろファイルが書き換えられました。
android
とios
ディレクトリができて、それぞれにネイティブ用のプロジェクトが格納されています。
依存性からはExpoが消えました。
CLIをインストール
react-native-cli
をインストールします。
sudo npm install -g react-native-cli
環境変数ANDROID_HOME
を設定
~/.zshrc
export ANDROID_HOME=${HOME}/opt/Android/Sdk
実行
エミュレータを起動します。
サーバを起動します。
npm run start
エミュレータ内でアプリを起動します。
npm run android
KVMを使う
エミュレータを高速に動かすためにKVMをインストールします。
sudo apt-get install qemu-kvm libvirt-bin
/dev/kvm
を開けるように、自分自身をkvm
グループに追加します。
sudo usermod --append kvm ログインID
gradleのヒープサイズを大きくする
デフォルト1024MBだとコンパイルが遅いので、最低1536MBにします。
~/.zshrc
export GRADLE_OPTS=-Dorg.gradle.jvmargs=-Xmx2048M
エミュレータが固まったら?
Cold Bootするとよいです。
感想
iOSとAndroidのアプリをソース一本で書けるのは、相当な効率アップです。
何かハマリどころが出てきた際、ネイティブの知識に+してReact Native + Reactの知識が必要になるので大変そうです。React Nativeを採用するかどうかは、作成するアプリケーションの規模と複雑さに応じてといったところでしょうか。
すでにiOS/Androidの十分な知識があるひとには、React Nativeとてもいいと思います。