Proguard メモ

忘れること多いので

## aar作成時にProgurad設定も一緒に入れておきたい

2015/07/22 追記

consumerProguardFiles という設定がある
なんと0.5.7の頃から…
[サンプルとrelease note に書いてある](http://tools.android.com/system/app/pages/search?scope=search-site&q=consumerProguardFiles)

[stack overflow見て知りました…](http://stackoverflow.com/a/27052696/4221135)


## こんなpluginとかがあった

2015/03/08 追記

素晴らしい

* [gradle-proguard-plugin](https://github.com/hotchemi/gradle-proguard-plugin)

こちらの[proguard設定を集めているところ](https://github.com/krschultz/android-proguard-snippets)から設定を取ってくるようですね

## 知らいない間にproguard-annotationsがMITライセンスで公開されていた

2015/06/12 追記

[ここ](https://android-arsenal.com/details/1/1833)

```
dependencies {
    compile "com.infstory:proguard-annotations:1.0.2"
}
```

proguard-annotations 確かにライセンスは気になっていたのでMITと明記してくれるのは嬉しい…
んだけど、これ本当に良いんだろうか…コードのCopyrightの人と違うけど…どういうあれになるんだろ

## 使っているライブラリを守る

AndroidをターゲットとしているLibraryなら、どこかしらに記載がある…気がする

無ければStackOverFlowをググったり（？）なんだりする

[よく使いそうなライブラリに関してまとめてくれている人もいる](http://qiita.com/tsuyosh/items/9dd3c6b9dc11b5f640be)

[gitignore.io](https://www.gitignore.io/) みたいなサイト欲しいですね(誰か作って)

あと以下に自分が最近良く使うLibraryに関連する設定を備忘的に

### retrolambda

https://github.com/evant/gradle-retrolambda#proguard

### RxJava (RxAndroid)

[RxJavaProGuardRules](https://github.com/artem-zinnatullin/RxJavaProGuardRules/blob/master/rxjava-proguard-rules/proguard-rules.txt)を参考に。

```proguard-rules.pro
-dontwarn sun.misc.Unsafe

-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
   long producerIndex;
   long consumerIndex;
}

-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
   long producerNode;
   long consumerNode;
}
```

この `keepclassmembers` を記述しておかないとこんな感じのエラーが発生することがある。

```java
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime: java.lang.InternalError
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.internal.util.unsafe.UnsafeAccess.a(SourceFile:103)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.internal.util.unsafe.SpscArrayQueueProducerFields.<clinit>(SourceFile:39)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.<init>(SourceFile:102)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.internal.operators.OperatorObserveOn.a(SourceFile:64)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.internal.operators.OperatorObserveOn.call(SourceFile:44)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.Observable$2.a(SourceFile:158)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.Observable$2.call(SourceFile:154)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.Observable$2.a(SourceFile:162)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.Observable$2.call(SourceFile:154)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.Observable.a(SourceFile:7804)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.Observable.b(SourceFile:7772)
10-22 11:46:03.926 2680-2680/? E/AndroidRuntime:     at rx.Observable.a(SourceFile:7574)
```

(上記は[konifarさん](http://qiita.com/konifar)が追記してくれました。ありがとうございました。)

[RxJavaProGuardRules](https://github.com/artem-zinnatullin/RxJavaProGuardRules#download)に記載されているように、依存関係に突っ込むのが楽かも

### functionaljava

2016/04/08 修正
現Versionの4.5ではretrolambdaに起因するものだけになりました（しました）
ので`-dontwarn java.lang.invoke**` だけで良いはず… 


## 自分のコードに適応する

### proguard annotations.jar の利用

何気に最近存在知った…

[この辺参考に](http://qiita.com/KeithYokoma/items/2f9dde7edd467e603e97)

ただ`-dontshrink`付ける必要はない(てかつけたらproguardとしての効果減るし)

一応手順を

`$ANDROID_HOME/tools/proguard/examples/annotations/lib/annotations.jar`

を依存関係に追加

`$ANDROID_HOME/tools/proguard/examples/annotations/lib/annotations.pro`

も使う

annotations.proをちょっと書き換える

```
#L17ぐらい
#依存関係に追加しているので要らなくなる
#-libraryjars annotations.jar
```

どっかに追加しとく

```
# annotations.jarの中身そのものが吹っ飛ぶのを避ける為に追加
# これを追加することで -dontshrink せずに済む
-keep class proguard.annotation.** {*;}
```

後は保護したいクラスやメソッドやFieldにアノテーションを付ける

txtでproguardの設定書かないメリットとして、IDEで一括リネームした時とかに有り難みを感じる

### build.gradle

```
android {
    buildTypes {
        beta {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'annotations.pro'
        }

        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'annotations.pro', ...
        }
    }
}
```

BuildTypeで最適化Option付きを選んだり選ばなかったりしている

### Genericの情報が

http://d.hatena.ne.jp/takeR/20120712/1342072534

Signature 結構忘れる


### 確認

とはいうものの実際Proguard結果がどうなったか気になることは多いはず

そんな時は`app/build/outputs/mapping` 以下とかみて確認する




## ProguardそのもののVersionを変えたい

2016/12/07追記

Android Studio 2.3から 5.3.2になるっぽいです。
[別のやつに書きました](http://qiita.com/daneko0123/items/e85ba853677692a428cb#20161207-%E8%BF%BD%E8%A8%98)が、仮に今直ぐあげるのなら **5.3.2** を選択しましょう。

2016/10/22追記

[ここ](http://stackoverflow.com/a/27553923)

2016/10/22時点でのandroidのGradlePlugin(2.2.2)が依存するProguardのVersionは 5.2.1

で、つい先日[これに近い(同じ？)現象に遭遇](https://sourceforge.net/p/proguard/bugs/437/#bd7f)

結果としてProguardを現行のVersion(5.3)にすることで回避できました

```sh
Unexpected error while performing partial evaluation:		
   Class       = [...]		
   Method      = [...]		
   Exception   = [java.lang.IllegalArgumentException] (Stacks have different current sizes [0] and [1])
```

みたいなのが起きたら、とりあえず

```gradle
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath ('com.android.tools.build:gradle:2.2.2') {
            exclude module: 'proguard-gradle'
        }
        classpath ('net.sf.proguard:proguard-gradle:5.3') {
            force = true
        }

    }
}
```

で回避できるかも？

なお、Optimize機能を利用しないなら関係のない話です