post Image
新しく入ったReverse Binding機能を使ってPure GoでAndroidアプリを作ってみる #golang #gomobile

はじめに

Go MobileというGoをモバイルアプリ開発に用いるというGoのサブリポジトリであるgolang.org/x以下で進められているプロジェクトがあります。

Go Mobile には、NativeアプリとSDKアプリという2種類の開発方法があり、NativeアプリはすべてをGoで書き、SDKアプリはJavaやObjective-CからGoの関数などを呼び出すというものでした。

これらの違いや詳しいやり方については、DroidKaigi 2016の資料やGopherCon 2016の資料ビデオ)などを確認していただければと思います。

Go MobileのNativeアプリでは、Goですべてを書けるものの、UIをOpenGLの関数を使って書く必要があり、せっかくAndroid APIがJava向けに提供されているにもかかわらず、Go Mobileからは直接は利用ができませんでした。

また、SDKアプリではJavaからGoを呼び出せるものの、GoからJavaのAPIを呼び出す方法がなく、NativeアプリもSDKアプリもこれじゃない感が否めませんでした。

ここでは、最近入ったJavaのAPIのバインディングを自動で作成する、Reverse Bindingの機能を使って、Javaで提供されているAndroid APIをGoから呼び出すサンプルを動かしてみます。

なお、Android SDKが必要となりますので、最新版のAndroid Studioをインストールするなりしておいて下さい。

Go Mobileのインストール

gomobileコマンドをgo getしてきます。

$ go get -u golang.org/x/mobile/cmd/gomobile

変更したものをgo installでビルドして反映させます。

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

もし、$GOPATH/bin以下にPATHを通してない場合は事前にパスを通して下さい。

$ export PATH=$PATH:$GOPATH/bin

gomobile initを呼び出して、初期化を行います。

$ gomobile init -v

もし、すでに過去にGo Mobileをインストールしたことがある方は、gomobile initの前に以下のようにキレイにしておくことをオススメします。

$ gomobile clean

サンプルを動かしてみる

今回使用するサンプルは、Go Mobileのリポジトリのexample/reverseGithubのリンク)に入っています。

Android Studioでexample/reverse/androidを開いてビルドする方法もありますが、ここではターミナルで直接gradleを使ってビルドする方法を説明します。
ちなみに、Android Studioでは開いてビルドボタンを押すだけで大丈夫です。

まず、gradleが入ってない場合はインストールします。Macの場合はbrew installで入ります。

$ brew install gradle

続いてディレクトリを移動します。

$ cd $GOPATH/src/golang.org/x/mobile/example/reverse/android

Android SDKがインストールされている場所をANDROID_HOMEに設定します。
毎回実行するのがめんどくさい場合は、.bashrc.zshrcに設定しておくと良いでしょう。

$ export ANDROID_HOME=$HOME/Library/Android/sdk

gradlewを生成します。

$ gradle wrapper

ビルドには上記で生成したgradlew(Windowsの場合はgradlew.bat)を使います。

$ ./gradlew build

うまくいくとbuild/outputs/apkapkファイルができているはずです。

$ ls build/outputs/apk
android-debug.apk            android-release-unsigned.apk

デバッグビルドがandroid-debug.apkでリリースビルドがandroid-release-unsigned.apkです。

Android機に入れて実行してみましょう。

$ adb install -r build/outputs/apk/android-debug.apk

実行してみると以下のような画面が出て来るはずです。

ReverseBindingExample.png

ぱっと見はAndroidアプリっぽい感じになってますが、Goのコードはどうなっているんでしょうか?

ソースコードを読んでみる

Goのコードは、example/reverse/reverse以下に入っています。

$ cd $GOPATH/src/golang.org/x/mobile/example/reverse/reverse
$ ls
reverse.go

reverse.goの中身を見てましょう。

reverse.go
package reverse

import (
        "Java/android/databinding/DataBindingUtil"
        "Java/android/os"
        "Java/android/support/v7/app"
        rlayout "Java/go/reverse/R/layout"
        "Java/go/reverse/databinding/ActivityMainBinding"
)

type MainActivity struct {
        app.AppCompatActivity
}

func (a *MainActivity) OnCreate1(this app.AppCompatActivity, b os.Bundle) {
        this.Super().OnCreate1(b)
        db := DataBindingUtil.SetContentView2(this, rlayout.Activity_main)
        mainBind := ActivityMainBinding.Cast(db)
        mainBind.SetAct(this)
}

func (a *MainActivity) GetLabel() string {
        return "Hello from Go!"
}

Java/で始まるパッケージをインポートしていることが分かります。
これらのパッケージはどこからインポートされるのでしょうか?

実はGOPATHの中を探してもこれらのパッケージはありませんし、どこかにこれらのパッケージが公開されていてgo getするわけでもありません。
また、よく見るとJava/の後ろはJavaのパッケージ名またはパッケージ名+クラス名になっていることが分かります。
Reverse Bindingという機能を使って、このインポート文から自動でバインディングが生成されます。
Java/android/databinding/DataBindingUtilのメソッドを呼び出すと、JNI経由でandroid.databinding.DataBindingUtilが呼び出されるようなバインディングがビルド時に自動的に生成されます。

Java/go/reverse/R/layoutについては、example/reverse/android/src/main/res/layout/以下で定義されているレイアウトに対応します。ActivityMainBindingについては、Androidバインディングの機構で生成されるクラスのようです。

このサンプルを見ると、MainActivityapp.AppCompatActivityを埋め込んでいます。
これは、Javaの継承に対応するコードで、onCreateをオーバーライドしています。
onCreateonCreate1となっているのは、Javaにはオーバーロードの機能があり、Goには無いため、メソッド名が被る場合は引数の個数を後ろにつけるルールでバインディングが生成されるからです。
この場合、引数が2つに見えますが、実際にはJava側のOnCreate(bundle Bundle)に対応しているので、1になっています。

第1引数のthisについては、他のJavaのメソッドの引数に渡すためのレシーバに対応するオブジェクトであり、この場合はDataBindingUtil.SetContentView2mainBind.SetActに渡すために使用されます。
また、Superを呼び出すとJava上のsuperに当たるオブジェクトを取得することができ、スーパークラスのメソッドなどを呼び出すことができます。

詳しい説明については、Reverse Bindingのプロポーザルを読むとよいでしょう。

まとめ

さて、いかがだったでしょうか?
GoでAndroidアプリを書くという話がだんだんと現実的なところまできてるな感じる機能です。
もちろん、まだまだクリアしないといけない課題もあり、Experimentalなプロジェクトであることは変わりませんが、今後が楽しみです。
今回説明できなかった、生成されたバインディングやどうやってバインディングを作るのかといった話やiOSについてはまた別の記事にまとめようと思います。


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。