2010-10-29 161 views
2

「抽象類實例化」,你說。 「不可能!」Proguard,Android和抽象類實例化

這裏是我的代碼:

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,它應該可以工作。

回答

7

ProGuard從代碼中刪除構造函數,因爲它看起來沒有用。 ProGuard無法檢測到構造函數正在被反射調用。所以,你必須保持它明確:

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

請注意,你可能有與ProGuard的的幫助論壇這樣的問題更好的機會。

0

您是否還添加語句以保留FooBar中的內容?

您可以使用「dexdump」或「dexlist」來查看實際生成到.dex文件中的類和方法的列表。比較你有沒有proguard可以得到照亮。

+1

我沒有弄清楚你的方法,但我最終發現了什麼。我檢查了我的mapping.txt文件,發現FooBar的構造函數沒有被添加。上面的變量和下面的方法正在被轉換,但構造函數根本就不存在。我目前正試圖弄清楚爲什麼即使在明確聲明 GJTorikian 2010-10-30 01:45:42