Proguard、Android、および抽象クラスのインスタンス化
-
27-09-2019 - |
質問
「抽象クラスのインスタンス化」とあなたは言います。 "不可能!"
これが私のコードです:
public static AbstractFoo getAbstractFoo(Context context) {
try {
Class<?> klass = Class
.forName("com.bat.baz.FooBar");
Constructor<?> constructor = klass.getDeclaredConstructor(
String.class, String.class);
constructor.setAccessible(true);
AbstractFoo foo = (AbstractFoo) constructor.newInstance(
"1", "2");
return foo;
} catch (ClassNotFoundException e) {
// Ignore
} catch (NoSuchMethodException e) {
throw new InflateException(
"No matching constructor");
} catch (IllegalAccessException e) {
throw new InflateException("Could not create foo", e);
} catch (InvocationTargetException e) {
throw new InflateException("Could not create foo", e);
} catch (InstantiationException e) {
throw new InflateException("Could not create foo", e);
}
return null;
}
com.bat.baz.foobarは、abstractfooを拡張するプライベートクラスです。 Proguardがなければ、このコードはAndroidデバイスで実行されます。それにより、それはnosuchmethodexception try/catchで失敗します。
Proguard configファイルにステートメントを追加し続けます
-keep public abstract class AbstractFoo
{public *;protected *; private *;}
しかし、それは問題を解決しません。これがAbstractFooオブジェクトをインスタンス化する有効な方法であることをProguardに受け入れるにはどうすればよいですか?少なくとも、それがProguardなしで機能する場合、それはそれで動作するはずです。
解決
Proguardは、未使用のように見えるため、コードからコンストラクターを削除しています。 Proguardは、コンストラクターが反射によって呼び出されていることを検出できません。したがって、あなたはそれを明示的に保つ必要があります:
-keepclassmembers class com.bat.baz.FooBar {
<init>(java.lang.String, java.lang.String);
}
Proguard's Helpフォーラムに関するこれらのような質問でより良いチャンスがあるかもしれないことに注意してください。
他のヒント
また、Foobarに物を保つためのステートメントも追加していますか?
「dexdump」または「dexlist」を使用して、.dexファイルに実際に生成されたクラスとメソッドのリストを表示できます。 Proguardの場合とそれなしで得られるものを比較することは、照らされる可能性があります。
所属していません StackOverflow