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

但这并不能解决问题。如何让 Proguard 接受这是实例化 AbstractFoo 对象的有效方法?至少,如果它在没有 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 文件中的类和方法的列表。比较使用和不使用 proguard 得到的结果可能很有启发性。

于 2010-10-29T23:39:33.203 回答