Gson EnumTypeAdapter で Proguard Obfuscation を使用すると AssertionError が発生する。
2023-09-27 22:30:19
質問
私のプロジェクトでは
TypeAdapter
で
Gson
をシリアライズ/デシリアライズする際に、オブジェクトのポリモーフィズムの状態を保持するために使用します。とにかく、このプロジェクトは開発テストの間はうまくいくのですが、リリースするときに
proguard 難読化
を付けてリリースし、テストすると、クラッシュしてしまいます。
03-21 10:06:53.632: E/AndroidRuntime(12441): FATAL EXCEPTION: main
03-21 10:06:53.632: E/AndroidRuntime(12441): java.lang.AssertionError
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.TypeAdapters$EnumTypeAdapter.<init>(SourceFile:724)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.TypeAdapters$26.create(SourceFile:753)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.getAdapter(SourceFile:353)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(SourceFile:82)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(SourceFile:81)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(SourceFile:118)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(SourceFile:72)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.getAdapter(SourceFile:353)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.toJson(SourceFile:578)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.toJsonTree(SourceFile:479)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson.toJsonTree(SourceFile:458)
03-21 10:06:53.632: E/AndroidRuntime(12441): at com.google.gson.Gson$3.serialize(SourceFile:137)
私のGson特有のproguardの設定は
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
#This is extra - added by me to exclude gson obfuscation
-keep class com.google.gson.** { *; }
##---------------End: proguard configuration for Gson ----------
この TypeAdapter 使っているのは
public final class GsonWorkshiftAdapter implements JsonSerializer<IWorkshift>, JsonDeserializer<IWorkshift> {
private static final String CLASSNAME = "CLASSNAME";
private static final String INSTANCE = "INSTANCE";
@Override
public JsonElement serialize(IWorkshift src, Type typeOfSrc, JsonSerializationContext context) {
String className = src.getClass().getCanonicalName();
JsonElement elem = context.serialize(src);
JsonObject retValue = new JsonObject();
retValue.addProperty(CLASSNAME, className);
retValue.add(INSTANCE, elem);
return retValue;
}
@Override
public IWorkshift deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
String className = prim.getAsString();
Class<?> klass = null;
try { klass = Class.forName(className); }
catch (ClassNotFoundException e) { throw new JsonParseException(e.getMessage()); }
return context.deserialize(jsonObject.get(INSTANCE), klass);
}
}
Gsonに特化したこのエラーについていろいろと検索してみましたが、参考になる回答は見つかりませんでした。しかし、私は見つけた 別の質問 を見つけました。
開発者コミュニティからのどんな助けでも感謝します。
どのように解決するのですか?
列挙のメンバーを保持するように要求する必要があるようです。 proguard の設定ファイルにこれを追加すると、私の場合はうまくいきました。
-keepclassmembers enum * { *; }
あるいは、もっと具体的に言うなら
-keepclassmembers enum com.your.package.** { *; }
関連
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み] ArrayAdapter<myClass> の使用方法
-
[解決済み] getApplication()、getApplicationContext()、getBaseContext()、someClass.thisの違いと使い分け。
-
[解決済み] アプリ内課金テスト:android.test.purchased already owned
-
[解決済み] データベースでリサイクルビューを使用する
-
[解決済み] Android Studioの「未実装メソッドの追加」機能
-
[解決済み] Android - Snackbar vs Toast - 使い方と違い。
-
[解決済み] AndroidでTextViewの下にアンダーラインを引くには
-
[解決済み] フラグメント間の値の受け渡し方法
-
[解決済み] Travis.yml ./gradlew : パーミッションが拒否されました。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Androidのソースコードにある@hideの意味とは?
-
[解決済み] AppCompat-v7 21でアクションバー/ツールバーにアイコンを表示する。
-
[解決済み] TabLayoutに対応したandroidデザインでタブテキストのフォントを変更する
-
[解決済み] onCreate(Bundle savedInstanceState)とは?
-
[解決済み] Studio 3.4 をアップデートしたら、引数の leftShift() メソッドが見つかりませんでした。
-
[解決済み] 複数のフィルタを持つBroadcastReceiverか、複数のBroadcastReceiverか?
-
[解決済み] AndroidでTextViewの下にアンダーラインを引くには
-
[解決済み] グリッドビューの高さが削減される
-
[解決済み] PendingIntentの "requestCode "は何に使うのですか?
-
[解決済み] BottomNavigationViewを新しいNavControllerで使用する際に、フラグメントを生かす方法はありますか?