本番Androidアプリケーションからロギングを削除するための最良の方法は何ですか。proguardはこれを完全には行わないようですが、文字列はまだ書き込まれているので、本番コードからロギングを削除するための最良の解決策は何でしょうか。
8 に答える
IMOの最善の解決策は、ロギングメソッドを呼び出す場所に以下のようなコードを記述することです。
if (SOME_LOG_CONSTANT) Log.d(TAG, "event:" + someSlowToEvaluateMethod());
1つの定数を変更することにより、不要なすべてのログを削除します。そうすれば、コンパイラが.classファイルを完全に削除できるため、背後の部分if (false)
が.classファイルに侵入することはありません(到達不能コードです)。
これは、コードブロックをラップする場合、リリースソフトウェアからコードブロック全体を除外できることも意味しますif
。それはプロガードでさえできないことです。
SDKToolsr17以降を使用している場合に可能SOME_LOG_CONSTANT
です。BuildConfig.DEBUG
その定数は、ビルドタイプに応じて自動的に変更されます。Thx @Christopher
Timberを使用してください。ログを構成するための優れたライブラリです: https ://github.com/JakeWharton/timber
使用例:Timber.d( "Activity Created");
構成例:
public class ExampleApp extends Application {
@Override public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new DebugTree());
} else {
Timber.plant(new CrashReportingTree());
}
}
/** A tree which logs important information for crash reporting. */
private static class CrashReportingTree extends Timber.Tree {
@Override protected void log(int priority, String tag, String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
FakeCrashLibrary.log(priority, tag, message);
if (t != null) {
if (priority == Log.ERROR) {
FakeCrashLibrary.logError(t);
} else if (priority == Log.WARN) {
FakeCrashLibrary.logWarning(t);
}
}
}
}
アプリケーションをリリース用に構成すると、アプリケーションをリリースLog
する前にコマンドを削除するように指示されます。
ソースファイルのLogメソッドへの呼び出しを削除することで、ロギングを非アクティブ化できます。
私がしていることは、次のようなグローバルブール値を読み取る独自の静的ログメソッドを作成することです。
class MyLog {
private static final boolean LOGGING = true; //false to disable logging
public static void d(String tag, String message) {
if (LOGGING) {
Log.d(tag, message);
}
}
/* ... same for v, e, w, i */
}
ログに記録するすべての場所でこれを使用します。
MyLog.d("Tag", "This will only work with LOGGING true");
このログ拡張クラスを確認することをお勧めします。
これにより、ログを細かく制御できます。たとえば、すべてのログ(構成ファイルのおかげで)を無効にすることも、一部のパッケージまたはクラスのログのみを無効にすることもできます。
さらに、いくつかの便利な機能が追加されます(たとえば、ログごとにタグを渡す必要はありません)。
このメソッドをコードに追加し、Log.dの代わりにLogdを使用するだけです。
private static final String TAG = "your own tag to recognize log entries from this app";
public static void Logd(String txt) {
if (BuildConfig.DEBUG&&BuildConfig.BUILD_TYPE.equals("debug")) Log.d(TAG,txt);
}
文字列が引き続き評価されることはわかっていますが、余分な処理時間でマイクロ秒を話します。ループで何千ものロギングを行っていない限り、アプリの速度の違いに気付くことはありません。
DEBUGとBUILD_TYPEは、AndroidStudioで使用できます。DEBUGブール値は、build.gradleファイルの「デバッグ可能」オプションです。
buildTypes {
debug {
debuggable true
runProguard false
proguardFile getDefaultProguardFile('proguard-android.txt')
}
release {
debuggable false
runProguard true
proguardFile getDefaultProguardFile('proguard-android.txt')
}
}
Android Studioで実行すると、BUILD_TYPEは自動的に「デバッグ」に設定されます。
したがって、debuggableをfalseに設定した場合、またはユーザーがリリースバージョンを使用している場合、ログは失われます。
Roboguice(http://code.google.com/p/roboguice/ )を確認することをお勧めします。組み込みのLn関数を使用すると、署名されたAPKに自動的にログオンしません。それは他のAndroidボイラープレートのトンも単純化します。Basedroidで実際に動作していることを確認できます-https ://github.com/achuinard/basedroid
DebugLogクラスを使用できます。アプリがリリースされると、DebugLogによってすべてのログが無効になります。また、開発者にとってより理解しやすいDDMSログを提供します。
元;
DebugLog.e("your message");
最善の方法は、私の経験からこれを処理することです。
まず、ログを記録しているときに、BuildConfig.DEBUGフラグをチェックしてログを出力します。
Class LogUtils{ public static void log(Class clazz, String message) { if (BuildConfig.DEBUG) {//log only in debug mode Log.d(clazz.getSimpleName(), message); } } }
次に、アプリモジュールのgradleファイルへのミニファイを有効にします。これにより、proguardがバイナリを最適化できるようになります
android { buildTypes { release { minifyEnabled true //shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } } }
これにより、デバッグビルドにデバッグログが保持されます。ただし、リリースビルドでは、if (BuildConfig.DEBUG)
条件が真になることはないため、proguardは到達不能なログコードをバイナリから削除します。