2014-03-28 64 views
2

我有日誌記錄靜態方法的類,如:刪除日誌要求使用ProGuard留下StringBuilders

我試圖刪除所有這些使用ProGuard。我不想僅僅禁用它們(反正用邏輯來完成),我希望它們在反編譯時消失。

它正在成功刪除對我的日誌記錄方法的調用,但留下了連接的字符串。它完全刪除了已修復的字符串。

這是我的ProGuard設置:

-assumenosideeffects class com.mypackage.Log { *; } 

這是我的源:

void doSomething(String name) { 
    Log.verbose("Hello!"); 
    Log.verbose("My name is " + name); 
    ... 
} 

這是它反編譯到:

void a(String a) { 
    new StringBuilder("My name is ").append(a); 
    ... 
} 

這就是我希望它反編譯爲:

void a(String a) { 
    ... 
} 

對於此示例,假定名稱參數稍後在方法中使用(即不應完全優化)。

我還應該使用assumenosideeffects作爲StringBuilder嗎?我在其他地方使用了StringBuilders,我確實想保留它。那也會在那裏把他們刪除嗎?

+0

您使用的是哪種日誌記錄框架?用log4j你可以寫Log.verbose(「我的名字是#0」,名字);而不是Log.verbose(「我的名字是」+ name);只有在必要時纔會發生串聯,即如果loglevel> = verbose。 – StephaneM

+0

[在ProGuard優化期間刪除未使用的字符串]可能的副本(http://stackoverflow.com/questions/6009078/removing-unused-strings-during-proguard-optimisation) – sschuberth

回答

1

很好,你檢查結果是否如預期。在這種情況下,ProGuard並不知道StringBuilder操作沒有任何網絡效應,因此它會將它們留在中。您可以在Removing unused strings during ProGuard optimisation問題中找到相當完整的討論。

最近的ProGuard版本有一些啓發式技術可以解決像這樣的簡單情況。 ProGuard的商業擴展DexGuard實現了一種更高級的技術,稱爲逃逸分析;它可以作爲結果移除調用。

(我是ProGuard和DexGuard的開發者)

+0

對上述情況有任何影響嗎?我的意思是,如果參數「name」在包括「Log ...」的行中沒有被修改,那麼即使您稍後使用該變量,刪除該行中的引用是否也會有所作爲?我想不是在這個簡單的情況下。 – mass