2011-08-15 36 views
3

比方說,我有這樣的Java應用程序:的java的ProGuard刪除(收縮)未使用的類

package com.site; 

public class MyAppBase {} 

package com.site.free; 

import com.site.MyAppBase; 

public class MyApp extends MyAppBase {} 

package com.site.pro; 

import com.site.MyAppBase; 

public class MyApp extends MyAppBase {} 

package com.site; 

public class Edition 
{ 

    public static final int  FREE = 1; 
    public static final int  PRO  = 2; 

    private static final int EDITION = PRO; 

    public static boolean is(final int edition) 
    { 
     return (EDITION == edition); 
    } 
} 

現在
package com.site; 

public class EditionFactory 
{ 

    public static MyAppBase get_app() 
    { 
     MyAppBase ret = null; 

     if (Edition.is(Edition.FREE)) 
      ret = new com.site.free.MyApp(); 
     else if (Edition.is(Edition.PRO)) 
      ret = new com.site.pro.MyApp(); 

     return ret; 
    } 
} 

,我想ProGuard的配置的任何組合,擺脫非選擇的版本(在這種情況下,它是免費的)無法正常工作。通過「擺脫」我的意思是使實際的類消失(以及來自調用代碼)。

換句話說,這樣一個電話:

final MyAppBase app = EditionFactory.get_app(); 

..目前正在翻譯成,ProGuarding之後,這樣的:

if (a.a(1)) 
    localObject5 = new c(); // <<< FREE 
else if (a.a(2)) 
    localObject5 = new d(); // <<< PRO 

..同時我也希望被翻譯成這樣:

localObject5 = new d(); // <<< PRO only in the code (as set at Edition.EDITION) 

底線是除了ProGuard是偉大的事實!),我似乎無法使其「透視」,並明白,Edition.is()是一個布爾函數,返回一個常量,它可以刪除一些類。

我已經試過類似的配置:

-keep,allowshrinking,allowoptimization public class * extends com.site.MyAppBase 
-optimizationpasses 10 

..沒有工作。另一方面,如果我參考Edition.EDITION並比較它內聯(即沒有任何「代理」函數),Java編譯器(v1.6)會檢測它並刪除整個非引用的引用 - 選擇版/類。
這導致ProGuard移除/縮小非常好的未使用的類。

這裏唯一的問題是關於維護 - 我很樂意繼續使用EditionFactory風格。

回答

7

優化不會執行,因爲ProGuard決定不內嵌方法Edition#is,因此它不能簡化所得到的一系列指令。該方法不是內聯的,因爲它不是非常短的,而且它也被調用多次。你可以解決第一個標準,這個無證JVM選項的ProGuard:

-Dmaximum.inlined.code.length=16 

或者,你可以解決的第二個標準,以確保該方法只調用一次:

return Edition.is(Edition.FREE) ? 
    new com.site.free.MyApp() : 
    new com.site.pro.MyApp(); 

或者,你可能會創建短函數isFree()和isPro(),因爲它們會返回將被內聯的常量。

如果您期待某些特定優化,那麼檢查已處理的代碼是一種很好的做法,因爲它們通常受到複雜的約束。

很高興聽到你喜歡ProGuard。

1

這是因爲你的方法is(...)可以在多個值僅比1和2。它可以在代碼的其他地方用3,4,6來調用...... Proguard不能排除這種情況。

解決您的問題是使Editionenum。您不再需要is(...)方法,可以依賴equals(...)

+0

你的意思是讓'版本'爲'enum'? –

+0

不工作JVerstry,但謝謝你的努力.. – Poni

+0

哎呀,對不起,錯字,我的意思是版本。 – JVerstry