編輯:關於Android編程
我們在開發時,經常會輸出各種日志來debug代碼。但是等到應用發布的apk運行時不希望它輸出日志。
關閉輸出日志Log.v(),Log.i(),Log.w(),Log.v(),Log.e()等
那麼我們可以通過proguard來刪除各種日志輸出代碼。然後導出apk時,將會過濾掉日志代碼。
通過配置proguard,將類android.util.Log的方法給置為為無效代碼。(proguard是一個代碼優化的工具,也可以混淆代碼)
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 不要優化;將會會關閉優化,導致日志語句不會被優化掉。所以不能有這個配置
在project.properties文件最後行添加:proguard.config=proguard
如我的project.properties文件:
target=android-18
proguard.config=proguard-project.txt
如:我的配置文件是: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(...);
}
proguard,在導出apk的時候才會優化代碼,生成優化後的apk。(完成代碼混淆也是在導出apk,proguard將代碼混淆後生成apk)
通過如上兩個步驟,配置project.properties文件和proguard.properties文件;那麼項目就配置好了。可以直接導出簽名apk,該apk不會輸出日志,我們用LogCat是看不到該apk的日志。
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)
public class MainActivity extends Activity { protected void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); setContentView(2130903040); } }
很明顯Log.e("MainActivity","log" );被優化掉了
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)
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()方法依然被保留了,
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)
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()方法依然被保留了,
轉載請注明出處,jiese1990。
一、Intent的用途Intent主要有以下幾種重要用途: 1. 啟動Activity:可以將Intent對象傳遞給startActivity()方法或startActi
本文實例講述了Android EditText自定義樣式的方法。分享給大家供大家參考,具體如下:1.去掉邊框EditText的background屬性設置為@null就搞
知識點目錄 10.1 布局優化 10.1.1 Android UI渲染機制 10.1.2 避免Overdraw 10.1.3 優化布局層級 10.1.4 避免嵌套過多無用
曾經有一個朋友問過我一個問題, 一張512*512 150KB PNG格式圖片和一張512*512 100KB 壓縮比是8的JPG格式的圖片,加載到內存中,也