2012/05/30

署名Androidアプリケーション作成時のWarning

Google PlayにAndroidアプリケーションを載せる前に、アプリケーションに署名を行ないますが、 Export Signed Application Package...を選択した時に、同一パッケージ内で can't find referenced classのワーニングが大量に発生して、パッケージを作成する事ができませんでした。

いろいろ調べると、proguard設定に-dontwarn設定を追加すれば良いと書かれていますが、 不必要に全てのワーニングを抑制するのが嫌だったのでproguardのサイトを眺めた時のメモです。

ワーニングメッセージの例

...
Proguard returned with error code 1. See console
Warning: com.example.android.MenuFragment$1: can't find referenced class com.example.android.TempActivity
Warning: com.example.android.ToolsFragment: can't find referenced class com.example.android.ImportAsyncFragment
Warning: com.example.android.ToolsImportFragment$1: can't find referenced class com.example.android.ImportAsyncFragment
...

EclipseのADTバージョンによるproguard設定の指定方法の違い

Eclipse 3.6ベースのADTを使っていた時には、project.propertiesにproguard.cfgファイルを指定していました。

...
target=android-4
proguard.config=proguard.cfg...
...

この時のproguard.cfgは必要な設定全体を含んでいましたが、 Android 3.7ベースのADT 18.0.0では、project.propertiesに次のような行が含まれています。

...
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
...

コメントの一部なのでまぎらわしいですが、proguard.configで始まる一行をコメントアウトして、システム全体で共通の設定ファイルを使うように変更されています。

自分のアプリケーション用の設定は、AndroidManifest.xmlなどと同じフォルダにproguard-project.txtを作成し、 差分だけを記述するように変更されています。

Proguard トラブルシューティング記事のまとめ

proguardサイトのトップページから"Manual"をクリックすると、左のメニューが変化して"Troubleshooting"ページにアクセスする事ができるようになります。

can't find referenced classで検索すると、3つの項目が並んでいました。 Eclipseを使ってAndroidアプリを開発している場合には、1,2はなさそうです。

選択肢1. 必要なjarファイルが指定されていない場合

指定漏れのあるjarファイルがあれば、-injarsオプションなどで適宜追加するように書かれています。 コマンドラインでビルドする場合には注意が必要でしょうが、Eclipse内でビルドが正常に完了して、Eclipseからproguardを起動していれば必要ないはずです。

選択肢2. アプリケーションの稼働に不要なクラスの参照関係が解決できない場合

ワーニングに指定されているクラスへの参照は必要ないから、解決できなくても動くよ、そんな場合にはfilter outの指定をするように書かれています。

これは1.との合わせ技で、-injarsで指定するjarファイルの後ろに無視する条件を指定する方法で、これもEclipseを使っていれば本来必要ないはずです。

選択肢3. filter outが気に入らなければ-ignorewarningsか-dontwarnを使えばいいよ

ほとんどのEclipseでAndroidアプリを開発している場合にあてはまるのが、このオプションを指定する場合だと思います。

StackOverflowなんかをみていても、-dontwarnを指定すればいいんじゃない?、というアドバイスが多かったです。

Troubleshootingページをみると、"-dontwarn java.awt.**" みたいな指定ができるので、 自分が作成した同一パッケージ内でのクラスの参照関係が解決できなくても無視するように次のような設定をしています。

現状のproguard-project.txt全体

-keepclassmembers class com.example.android.InfoFragment.DemoJavaScriptInterface {
   public *;
}
-dontwarn com.example.android.*

WebViewを使ってJavaScript用にオブジェクトを設定している場合には、そのクラスを指定するように書かれているので、その下に-dontwarn行を追加しました。

さいごに

署名済みAPKファイルは無事に生成できるようになりました。

別のprogurad.cfgの挙動が変化した分けじゃないんですが、ADTをアップグレードして空のプロジェクトを生成した時にproguard.cfgがなくなったりすると、そのまま昔のproguard.cfgをproguard-project.txちょっとした混乱が起きそうです。

Googleで解決策がみつかるのは良いんですが、そのまま信用して簡単な策を取ると、いろいろ問題がありそうですね。 まぁ趣味の範囲なら、なんでも良いんですけれど。

いろいろな事がボーダーレスになって、プロとアマチュアの境界があいまいになりつつあるのが、少し怖いです。 怖いのはアマチュアに侵食されるんじゃなくて、プロのはずがアマチュアに落ちる事なんですけどね。

0 件のコメント: