どうも、水谷です。
今日は、GoMobileについて書こうと思います。
めっちゃ面白いですよ、GoMobile。
勉強し始めたばかりなので、これから始めようっていう方向けの記事です。
ごりごりやってる方には物足りないと思います。
今回は、GoMobileでAndroid用ライブラリを作成しようと思います。
開発環境はmacです。
なんでGoでライブラリ?
弊社では、AndroidとiOSのどちらにもアプリをリリースしています。
そして、1.5からiOSへのライブラリも生成できるようになりました。
ということなら、ビジネスロジック部分を、Goでライブラリー化できれば、開発の手間が省けると思ったからです。
何はともあれ、インストールしよう
とりあえず、もうGomobile使えるよって人はスルーでオッケーです。
まずはbrewを更新
sudo brew update
・ここで以下のエラーが出る場合
Cowardly refusing to
sudo brew
・/usr/localのファイル所有者が自分自身になっている可能性があるので、以下のコマンドを実行し、所有者をrootに戻す。
sudo chown -R root /usr/local
gvmのインストール
gvmは、なんかよくわからないけど、rvmとかそういうやつっぽい。
goのバージョン管理ができるのが便利なので、使ってみます。
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
・$HOME/.bash_profileに、以下のコマンドが書き込まれているか確認する。
[[ -s "$HOME/.gvm/scripts/gvm" ]] && source "$HOME/.gvm/scripts/gvm"
書き込まれていなければ、追記する。
一度、ターミナルを閉じるか、sourceする。
go1.5をインストールする。
gvm install go1.4 // 1.4がないと1.5がコンパイルできないため、先にインストール
gvm use go1.4 // go1.4を使用
gvm install go1.5.2 // go1.5.2をインストール
gomobileのインストール
go get golang.org/x/mobile/cmd/gomobile
gomobile init -v
サンプルライブラリを作ってみよう
まぁ、定番ですね。HelloWorldって文字列を返すだけの、どこにでもあるサンプルです。
// goのソースを作成
cd $GOPATH/src
mkdir facescene
cd facescene
mkdir mobile
cd mobile
vi helloworld.go
// Android向けにコンパイル
gomobile bind -target android
// 作成されたライブラリを確認
ls
hello.aar helloworld.go
・helloworld.go
package hello
func World() string {
return "Hello, world!"
}
ここで、作成されたhello.aarというファイルがAndroid用のライブラリになります。
gomobile bind -target ios
上記を実行すると、iOS向けのライブラリが作成されます
Androidに組み込んでみよう
モジュールの追加
メニュー File > New > New Module… を選択、Import .JAR/.AAR Package でライブラリのモジュールを作る。
メニュー File > Project Structure… を選択、 ライブラリを使用するアプリケーションのモジュールを選択し、 「Dependencies」のタブを開き、 プラス記号「+」アイコンを押し「Module Dependency」を選ぶ。 手順1で追加したモジュールを選択。
ソースコードへ追加
import go.hello.Hello;
// 適当なところで呼び出す
Log.e("check GoMobile : ", Hello.World());
これで、gomobileで作成したライブラリをAndroidで呼び出せるようになりました。
超簡単ですね!
ちょっとしたこと
Goを書く上でちょっとしたルールがあります。
公式ドキュメントは、頑張って読みましょう。
……はい、読みます。
グローバル関数とプライベート関数
関数名の頭が大文字だと外部から呼び出せます。
関数名の頭が小文字だと内部でしか使用できない関数になります。
// グローバル関数 func ApiText() string { ......処理 } // プライベート関数 func httpPost() { ......処理 }
mapはグローバル関数の引数に指定できない
これは、以下のようなエラーが吐かれて、少し悩みました。
panic: unsupported seqType: map[string]string / *types.Map
見る限り、どうやらサポートされてないようです。
httpリクエストなどの時、パラメーターを配列にして渡したかったのですが、できませんでした。
しかし、プライベート関数には、指定できるようです。
ですので、APIとかでパラメータを使う時は、以下のようにして、対応しました。
func ApiTest(token string, text1 string, text2 string) string {
params := map[string]string{"token":token, "param1":text1, "param2":text2}
return httpPost(api_test_url, params)
}
func httpPost(url string, params map[string]string) string {
…postする
}
APIごとにひとつ関数が増えるので、ちょっと不満です。
無念……。
定数に配列は指定できない
これは嫌でした。Goの嫌なところといったら、おそらくこれです。
定数配列で、APIのアドレスとかドメインとか指定して、debug_codeとかで切り替えられるようにしようと思ったのに、許されませんでした。
仕方がないので、URLを作成する関数を作って、その中にドメインの配列を作りました。
なんか、その関数呼び出すたびに配列を作り直すので、気持ち悪いです。
まとめ
とても簡単に導入できました。
JavaとかSwiftとかやってる方なら、覚えるのは簡単かなと思います。
特に、Swiftとはよく似ているそうです(やったことないからわからないけど・・・)
EclipseやAndroid Studioのような開発環境は、まだちょっとしかありませんでした。
今回は、viとSublimeで作成しています。
今後、開発環境もしっかり整備されてくれれば、Goがひとつの言語として浸透していくのだろうなぁと思います。
個人的には、すごく期待してます!