Android
Go
GoDay 3

GoAndroidでʕ ◔ϖ◔ʔGo~

More than 3 years have passed since last update.


はじめに

3日日担当の@ladicleです

タイトル通りAndroidのアプリ上でGoを動かそうと思います

とは言っても一から作るのではなく

eliasnaurさんが書かれたパッチを使用していきます


GoとAndroid

御存知の通り、AndroidのアプリはJavaで書かれていますので

そのままGoを動かすことはできません

というわけで、ネイティブライブラリ(.so)にしてアプリに埋め込みます

アプリじゃなくてルート取って動かせればいいよって方はこちら

パッチの話はここらへん参照。


環境

OS: Ubuntu 13.10 desktop amd64

昨日のRelease1.2で、OSXでもできるようになりました!!!


必要なもの


  • Git

  • Mercurial

  • JDK7

  • Ant


導入


1 SDK

SDKをDL。任意の場所に解凍してパス設定

export ANDROID_HOME="$HOME/Develop/Android/SDK"


2 NDK

NDKをDL。任意の場所に解凍してパスを設定

export NDK="$HOME/Develop/Android/NDK"

下記のコマンドでNDKtoolchainの生成

$NDK/build/tools/make-standalone-toolchain.sh --platform=android-9 --install-dir=ndk-toolchain

ndk-toolchainが生成されていたらパスを設定

export NDK_ROOT="$NDK/ndk-toolchain" 


3 Go

適当なところでパッチ(goandroid)をクローン

git clone https://github.com/eliasnaur/goandroid.git

パスの設定

export GOPATH="$HOME/Develop/Golang"

export GOBIN="$GOPATH/bin"

ソースコードを持ってくる

hg clone https://code.google.com/p/go $GOPATH

パッチフォルダーをコピー

cp -a patches $GOPATH/.hg

Mercurialの設定

[extensions]

mq =
codereview = !

[ui]
username = Go<Go@mail.com>

パッチの適用

cd $GOPATH/src

hg qpush -a

ビルド

CGO_ENABLED=0 GOOS=linux GOARCH=arm ./make.bash  

CC="$NDK_ROOT/bin/arm-linux-androideabi-gcc" GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 $GOBIN/go install -tags android -a -v std
cd ../..


動かす

goandroidには


  • hello-gl2 :: Javaアリ

  • nativeactivity :: Javaナシ

の2サンプルが入ってますが、手順はどちらも同じです

各フォルダ内のbuild.shを実行すると.soライブラリが生成されます

(build.sh内の../go/bin/$GOBINに置き換え)

project.propertiesを使用するバージョンに書き換え

(今日落としたならtarget=android-19)

Android端末を繋ぎ、下記のコマンドを実行するとインストールされます

ant -f android/build.xml clean debug install


書く

Javaから呼び出す関数の指定は


main.go

//export Java_net_goandroid_hellogl2_Engine_resize

func Java_net_goandroid_hellogl2_Engine_resize(env *C.JNIEnv, clazz C.jclass, width, height C.jint) {
defer func() {
if err := recover(); err != nil {
log.Fatalf("panic: resize: %v\n", err)
}
}()
g.resize(int(width), int(height))
}

こんなかんじ。呼び出し元は


Engine.java

 static native void resize(int w, int h);


と、こんなかんじ。だいたい通常のJNIとcgoです

//export Java_(パッケージ)_(関数名)

func Java_(パッケージ)_(関数名)(env *C.JNIEnv, clazz C.jclass, ....) ... {
return ...
}

変数名にC.jxxxxつけていくとだいたいうまくいきますʕ ◔ϖ◔ʔ


おわり

たのしいAndroidライフを!