読者です 読者をやめる 読者になる 読者になる

ProGuard試行錯誤のメモ

ProGuard 単純なプロジェクトにはかかるんだけど
ちょっと複雑なプロジェクトになると上手く行かず。。。
とりあえず試行錯誤のつぶやきとかメモ。また同じ事悩みそうなので・・

まず基本的なantでのbuild.xmlの話はここらへん

一応蛇足だけど作ったapkは下記みたいなシェルを作っておくと後々楽

  • apk_install.sh
#!/bin/sh
pkgname=パッケージ名
activity=起動クラス名

if [ $# -eq 0 ]; then
  echo "=== usage: ===" 
  echo "   ./apk_install.sh XXX.apk"
  echo "   ./apk_install.sh XXX.apk 123456789"
  exit 0
fi

if [ $# -eq 2 ]; then
  echo " === $2 start ==="
  adb -s $2 shell am force-stop $pkgname
  adb -s $2 uninstall $pkgname 
  adb -s $2 install $1
  adb -s $2 shell am start -a android.intent.action.MAIN -n $pkgname/$activity
  echo " === $2 end ==="
  exit 0
fi


for SERIAL in `adb devices | sed -e "s/List of devices attached//" | sed -e "s/device//"`
do
  echo " === $SERIAL start ==="
  adb -s $SERIAL shell am force-stop $pkgname
  adb -s $SERIAL uninstall $pkgname 
  adb -s $SERIAL install $1
  adb -s $SERIAL shell am start -a android.intent.action.MAIN -n $pkgname/$activity
  echo " === $SERIAL end ==="
done

exit 0

あと proguardかけた後のStackTraceを終えないと後で困るので下記のサイトで手順は把握しておくこと

でも見た感じ具体的な行数までは出てこないみたいなんだよな。。。
関数名はわかるようになるんだけど。


備考)

みてると一応パスの問題は最新だと直ってるみたい

  • disp_proguard.sh
#!/bin/sh
$ANDROID_HOME/tools/proguard/bin/retrace.sh -verbose ./bin/proguard/mapping.txt $1

をプロジェクトの直下において実行すればOK。
ただし ./bin以下って ant clean すると消えるので
直下にコピーしておいたほうがいいかなーとか思ったりもしてる(汗



想定構成は

  1. MainP(use twitter4j)


android update project -p ./ -l ./../libP
・libP(use Ad SDK)

android update project -p ./
として、それぞれのフォルダにbuild.xmlを生成した時

  1. MainP側のprogurad.cfg
-dontwarn
-keep class twitter4j.** {*;}

辺りを追加。-dontwarn の後ろにクラスを指定しない場合は全対象になる*1

  1. libP側のprogurad.cfg の末尾あたりに追記
-keep class com.ad_stir.** {*;}
-keep class com.ngigroup.** {*;}
-keep class com.google.ads.** {*;}
-keep class jp.co.nobot.libAdMaker.** {*;}
-keep class jp.Adlantis.Android.** {*;}
-keep class jp.co.imobile.android.** {*;}
-keep class jp.co.cyberagent.** {*;}
-keep class mediba.ad.sdk.android.openx.** {*;}
-keep class net.nend.android.** {*;}
-keep class jp.co.dac.smarti.android.** {*;}
-keep class com.inmobi.androidsdk.** {*;}

-keep class jp.co.nobot.libYieldMaker.** {*;}
-keep class jp.co.microad.smartphone.sdk.** {*;}
-keep class net.zucks.zucksAdnet.sdk.** {*;}

# original assain image
-keep class [package name].** {*;}

# admob warn
-dontwarn com.google.ads.**
-dontwarn jp.co.cyberagent.AMoAdView


annotaionベースのproguardの話はここらへんの話

proguard/annotation.jarを使う場合は

-include libs/annotations.pro

宣言を追加し
libP/libs辺りに

  • annotation.jar
  • annotation.pro
#
# This ProGuard configuration file specifies how annotations can be used
# to configure the processing of other code.
# Usage:
#     java -jar proguard.jar @annotations.pro -libraryjars annotations.jar ...
#
# Note that the other input/output options still have to be specified.
# If you specify them in a separate file, you can simply include this file:
#     -include annotations.pro
#
# You can add any other options that are required. For instance, if you are
# processing a library, you can still include the options from library.pro.


# The annotations are defined in the accompanying jar. For now, we'll start
# with these. You can always define your own annotations, if necessary.
-libraryjars annotations.jar # ★相対パス


# The following annotations can be specified with classes and with class
# members.

# @Keep specifies not to shrink, optimize, or obfuscate the annotated class
# or class member as an entry point.

-keep @proguard.annotation.Keep class *

-keepclassmembers class * {
    @proguard.annotation.Keep *;
}


# @KeepName specifies not to optimize or obfuscate the annotated class or
# class member as an entry point.

-keepnames @proguard.annotation.KeepName class *

-keepclassmembernames class * {
    @proguard.annotation.KeepName *;
}


# The following annotations can only be specified with classes.

# @KeepImplementations and @KeepPublicImplementations specify to keep all,
# resp. all public, implementations or extensions of the annotated class as
# entry points. Note the extension of the java-like syntax, adding annotations
# before the (wild-carded) interface name.

-keep        class * implements @proguard.annotation.KeepImplementations       *
-keep public class * implements @proguard.annotation.KeepPublicImplementations *

# @KeepApplication specifies to keep the annotated class as an application,
# together with its main method.

-keepclasseswithmembers @proguard.annotation.KeepApplication public class * {
    public static void main(java.lang.String[]);
}

# @KeepClassMembers, @KeepPublicClassMembers, and
# @KeepPublicProtectedClassMembers specify to keep all, all public, resp.
# all public or protected, class members of the annotated class from being
# shrunk, optimized, or obfuscated as entry points.

-keepclassmembers @proguard.annotation.KeepClassMembers class * {
    *;
}

-keepclassmembers @proguard.annotation.KeepPublicClassMembers class * {
    public *;
}

-keepclassmembers @proguard.annotation.KeepPublicProtectedClassMembers class * {
    public protected *;
}

# @KeepClassMemberNames, @KeepPublicClassMemberNames, and
# @KeepPublicProtectedClassMemberNames specify to keep all, all public, resp.
# all public or protected, class members of the annotated class from being
# optimized or obfuscated as entry points.

-keepclassmembernames @proguard.annotation.KeepClassMemberNames class * {
    *;
}

-keepclassmembernames @proguard.annotation.KeepPublicClassMemberNames class * {
    public *;
}

-keepclassmembernames @proguard.annotation.KeepPublicProtectedClassMemberNames class * {
    public protected *;
}

# @KeepGettersSetters and @KeepPublicGettersSetters specify to keep all, resp.
# all public, getters and setters of the annotated class from being shrunk,
# optimized, or obfuscated as entry points.

-keepclassmembers @proguard.annotation.KeepGettersSetters class * {
    void set*(***);
    void set*(int, ***);

    boolean is*();
    boolean is*(int);

    *** get*();
    *** get*(int);
}

-keepclassmembers @proguard.annotation.KeepPublicGettersSetters class * {
    public void set*(***);
    public void set*(int, ***);

    public boolean is*();
    public boolean is*(int);

    public *** get*();
    public *** get*(int);
}


ant release
時にprogurad.cfgを有効にするには、project.properies の

proguard.config=proguard.cfg

を有効にするイメージ

mapping.txtで確認
実行後にMainP側の

  • bin/proguard/

の下に生成される

引っかかった処<要除外設定)

  • Serializeしているクラス
  • staticフィールドがあるクラス

まあ Proguardかけるのはいいけど、復元にはmapping.txtを残しておく必要が有る*2

参考リンク)
なんか環境によりproguardの本家のjar入れないと動かない場合があるらしい((たしかに以前あったような、、))

