標籤:
android關閉日誌
我們在開發時,經常會輸出各種日誌來debug代碼。但是等到應用發布的apk運行時不希望它輸出日誌。
關閉輸出日誌Log.v(),Log.i(),Log.w(),Log.v(),Log.e()等
原理:
那麼我們可以通過proguard來刪除各種日誌輸出代碼。然後匯出apk時,將會過濾掉日誌代碼。
通過配置proguard,將類android.util.Log的方法給置為為無效代碼。(proguard是一個代碼最佳化的工具,也可以混淆代碼)
assumenosideeffects
assumenosideeffects,assume no side effects;假定無效;該屬性也就是標識無效代碼。我們就是通過這個參數來讓proguard刪除日誌代碼。
assumenosideeffects的官方解釋:
In the optimization step, ProGuard will then remove calls to such methods, if it can determine that the return values aren‘t used.ProGuard will analyze your program code to find such methods automatically.It will not analyze library code, for which this option can therefore be useful.
In general, making assumptions can be dangerous; you can easily break the processed code. Only use this option if you know what you‘re doing!
如下:
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
使用這個配置時,一定要注意-dontoptimize,配置。
don‘t optimize 不要最佳化;將會會關閉最佳化,導致日誌語句不會被最佳化掉。所以不能有這個配置
如何關閉日誌:
我的項目目錄:
1)開啟proguard-------修改project.properties檔案。
在project.properties檔案最後行添加:proguard.config=proguard
如我的project.properties檔案:
target=android-18
proguard.config=proguard-project.txt
2)配置proguard-------修改proguard設定檔,
如:我的設定檔是:proguard-project.txt
配置為:
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-dontwarn android.support.**
-keepclassmembers class **.R$* {
public static ;
}
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String,int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
3)匯出關閉日誌的apk
proguard,在匯出apk的時候才會最佳化代碼,產生最佳化後的apk。(完成代碼混淆也是在匯出apk,proguard將代碼混淆後產生apk)
通過如上兩個步驟,配置project.properties檔案和proguard.properties檔案;那麼項目就配置好了。可以直接匯出簽名apk,該apk不會輸出日誌,我們用LogCat是看不到該apk的日誌。
測試源碼1)
?
| 12345678 |
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("MainActivity", "log" ); }} |
通過產生的apk反編譯出如下代碼1-1)
?
| 12345678 |
public class MainActivity extends Activity{ protected void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); setContentView(2130903040); }} |
運行LogCat中沒有輸出日誌。
很明顯Log.e("MainActivity","log" );被最佳化掉了
源碼2)
?
| 12345678910111213 |
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("MainActivity", "log " + test()); } private String test(){ Toast.makeText(this, "test", Toast.LENGTH_SHORT).show(); return "jjyy"; }} |
通過產生的apk反編譯出如下代碼2-1)
?
| 123456789101112 |
public class MainActivity extends Activity{ protected void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); setContentView(2130903040); //如下是test()函數的代碼 StringBuilder localStringBuilder = new StringBuilder("log "); Toast.makeText(this, "test", 0).show(); localStringBuilder.append("jjyy").toString(); }} |
運行LogCat中沒有輸出日誌。但是彈出toast。
很明顯Log.e();被最佳化掉了,但是test()方法依然被保留了,
源碼3):
?
| 123456789101112131415 |
public class MainActivity extends Activity { int i = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("MainActivity", "log" + test() ); Toast.makeText(this, "i = " + i, Toast.LENGTH_SHORT).show(); //i == 1; } private String test(){ i++; return "test" + i; }} |
通過產生的apk反編譯出如下代碼3-1)
?
| 123456789101112131415 |
public class MainActivity extends Activity{ private int a = 0; //proguard將代碼混淆後變數i變為了a protected void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); setContentView(2130903040); //Log.e()代碼被刪除了,但是調用test()函數裡的i++被直接最佳化到這裡 StringBuilder localStringBuilder = new StringBuilder("log"); this.a = (1 + this.a); localStringBuilder.append("test" + this.a).toString(); Toast.makeText(this, "i = " + this.a, 0).show(); }} |
運行LogCat中沒有輸出日誌。但是彈出toast 顯示字串 : "i = 1"
很明顯Log.e();被最佳化掉了,但是test()方法依然被保留了,
來自:http://www.2cto.com/kf/201403/287453.html
android 代碼最佳化:關閉輸出日誌