2

「抽象クラスのインスタンス化」とあなたは言います。"不可能!"

これが私のコードです:

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構成ファイルに次のようなステートメントを追加し続けます

-keep public abstract class  AbstractFoo
{public *;protected *; private *;} 

しかし、それでは問題は解決しません。これがAbstractFooオブジェクトをインスタンス化する有効な方法であることをProguardに受け入れさせるにはどうすればよいですか? 少なくとも、Proguard なしで動作する場合は、Proguard で動作するはずです。

4

2 に答える 2

7

未使用のように見えるため、ProGuard はコードからコンストラクターを削除しています。ProGuard は、コンストラクターがリフレクションによって呼び出されていることを検出できません。したがって、明示的に保持する必要があります。

-keepclassmembers class com.bat.baz.FooBar {
  <init>(java.lang.String, java.lang.String);
}

ProGuard のヘルプ フォーラムで、このような質問をする可能性が高くなる可能性があることに注意してください。

于 2010-10-31T11:14:25.147 に答える
0

FooBar に保持するためのステートメントも追加していますか?

「dexdump」または「dexlist」を使用して、実際に .dex ファイルに生成されるクラスとメソッドのリストを表示できます。プロガードを使用した場合と使用しない場合の結果を比較すると、明らかになる可能性があります。

于 2010-10-29T23:39:33.203 に答える