addJavascriptInterfaceの対象クラスもproguard除外対象にしないとダメの話




備考)
ADT21でのproguart-project.txt になおしてみた(2013/03/12)

  • MainP/proguart-project.txt
-include libs/pro_annotations.pro

#-dontwarn
#-dontnote
-dontwarn twitter4j.**
-dontnote twitter4j.**
-keep class twitter4j.** {*;}

-dontwarn facebook4j.**
-dontnote facebook4j.**
-keep class facebook4j.** {*;}

悩んだのは

わけわからん。。

見てると個別に指定できるよう

  • libP/proguart-project.txt
-include libs/pro_annotations.pro

-keep class com.ad_stir.** {*;}
-keep class com.ngigroup.** {*;}

-keep class com.google.ads.** {*;}
-keep class jp.co.nobot.libAdMaker.** {*;}
-keep class jp.Adlantis.Android.** {*;}
-keep class jp.co.imobile.android.** {*;}
-keep class jp.co.cyberagent.** {*;}
-keep class mediba.ad.sdk.android.openx.** {*;}
-keep class net.nend.android.** {*;}
-keep class jp.co.dac.smarti.android.** {*;}
-keep class com.inmobi.androidsdk.** {*;}

-keep class jp.co.nobot.libYieldMaker.** {*;}
-keep class jp.co.microad.smartphone.sdk.** {*;}
-keep class net.zucks.zucksAdnet.sdk.** {*;}


