2011年12月13日火曜日

ProGuardを実行したときに出たエラーの対処

ProGuardを使ったときに「Conversion to Dalvik format failed with error 1」というエラーが出た場合の話。
以下のページにWorkaroundがあるので、バッチファイルの修正を行えば行けた。

http://wada811.blog.fc2.com/blog-entry-62.html

念のため、内容をコピペしておく。以下引用。

タイトルの通り、「Conversion to Dalvik format failed with error 1」というエラーが出る場合の対処法です。
このエラーが出たらやることは基本的に一つ。Eclipseのクリーンです。
今回はそれでも改善されずにapkファイルが作れなかった場合について書いておきます。

もしかして:Android SDK Tools r12 にバージョンアップした

当てはまる人はこの記事の内容で対処できるはずです。
この問題は既に報告されているようです。
Android SDK tools revision 12 has problem with Proguard - Android - An Open Handset Alliance Project
Android SDK Tools r12 に含まれるProGuardのバージョンが古いためバグを内包しているというもの。
解決法は主に二つ

proguard.batを書き換える
ProGuardの最新版をダウンロードしてきて置き換える

proguard.batを書き換える

[Android SDK]\tools\proguard\bin

を開きます。
proguard.bat をエディターで開きます。
内容をコピーします。(おそらく書き換え禁止になっているので)
エディターを新しく開き、コピーしたものを貼り付けます。

call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %*



call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %1 %2 %3 %4 %5 %6 %7 %8 %9

に書き換えます。
proguard.bat というファイル名で保存して元の proguard.bat と置き換えます。
コレでapkファイルを作れるようになったと思います。
一部の人はこれでもできない場合があるらしいです。
ProGuardの最新版をダウンロードしてきて置き換える

ProGuard Java Optimizer and Obfuscator - Browse /proguard at SourceForge.net にアクセスします。
Android SDK Tools に含まれる ProGuard4.4 より新しいものを選ぶ(現在なら 4.6 が最新なので 4.6 が好ましい)
ダウンロードしたファイルを解凍します。
bin フォルダと lib フォルダで Android SDK Tools の proguard フォルダの bin フォルダと lib フォルダを置き換えます。
コレでapkファイルを作れるようになったと思います。

これでも直らない場合はお手上げです。あとは頑張ってください。

「resources.ap_ does not exist」が出る

EclipseでAndroidアプリケーションを開発しているときに、不意にハマった現象。

もしかして:Eclipseのオプションで、Android > Build > Build output > Verbose にしていないか?
今回ハマった現象はこれで、ADT14のaaptが-vオプション有りで死ぬらしい。
https://code.google.com/p/android/issues/detail?id=20395 参照。

注:これを書いている時点でADT16がリリースされていたので、もう直ってるかも。

そうでなければ以下を参照。

stackoverflow.comの記事
http://stackoverflow.com/questions/4437023/resources-ap-does-not-exist-when-compile-my-android-project

他のマシンで動作するシンプルなサンプルでも、自分の環境では冒頭のエラーで実行出来ない症状。
いくつかのWorkaroundが存在する。

1. Project > Clean を実行する(いくつかの派生がある。Clean,Delete gen,restart eclipseとか)
2. 指摘された場所に「resources.ap_」という空ファイルを作成してClean/Rebuildする
3. 不正なリソースファイル(adbの認識出来ないPNGファイルとか)を削除する。ただしこの場合は別のエラーが出ているはず。
4. aaptをアップデートした際に、順序のない書式指定文字列をビルドエラーとして扱うようになった。
ちょっとややこしい。
This was my problem as well. Basically anywhere in your strings.xml where you have any combination of %s or %d in the same string, replace them with %1$s or %2$d where the number between the % and $ is the order in which they are placed in the string. For exmaple: "Blah %d something %s" should now be "Blah %1$d something %2$s" – GuyNoir Dec 26 '10 at 20:12
Oh, you did not mention that you upgraded to SDK v8 when you encountered the problem. Yes, the SDK is more strict now when it comes to ordering format strings. :) – Zarah Jan 9 at 18:06
It can't be, we can find this problem in android sdk examples, SearchableDictionary has this problem ._. – rubdottocom Feb 22 at 16:48
5. "gen"を消してからProject > Build All を実行して、R.javaを再生成する。
6. API-Levelが間違っている。正しいLevelを選択すればよい。
7. string.xmlに問題がある。最低限必要な分を残し、一回全部消してみる。
8. Admob adsを使っている場合に
1) I was using Admob ads, and I didn't have an attrs.xml file in my res/values folder
2) I deleted a line that says "import andriod.R" from my main activity, and all my resources connected again and this ultimately made the error go away.
3) The last thing I had wrong is I had a "lib" folder instead of a "libs" folder that held my Admob jar file.
Lastly, I cleaned the project after these changes.
9. (Alt-Shift-Q then X)でなんかでてくる?他にもConsoleのproblemログをきちんと確認する。(異常なリソースファイルとかはこれでわかるかも)
結構9patchで問題が出ている場合が多いっぽい。作り方の問題か?
10. バックスラッシュをstrings.xmlに含んでいる
11. アップデート時に問題が出た場合、プロジェクトのバックアップから復元し直してみることで治るかもしれない。
12. binおよびgenを消して、リフレッシュ(F5)してみる
13. eclipseのWorkspaceの".metadata"が壊れている。Workspaceを作り直す。ただしEclipseの環境は1から作り直しになる。

2011年12月12日月曜日

ProGuardを使う

というわけで、必要になったのでProGuardを使ってみた。

基本的な情報はWebでいろいろ拾える。参考にしたのは

  • http://y-anz-m.blogspot.com/2010/10/androidlvl-securing-android-lvl.html
  • http://d.hatena.ne.jp/bs-android/20101207/1291702021
  • http://d.hatena.ne.jp/hyoromo/20101120/1290216449
このあたり。

で、いざ実践してみてハマったところとか気がついたところをまとめておく。

まず、上記参考URLの情報では、"default.properties"にパスを追加するということが書かれているのだが、これではProGuardが走らなかった。
正解は"project.properties"の方に書く。
実際に新しいプロジェクトを作成して見るとそうなっているので、そのまま持ってくるようにすれば良い。

proguard.cfg自体はEclipse上でコピー&ペーストすればOK。

んで、どっかで外部ライブラリは難読化されないと書いてた気がするんだけど、
自分で作った物はちゃんと難読化されている様子。
今回だとLVL(Licensing Verification Library)を併用しているんだけど、
そっちのクラスが難読されている様子が、mapping.txtにはき出されていた。

そして難読化してはいけないもの。
JNI関係は難読化してはいけない、というのは上記参考URLにも書いてある。
これは具体的には"native"接頭辞を付けたメソッドを宣言しているクラスをkeepに指定すれば良い。
逆にこれを難読化すると、JNIのメソッドが一切呼ばれなくなる。エラーは吐かないのでわかってないとハマるかも。
LVLは特に書かなくても動いてるなー。あとでなんか問題でてくるかも?
もしくはデフォルトで書いてある

-keep public class com.android.vending.licensing.ILicensingService

という指定で行けてるような気がする。

2011年11月28日月曜日

作ってみた。

技術的な事とかで調査した内容はTwitterではつぶやきにくいので、ブログを作ってみた。

まぁ技術的な事に限るつもりは無いけど、基本的には自分用メモって事で。

特に宣伝する気も無いのでこの文章を読む人間が居るかどうかは怪しいが…