スマホ交換 - なか日記で「Androidアプリの開発はきっとしない」と書いたのに、Android Studioが発表されたのでちょっとインストールしてみた。
インストール
公式サイトからダウンロードしたインストーラでさくさくっとインストールできる。
Android Studioの起動
ショートカットをクリックで起動すると思ったのに起動しない!と思ったら、環境変数にJAVA_HOMEを設定してなかったからだった。公式サイトのトップページにちゃんと書いてあるのに、ドキュメントを見ずに触ってはまるなんて…悪いクセがここでも発揮された感じ。
サンプルプロジェクトの作成
メニューから「New Project」を選択するとウィザードが起動するのでそれに従ってれば雛形ができる。この辺はEclipseでのプロジェクト作成と殆ど同じかな。
作成されたプロジェクトを見ると、Gradleを使ってビルドするようになってるみたい。Gradleなんてさっぱりやでぇ…
android-bindingを追加
android-bindingを使ってみようとしてみた。で、まいった。
libsへjarファイルを追加
android-bindingの公式サイトから最新のjarファイル*1をダウンロードして、libsフォルダへコピーする。
プロジェクトの設定
「File」メニューの「ProjectStructure」でプロジェクトの設定画面を表示し、「Libralies」メニューでjarファイルを登録する。
登録する際どのモジュールに追加するか聞かれるので、「AndroidBindingSample-AndroidBindingSample」に追加しておく。
これでコード補完ができるようになる。
build.gradleの編集
ビルドはGradleで行うので、上の設定だけじゃダメみたい。「AndroidBindingSample-AndroidBindingSample」配下にあるbuild.gradleの依存関係にjarファイルを登録する。
dependencies { compile files('libs/android-support-v4.jar') compile files('libs/android-binding-v30-0.52.jar') }
libsフォルダ配下のjarファイルは全部必要な場合は以下の様に書いてもよさげ。
dependencies { compile fileTree(dir: 'libs', include: '*.jar') }
ビルドと実行
これで一通りの準備は整った(はず)なので、Shift+F10で実行してみる。ビルドが正常に終了すると、実行する環境を選択する画面が出るので好きな環境を選んでデプロイ&実行する。
そうすると・・・プギャー
05-18 19:28:23.298 8322-8322/? D/dalvikvm: Late-enabling CheckJNI 05-18 19:28:23.438 8322-8322/com.example.androidbindingsample E/dalvikvm: Could not find class 'gueei.binding.observables.DoubleObservable', referenced from method com.example.androidbindingsample.BMIViewModel.<init> 05-18 19:28:23.438 8322-8322/com.example.androidbindingsample W/dalvikvm: VFY: unable to resolve new-instance 555 (Lgueei/binding/observables/DoubleObservable;) in Lcom/example/androidbindingsample/BMIViewModel; 05-18 19:28:23.438 8322-8322/com.example.androidbindingsample D/dalvikvm: VFY: replacing opcode 0x22 at 0x0003 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample I/dalvikvm: Could not find method gueei.binding.observables.StringObservable.get, referenced from method com.example.androidbindingsample.BMIViewModel.Calculate 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample W/dalvikvm: VFY: unable to resolve virtual method 4105: Lgueei/binding/observables/StringObservable;.get ()Ljava/lang/Object; 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample D/dalvikvm: DexOpt: unable to opt direct call 0x1006 at 0x05 in Lcom/example/androidbindingsample/BMIViewModel;.<init> 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample D/dalvikvm: DexOpt: unable to opt direct call 0x1008 at 0x0c in Lcom/example/androidbindingsample/BMIViewModel;.<init> 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample D/dalvikvm: DexOpt: unable to opt direct call 0x1008 at 0x13 in Lcom/example/androidbindingsample/BMIViewModel;.<init> 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample W/dalvikvm: Unable to resolve superclass of Lcom/example/androidbindingsample/BMIViewModel$1; (554) 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample W/dalvikvm: Link of class 'Lcom/example/androidbindingsample/BMIViewModel$1;' failed 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample D/dalvikvm: DexOpt: unable to opt direct call 0x0ff1 at 0x1a in Lcom/example/androidbindingsample/BMIViewModel;.<init> 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample D/AndroidRuntime: Shutting down VM 05-18 19:28:23.448 8322-8322/com.example.androidbindingsample W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40aeb9f0) 05-18 19:28:23.458 8322-8322/com.example.androidbindingsample E/AndroidRuntime: FATAL EXCEPTION: main java.lang.NoClassDefFoundError: gueei.binding.observables.DoubleObservable at com.example.androidbindingsample.BMIViewModel.<init>(BMIViewModel.java:12) at com.example.androidbindingsample.MainActivity.onCreate(MainActivity.java:13) at android.app.Activity.performCreate(Activity.java:4465) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992) at android.app.ActivityThread.access$600(ActivityThread.java:127) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4441) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590) at dalvik.system.NativeStart.main(Native Method)
java.lang.NoClassDefFoundErrorですって!? 作成されたapkファイルを見ると明らかにandroid-binding-v30-0.52.jarが含まれていない感じ。何か設定が足りないのかなぁと調べてみたけどよくわからず。
教えてエロい人!
追記(5/22)
よくよく見てみるとAndroidBindigの使い方を間違ってて、ActivityはBindingActivityを継承しないといけないのにしてなかった。
修正して再度実行!今度こそ!と思ったけど、今度は
05-22 23:33:59.573 13981-13981/com.example.androidbindingsample E/AndroidRuntime: FATAL EXCEPTION: main java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.androidbindingsample/com.example.androidbindingsample.MainActivity}: java.lang.ClassNotFoundException: com.example.androidbindingsample.MainActivity at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1891) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
うーむ。。。
とりあえず、ソース晒しておくか
GitHub - nakaji/AndroidBindingSampleUsingAS: AndroidBindingSample using Android Studio
追記(5/25)
原因はよくわからないが、解決した。
そういやリポジトリに不要なファイル*2を登録してたよなぁと思って
$ git rm -rf AndroidBindingSample/build/
その後、ビルドすると…
あ、動いた\(^o^)/
ナン、デヤネン。
Build配下に何かゴミが残って悪さしてたって事?
確認すると、 AndroidBindingSample/build/libs/ 配下の AndroidBindingSample-debug.dex だけ削除すればちゃんと動くアプリが生成されるみたい。
DEXファイルっていうのはAndroidの仕組みを知る(2) | 日経 xTECH(クロステック)によると
Dalvik VMが実行するのは、「Dalvik Executable(DEX)」と呼ばれる独自形式のバイナリ・プログラムだ。通常、レジスタ・ベースのバイナリは、スタック・ベースのバイナリに比べて容量が大きくなる。しかし、DEXでは、重複による無駄を極力減らし、Java VMのクラス・ファイルよりも小さいバイナリを実現している*1。重複を減らすために、内部的にクラス名、変数名やメソッド名をJavaバイト・コードのように文字列としてではなく、一意の名前(シンボル)に変換して管理している。
何で更新されないのかよくわからん。RebuildProjectしても更新されんからそんなもんなんだろう。
おまじないとして覚えておこう。
動くはずなのに動かないときはとりあえず、Build配下を削除してみる