-dontwarn com.google.ads.**
-dontwarn jp.adlantis.admediation.adapters.AMoAdAdapter
-dontnote jp.adlantis.android.**

-dontwarn com.ad_stir.adapters.** //☆
-dontnote com.ngigroup.adstir.adapters.** //☆

-dontnote **ILicensingService  //☆
-dontnote **InstallReceiver //☆

☆は新規引っかかった。
adstir と AdMob更新したからかも‥‥


AdMob絡みだと

な話もあるよう

PS)
実際はadstirの公式wikiが間違ってたらしい(汗




追記1)

nakamap 1.7 でていたので更新してみる。
今回はキャッシュでははまらなかったけど、試しにProGuardかけてみたらバッチ押しても動かず。。何が悪いんだろう?
一応wikiの記述を参考にして nakamap用のproguard.cfgは設定してみているんだけど。。。

nakamapのwikiだと

  • project.properties
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard.cfg:nakamapsdk-proguard.cfg

を有効にするイメージでしたけど、動かせたのは下記(nakamap-sampleから nakamapsdk-proguard.cfgコピーは忘れずに)

proguard.config=proguard.cfg:nakamapsdk-proguard.cfg




追記2)

のつぶやき見てると、proguard-android.txtの参照って
proguardを最新にする って話らしいんだけど、引っかかるのはなんでだろ。ちょっと保留課題かも
<実際新しく作って比べてみてもたいして差分がなかった。。

  • project.properties
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt:nakamapsdk-proguard.cfg

追記2+)

 PASS等もわからないのでkey作りなおしたけど。。。 まあずっと放置されてたアプリだったしね(苦笑。勿論以前の担当者の人は既にいないorz
CMうつタイミングで緊急改修的な
そこら辺の話は androidのgradle対応の話 - exception think にメモってる

  • project.properties
android.library.reference.1=../libP
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:${android.library.reference.1}/proguard.cfg:proguard-project.txt




追記3)
NDK絡みの話

正直

らへんの話もあるのでちゃんと抑えておかないと駄目なんだろうな(汗

LVLの話)



追記4)

Interface周りの話)

http://twitter.com/kimukou2628/status/334250725540499457:twitter:detail:right

http://twitter.com/kimukou2628/status/334255433684484097:twitter:detail:right
http://twitter.com/kimukou2628/status/334256715115679744:twitter:detail:right
http://twitter.com/kimukou2628/status/334263622442307584:twitter:detail:right
http://twitter.com/kimukou2628/status/334268322927480832:twitter:detail:right
http://twitter.com/kimukou2628/status/334269526264918017:twitter:detail:right
http://twitter.com/kimukou2628/status/334463672091037696:twitter:detail:right
http://twitter.com/kimukou2628/status/334464523677351937:twitter:detail:right



TL上のメモ等)

*1:twitter4jが色々と外部ライブラリ参照してるよう

*2:何時も消してる気がする。。。