熱があって体調激悪ですが、なんか書いてみましたの第二弾です。
週末、自前のAndroidアプリの 手直しをしようとしててハマったので愚痴だと思って聞いてください。
Root CA Viewer Liteに証明書リストをエクスポートする機能を追加しようと思い、 幾つかのサイトを参考にしながら、でも、Android のプログラミングも超久しぶりなので ビルドどうやんだっけ?、コード署名どうやんだっけ?などもたもたしながら 2時間ほどで実機で動作することは確認できました。
実機確認はGoogle PlayにあげずにLAN内でやるわけですが、 AirDroidは すごく助かりますね。これをあげるとAndroid側がリモートサーバーになって 開発機からapkをアップしたり、SDカードみたりいろんなことができて実機テストが捗ります。
まず、zipalignでハマる
で、まぁ動いたから公開すんべぇとGoogle Playにアップしようとしたら zipalignされてないからアップロードできないと英語で怒られました。
minghaiさんの日記:apkファイルを最適化する zipalignに説明があった。apkファイルがzipalignされてないとapk(zip)解凍の時、非常に メモリ効率が悪くなるのだそうです。
探してみるも zipalign などない。どうやら新しい Android SDK でないと 入っていないそうです。仕方ないのでAndroid SDK Managerで アップデートをかけました。Android 4.0.3 API 15 までしか入ってなかったんですが、 Android 4.4 API 19 まで上げてみます。APIのターゲットは15のままです。 ただし、Google AdMobは、コード手直ししないといけなそうだったりしたので、これだけ保留にしておきました。
で、アップデートすると、「そもそもEclipseのライブラリが古いよ」とこれまた 英語で怒られてヘコみます。これは従順に言われた通りに上げます。
参照関係に泣く
で、Root CA Viewerをリビルド、エミュレータで実行させようとすると、リビルドできない。
Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.その他にも、DEXが壊れててよめねーじゃねーかと英語で怒られます。 Eclipseのログ見ろっていってもログの場所がわからない。
Google大先生に聞いてみるとEclipseのログは
$WORKSPACE/.metadata/.logにあることがわかりました。
ログにはあまり参考になりそうな情報はありませんでしたが、
多分、参照関係がおかしくなっているんでしょうね。
Google AdMobが古いせいなのかなと思い、AdMobライブラリも新しくしてみました。
一部、ソースコードやらXML設定ファイルやらを手直しして再度ビルドします。
再度ビルドしてみようとすると、
com.google.ads.AdView failed to instantiate. java.lang.ClassNotFoundException: org.json.JSONException at java.net.URLClassLoader$1.run(URLClassLoader.java:202)と怒られます。ええーーっ、JSON入ってないの?使っているJDKが古いのか、 Androidのライブラリが古いんでしょうねぇ。 Google大先生にJSONの件を聞いたら このページ(NoClassDefFoundError when trying to unit test JSON parsing in Android)を返してくれました。 APIのターゲットを上げると4.0そこそこのやつでは 動かなくなりそうだったので、org.jsonのソース探して、jar作って 置いてみました。
すると、またコレが出るようになりました。
Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.結局解決してなかったのね。
随分調べて このページ(Issue 61710:java.nio.BufferOverflowException When Building with 19 Build Tools) を見つけました。どうやらAndroid SDK 19 Build Toolの問題らしく、
- Android 19 Build Tools, API 19を削除する
- Target SDK を19から18に戻す
- extras/android/support/v7/appcompat/libs/android-support-v4.jarの参照を削除する
- 再度 android-support-v4.jar を追加する
最後にzipalignではまる
結局は署名済apkが出力される場所が間違っていたというオチなわけですが、 本来なら署名済apkを作った際に自動的にzipalignも実行されるとの事です。 結局コマンドラインでやってしまいました。
% tools/zipalign 4 RootCAViewerLite.apk RootCAViewerLite_.apk (*_.apkが出力先で署名済)ファイルサイズが昇順になるんですね。というわけで、いろいろありましたが何とか新しいRoot CA Viewer Liteを 公開することができました。あーつかれた。
% tools/zipallgn -v -c RootCAViewerLite_.apk (チェック)
Verifying alignment of RootCAViewerLite.apk (4)...
62 res/layout/activity_cert.xml (OK - compressed)
655 res/layout/activity_main.xml (OK - compressed)
1252 res/layout/activity_textview.xml (OK - compressed)
1937 res/menu/activity_cert.xml (OK - compressed)
2256 res/menu/activity_main.xml (OK - compressed)
2604 res/menu/activity_textview.xml (OK - compressed)
2916 AndroidManifest.xml (OK - compressed)
4000 resources.arsc (OK)
7316 res/drawable-hdpi/ic_action_search.png (OK)
7788 res/drawable-hdpi/ic_launcher.png (OK)
9864 res/drawable-ldpi/ic_launcher.png (OK)
11236 res/drawable-mdpi/ic_action_search.png (OK)
11612 res/drawable-mdpi/ic_launcher.png (OK)
13272 res/drawable-xhdpi/ic_action_search.png (OK)
13828 res/drawable-xhdpi/ic_launcher.png (OK)
16458 classes.dex (OK - compressed)
570061 README (OK - compressed)
571082 jsr305_annotations/Jsr305_annotations.gwt.xml (OK - compressed)
571300 jsr305_annotations/v0_r47/V0_r47.gwt.xml (OK - compressed)
571474 META-INF/MANIFEST.MF (OK - compressed)
572232 META-INF/CERT.SF (OK - compressed)
573041 META-INF/CERT.RSA (OK - compressed)
Verification succesful