Proguard,Android和抽象类实例化

时间:2010-10-29 16:00:51

标签: android abstract-class proguard

“抽象类实例化”,你说。 “不可能!”

这是我的代码:

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 *;} 

但这并没有解决问题。如何让Proguard接受这是实例化AbstractFoo对象的有效方法?至少,如果它在没有Proguard的情况下工作,它应该可以使用它。

3 个答案:

答案 0 :(得分:7)

ProGuard正在从代码中删除构造函数,因为它似乎未使用。 ProGuard无法检测到反射调用构造函数。所以,你必须明确地保持它:

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

请注意,您可能有更多机会在ProGuard的帮助论坛上提出类似问题。

答案 1 :(得分:0)

您是否还要添加语句以保留FooBar中的内容?

您可以使用“dexdump”或“dexlist”查看实际生成到.dex文件中的类和方法列表。比较你得到的和没有proguard的东西可能很有启发性。

答案 2 :(得分:0)

如果您想应用整个扩展AbstractFoo的类

-keepclassmembers class * extends xxx.xxx.AbstractFoo{
  <init>(android.content.Context);
}