2015年2月1日日曜日

Go on AndroidでAndroidアプリを作成する

こんにちは。野田(scarviz)です。

Go1.4からNDKを使って、Androidアプリが作れるようになりました。
作れるアプリは以下の2種類になります。

1. UIも含め、完全にGoだけ(All Go)で作るNDK Apps
2. UIはJava(Android SDK)で、ロジックをGoで作るSDK Apps

NDK Appsはゲームアプリを想定しています。UIはOpenGLで書くようになります。
SDK Appsは従来のJNIで作るのをGoで実装するってところですね。

NDK AppsについてはGothamGoの動画でデモがあるので、これを見てもらったら良いと思います。
http://vimeo.com/channels/852217/115307069
このスライドは下のです。
http://talks.golang.org/2014/gothamgo-android.slide#1

ゲームアプリを作りたいならNDK Appsですが、UIをOpenGLで書かないといけないので、
普通のAndroidアプリを作るなら、SDK Appsの方が良いと思います。
ということで、今回はSDK Appsの作り方を説明します。

環境は以下になります。

Go環境:
 マシン:Ubuntu14.04 (VMware Player)
 Goバージョン:1.4.1

Android環境
 マシン:Windows7
 開発環境:Android Studio 1.0.2

GoとAndroidStudioは予め入れておいてください。

環境は分ける必要はないですが、コマンドを打つのが楽なので、Go環境はUbuntuにしてます。


ちなみに2015/2/21(土)にGo on Androidの勉強会やります!
今回の内容ともくもく会になります。

申込フォーム:
http://goo.gl/iSOJvM

G+イベントページ:
http://goo.gl/YRhRw8

良かったら参加してくださいね。


■Go on Androidのビルド環境を作る
Go on Androidのビルド環境を作るには、NDKなどを用意する必要があり、若干面倒です。
Dockerファイルが用意されているので、Dockerでビルド環境を作ろうと思います。
まずはDockerをインストールしましょう。

$ sudo apt-get update
$ sudo apt-get install docker.io

Dockerを有効にし、試しにバージョンを確認します。

$ source /etc/bash_completion.d/docker.io
$ sudo docker --version

go.mobileが必要なので、go.mobileを取得します。

$ go get -d golang.org/x/mobile/...

Dockerファイルでビルド環境を作成します。

$ sudo docker build -t mobile $GOPATH/src/golang.org/x/mobile

下記のように最後に「WORKDIR」が実行され、「Successfully built」が表示されていればOKです。

Step 29 : WORKDIR $GOPATH/src/golang.org/x/mobile
 ---> Running in 321a28e9026b
 ---> 5cfd030b6850
Removing intermediate container 321a28e9026b
Successfully built 5cfd030b6850

出来たDockerイメージを確認してみます。mobileが出来ていればOKです。

$ sudo docker images

REPOSITORY  TAG         IMAGE ID        CREATED         VIRTUAL SIZE
mobile      latest      5cfd030b6850    9 minutes ago   3.32 GB

もし、<none>という名前だったりすると、作成に失敗しています。
ネットワーク環境が悪かったりすると、よく失敗するので、作り直すようにしましょう。
<none>は不要なので、下記コマンドで削除すると良いと思います。

$ sudo docker rmi (<none>のイメージID)

なお、Dockerイメージのubuntuは残しておくと、次にmobileのDockerイメージを作る時に、ubuntuのDockerイメージをダウンロードしなくて済むので、少し速くなります。


■サンプルをビルドしてみる
試しにサンプルをビルドしてみましょう。
go.mobileのlibhelloというサンプルをビルドしてみます。

$ sudo docker run --rm -v $GOPATH/src:/src mobile /bin/bash -c 'cd /src/golang.org/x/mobile/example/libhello && ./make.bash'

成功すると「BUILD SUCCESSFUL」と表示されます。

BUILD SUCCESSFUL
Total time: 6 seconds

libhello/binディレクトリに移動すると、「Hello-debug.apk」というファイルがあります。

$ cd $GOPATH/src/golang.org/x/mobile/example/libhello/bin

adb installで端末にインストールしてみましょう。

$ adb install ./Hello-debug.apk

僕はNexus7(Android4.3)に入れてみました。
「Hello」というアプリが入っていると思います。
起動してみると、上部に「Hello」と出ていると思います。


libhelloディレクトリにあるmake.bashは、最後にAndroidアプリを作るのにantでビルドしています。
アプリはAndroidStudioでビルドするつもりなので、共有ライブラリが欲しいと思います。
次は共有ライブラリの作り方を説明します。


■共有ライブラリを作成する
今回用にGoのサンプルソースを用意しました。
まずは、サンプルソースを取得してください。

$ go get github.com/scarviz/gocalc

gobindをインストールします。

$ go install golang.org/x/mobile/cmd/gobind

サンプルソースのディレクトリに移動します。

$ cd $GOPATH/src/github.com/scarviz/gocalc

"go_" + パッケージ名となるディレクトリを作成します。

$ mkdir calc/go_calc

gobindを使って、必要になるファイルを自動生成します。

$ gobind -lang=go github.com/scarviz/gocalc/calc > calc/go_calc/go_calc.go
$ gobind -lang=java github.com/scarviz/gocalc/calc > calc/Calc.java

go_calc.goは共有ライブラリの作成に必要なファイルです。
main.goにはgo_calcパッケージを含めています。
Calc.javaの方は後でAndroidのプロジェクトに含めます。

では、共有ライブラリを作成します。

sudo docker run --rm -v $GOPATH/src:/src mobile /bin/bash -c 'cd /src/github.com/scarviz/gocalc && ./make.bash'

make.bashの中では、Go.javaとSeq.javaをコピーしていますが、シンボリックリンクの方が好ましいそうです。
WindowsでAndroidアプリを作成するつもりなので、今回はコピーするようにしています。


■Androidアプリを作成する
今回の完成系は以下にあげています。
https://github.com/scarviz/GoCalcApp

作成手順は以下になります。
1. AndroidStudioを立ち上げ、適当なプロジェクトを作成
2. javaディレクトリ以下に、goディレクトリ以下を配置
3. go/calcディレクトリ以下にCalc.javaを配置
4. mainディレクトリ以下にjniLibsディレクトリを作成し、その下にarmeabi-v7aディレクトリ以下を配置

以下のような配置になります。

main
├─java
│  └─go
│      │  Go.java
│      │  Seq.java
│      │  
│      └─calc
│              Calc.java
└─jniLibs
    └─armeabi-v7a
            libgojni.so


ActivityクラスのonCreateメソッドなど、最初の処理でGo.initメソッドを呼び出し、初期化します。

Go.init(getApplicationContext());


後はgoの関数(Calc.javaのメソッド)を、Activityクラスなどから呼び出すように実装してください。
実装したら、Runで端末(またはエミュレータ)にインストールし、実行してみます。


動きましたか?
それGoで動いてるんですよ!
嬉しい気持ちになりますね。すごく嬉しいです。

1 件のコメント:

  1. 「Androidアプリを作成する」でGo.initを呼び出す、という説明を追記しました。
    これが無い状態で、Goの関数呼ぶと例外吐きます!

    返信削除