android 代碼優化:關閉輸出日志

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.prZ喎?/kf/ware/vc/” target=”_blank” class=”keylink”>vcGVydGllc87EvP6hozwvaDM+CjxwPjxpbWcgc3JjPQ==”” alt=”\”>

在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)

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);
  }
}

運行LogCat中沒有輸出日志。

很明顯Log.e(“MainActivity”,”log” );被優化掉瞭

源碼2)

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()方法依然被保留瞭,

源碼3):

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。

發佈留言