Android
Scala
sbt
Docker
android-sdk-plugin

ScalaでAndroid開発 - Docker編

More than 3 years have passed since last update.

AndroidやScala/sbtも日進月歩なので、変化追い易くなればと思い Docker で開発環境を作ってみた。

今回はDockerの勉強を兼ねて Ubuntu 14.04 ベースで Android SDK + sbt のイメージを作ったので、これを使ってScalaでのAndroid開発の環境を準備した。Dockerとの役割分担の方針として:


  1. sbtでのビルドやAndroidデバイスの定型操作などCUI操作はDockerのコンテナ上でやる

  2. 実機USB接続やエミュレータ実行、IDE起動はオーバーヘッドの少ないホスト機でやる

  3. 両者の通信は、adbサーバの5037番ポートをDockerコンテナからホスト機にSSHフォワードして行う

ことにした。


(1) Dockerのセットアップ

ホスト機にMacを使っているので boot2docker を入れる。

この記事などを参考にした。

$ brew install boot2docker

$ boot2docker init
$ boot2docker up


(2) Dockerイメージの動作確認

下のコマンドで、Android SDK + sbt + sshd が入ったイメージ ( ikuo/android-sbt ) からコンテナが起動する。初回はイメージのダウンロードで小一時間かかる。

$ docker run -it --rm -p 7022:22 ikuo/android-sbt:0.2 "`cat ~/.ssh/id_rsa.pub`"

最後の引数にある id_rsa.pub は、コンテナにssh接続する時に使う鍵ファイル。

動作確認なので --rm をつけて終了時にコンテナを消すようにしてある。

-p 7022:22 でコンテナの22番ポートにホスト機(boot2dockerの場合はboot2docker-vm)の7022番をフォワードする。

boot2dockerの場合はさらにこの記事 などを参考に、ホスト機の7022番をboot2docer-vmの7022番にフォワードさせておく:

# Macでoot2docker 使っている場合の追加手順

$ VBoxManage controlvm "boot2docker-vm" natpf1 "ssh to android-sbt,tcp,127.0.0.1,7022,,7022"

コンテナが起動したらホスト機からコンテナに下のようにSSH接続して、adbサーバが使う5037番をホスト機にフォワードしておく。adbのclient/server構成やポート番号などはこちらを参考にした。

$ ssh ubuntu@localhost -p 7022 -R 5037:localhost:5037 -Nv

ホスト機で、 adb start-server してから適当なエミュレータ起動や実機接続をしておくと、コンテナ上のadbコマンドからホスト機のAndroidデバイスが見えるようになる。

ubuntu@xxxxxxxxxx:~$ adb devices

List of devices attached
999673041154999 device

※ ホスト機でadbサーバが起動していない場合は error: protocol fault (no status) のような表示になる。


(3) android-sdk-plugin でのビルド

最近自分はsbtでのAndroidプロジェクトのビルドにandroid-sdk-pluginを使っているので、先のDockerのイメージも android-sdk-plugin に必なものだけを含めた。sbt-android plugin との違いはこちらにあったりする。

今回は既に android-sdk-plugin ベースのプロジェクトが手元にあったので、git cloneした後に下のように android update project を実行して Android SDK のパスを設定した。

ubuntu@...:~/work/myproject$ android update project -p . -t android-19

ubuntu@...:~/work/myproject$ git checkout proguard-project.txt

※ proguardの設定が上書きされたのでgitでリセット(2行目)

その後sbtでapkをビルドしてrunすると、ホスト機上のエミュレータや実機端末でアプリが無事に起動した。

ubuntu@...:~/work/myproject$ sbt android:package

ubuntu@...:~/work/myproject$ sbt run

動作確認に使ったアプリはこちら


(4) IDEでのファイル編集

レイアウトファイルなどはホスト機の IDE (IntelliJ IDEA) でレンダリング確認しながら編集したいので、こちらの手順を参考にファイル共有をセットアップした。

$ docker run -itd -v /data --name my-data busybox /bin/sh

$ docker run --rm -v /usr/local/bin/docker:/docker -v /var/run/docker.sock:/docker.sock svendowideit/samba my-data
$ boot2docker ip
192.168.59.103

上のコマンドは svendowideit/samba というイメージをもとに my-data という名前でファイル共有用のコンテナを起動するもの。my-dataコンテナは間違って消してしまわないように-itdオプションをつけてシェルをバックグラウンドで起動してある。

\192.168.59.103\data に共有フォルダができるので、MacならここにFinderで「サーバに接続」すると /Volumes/data にCLIでファイルを読み書きできるようになる。ここにコンテナからアクセスするには起動時に--volumes-from my-dataをつけて /data を読み書きする。

ということで(2)のコンテナ起動にこのオプションをつけると、android-sbtのコンテナ起動コマンドは下のようになった:

$ docker run -it --rm -p 7022:22 --volumes-from my-data ikuo/android-sbt:0.2 "`cat ~/.ssh/id_rsa.pub`"

ubuntu@...:~$ sudo chown -R ubuntu /data

後は /data 以下にプロジェクトファイルをgit cloneするなりして編集&ビルドすればOK。