モバイルアプリケーションの開発は、あなたがやりたいことと、デバイスプラットフォームがあなたにできることとの間の妥協です。 この記事では、Golangを使用してAndroidアプリケーションの機能を強化する方法について説明します。
ここでは、秘密のアンドロイドAPIのリークは見つかりません。 使用されるメカニズムは、標準(またはほぼ標準)のAndroidおよびGolangツールであり、その説明は公式サイトおよび専門フォーラムにあります。 しかし、単一の行動計画の形で、そしてロシア語でさえ-これは初めて、Habr専用に発行されます。
背景
いずれかのアプリケーションのユーザーからの多数のリクエストにより、テキスト予測が開発されました。 予測は、 基数ツリーアルゴリズムによって提供され、別のAndroidライブラリに実装されました。 アルゴリズムは、経済的なリソース消費とともに良好なパフォーマンスを示しました-1.5 MBのメモリ消費で数十ミリ秒の結果を生成しました。 完全なパフォーマンス指標。 しかし、これはJVM上のライブラリの分離テストでのみ行われました。
ライブラリをアプリケーションに接続するときに問題が発生しました。 Androidでは、予測アルゴリズムの速度が低下し始め、結果の出力が7秒にドラッグされました。 わあ! はい。7秒で、単語を手動で入力し、削除して、正しく入力できます。 そのような予測は良くありませんでした。
分析では、コードの問題は明らかになりませんでした。 アルゴリズムは完璧に機能し、厳密に割り当てられたメモリ量で消費され、無関係なプロセスに気を取られず、すべてが非同期であり、ハードウェアリソースが十分にありました。 結論は1つだけでした。Androidのdalvik仮想マシンのパフォーマンスはJVMとは異なり、dalvik内ではこのコードはブレーキをかけられます。
次に、予測アルゴリズムをダルビックから除外することが決定されました。 このJava Native Interface用のJNIがあります。 JavaからC / C ++で記述されたライブラリメソッドを呼び出すことができるメカニズム。 また、C / C ++ライブラリから、javaメソッドを呼び出します。
解決策
ネイティブライブラリを作成するために、Goが選択されました。 C / C ++とは異なり、経験があるからです。 Golangは驚くべき機能ですが、複雑さをさらに高めるため、この方法には困難が伴います。 純粋なC / C ++の場合、 NDKを使用し、 Android開発者の Webサイトに記載されている指示に従うだけで十分です。 Golangの場合、Android向けのgolangのコンパイルについて詳しく学ぶ必要があります 。 ここから開始できます 。
危険と冒険に満ちた道を前に築きました。 しかし、今ではこの道はすでに完了しており、喜んで彼の計画を共有します。
計画
Android開発環境:
- OS:Windows 7。
- IDE:ADTを使用したEclipse。 しかし、この計画はAndroid Studioにも適しています。
Golang開発環境:
- OS:Androidでgolangをコンパイルするには、Linuxが使用されます。 VirtualBoxで実行されているUbuntu 14.04を使用しています。
- Android SDK。
- 公式のAndroidサイトからアーカイブをダウンロード
-たとえば、
$HOME/android/android-sdk-linux
- Java JDK。
$ apt-get default-jdk
- 1.5に進みます。
Goの現在のバージョンは1.4です。 しかし、それを使用してライブラリをコンパイルすることはできませんでした。どこかでツールチェーンを構築するときにミスを犯しました。 したがって、Go 1.5の開発バージョンのgomobileパッケージを使用しましたが、そのリリースはまだ計画中です。 リリースはありませんが、Go 1.5のインストールについて説明します 。
-Go 1.4 golang.org/doc/installをインストールします
-現在のgolangリポジトリのクローンを作成します。
$ git clone https://go.googlesource.com/go $HOME/go
$ export GOROOT_BOOTSTRAP=/usr/local/go $ cd $HOME/go/src && ./make.bash $ export PATH=$PATH:$HOME/go/bin
- gomobileパッケージをインストールして初期化します。
$ go get golang.org/x/mobile/cmd/gomobile $ gomobile init
golangライブラリの開発。
- 定期的なgolangパッケージが開発されていますが、これ以上の推奨事項はありません。 エクスポートメソッドはAndroidから利用できます。
golangライブラリをandroid * .aarライブラリにコンパイルします。
- Android SDKへのパスでgomobile bindコマンドを使用します
$ cd <golang project folder> $ ANDROID_HOME=$HOME/android/android-sdk-linux gomobile bind
* .aarライブラリをアプリケーションに接続する:
まず、* .aarライブラリをAndroid開発マシンに転送します。 さらにIDEによって異なります。
日食の場合:
- * .aarライブラリを一時ディレクトリに解凍します
- Eclipseで、項目1から一時ディレクトリを指定して、既存のコードから新しいプロジェクトを作成します
- このプロジェクトはAndroidライブラリであることに注意してください
- 新しいプロジェクトのビルドパスにjniディレクトリとclasses.jarファイルをマウントします
- 新しいプロジェクトをライブラリとしてアプリケーションプロジェクトに接続します
- jniフォルダーの内容をアプリケーションプロジェクトのlibsフォルダーにコピーします。
- proguard.txtライブラリーの内容をアプリケーションプロジェクトのproguard.txtにコピーします(go *クラスを難読化から保護します)
- その後の* .aarライブラリの更新では、jni、libsフォルダー、classes.jarファイル内のファイルを更新するだけで十分です。
Android Studioの場合:
- Android Studioの標準ツールを使用して、完成した* .aarライブラリをプロジェクトに接続します。 残念ながら、私はそのような経験がないので、これを宿題として残します。
Androidからネイティブライブラリメソッドを呼び出す。
- アプリケーションでネイティブライブラリを使用する前に、初期化する必要があります。 これに適した場所は、onCreateメソッドです。
public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); Go.init(getContext()); } }
- golangライブラリのメソッドは、golangで定義したものと同じ名前のパッケージで利用できます。 例:
golang:
package radix … func Suggest(params string) string { … }
java:
suggestions = Radix.Suggest(params);
結果
アルゴリズムをネイティブライブラリに転送した後、予測はJVMよりもさらに速く動作し始めました-結果は10ミリ秒未満で返されます。 リソースの一部がネイティブコードの側に転送されたため、ガベージコレクションの数も減少しました。
JNI実装の効果は予想を上回りました。 これらのインジケータにより、キーボードがリリースされました。
おわりに
golangを使用してAndroidアプリケーションを高速化することはまったく理論ではありませんが、市場アプリケーションで既に使用されている実際の機能です。
もちろん、これはアプリケーションの開発を複雑にします;ツールの動物園は倍になります。 しかし、これにより興味深いソリューションを実装することができます。
Go 1.5のリリースにより、gomobileツールキットによりandroid-golangの統合がさらにアクセスしやすくなり、プロセス全体が2チームに削減されることが期待されます。