Dexguard を 7.0.12 から 7.1.22 に更新した後、Enum スイッチでクラッシュが発生しました。
これは、プロジェクトで Dexguard が実行されている場合にのみ発生します (これは Proguard の問題が原因だと思います)。
ハードコーディングされた値を使用すると、クラッシュは発生しません。
もちろん、ハードコードされた値の使用は避けたいと思います。
クラッシュ
発生するクラッシュは次のとおりです
java.lang.NoClassDefFoundError: Failed resolution of: Lif;
これは、次の行で発生しますswitch(type) {
(以下を参照)
例
アプリがクラッシュするコードの例 (MyEnum がもちろん Enum である場合):
MyEnum type = MyEnum.SomeValue;
switch (type) {
case SomeValue:
// Do something
Log.i("Tag", "Hello world!");
break;
}
の序数値が 1 であると仮定しますMyEnum.SomeValue
。
に変更case SomeValue:
するcase 1:
と、期待どおりに動作します。
私が試したこと
このクラッシュが発生する理由はわかりません。これらの Proguard ルールを追加しようとしました。
-keep enum * { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
しかし、これで問題は解決しません。
アップデート
マッピングファイルを確認したところ、すべての列挙名などが保持されています。今、私は何が起こっているかについてさらに無知です。
my.identifier.MyEnum -> my.identifier.MyEnum:
my.identifier.MyEnum SomeValue -> SomeValue
my.identifier.MyEnum[] $VALUES -> $VALUES
6:6:my.identifier.MyEnum[] values() -> values
6:6:my.identifier.MyEnum valueOf(java.lang.String) -> valueOf
6:6:void <init>(java.lang.String,int) -> <init>
6:7:void <clinit>() -> <clinit>
更新 2
ちょうど出力を見てみました。これにコンパイルされます。スタック トレースから判断すると、if
Proguard によって保持されていないと思われます。これはどこで定義されていますか?Proguardにこれを保持させるには何を追加する必要がありますか?
switch(if.ˊ[var2.ordinal()]) {
case 1:
//some other code
break;
更新 3
中間体では、コード行は次のようになります。
switch(null.$SwitchMap$my$identifier$MyEnum[type.ordinal()]) {
case 1:
//some other code
break;
null.$
それが私を悩ませているという事実。それは正しくないようです。またはそれは正常ですか?
更新 4
古いバージョンの Dexguard に戻し、追加した Proguard ルールを削除しました。
コードはまったく同じように見えますが、クラッシュは発生しなくなりました。(中間体と完全にコンパイルされたコード)
更新 5
Dexguard 7.2 に切り替えたところ、問題なく動作しました。