ほとんどの人がAndroid.util.Logを認識していると思います。すべてのロギングメソッドは、最初の引数として「Stringタグ」を受け入れます。
そして私の質問はアプリケーションでログをどのようにタグ付けするのですか?私はこのようなハードコードを見ました:
public class MyActivity extends Activity {
private static final String TAG = "MyActivity";
//...
public void method () {
//...
Log.d(TAG, "Some logging");
}
}
これは多くの理由で見栄えがよくありません:
クラスのTAGを取得する適切な方法はありますか?
TAGを使用しますが、次のように初期化します。
private static final String TAG = MyActivity.class.getName();
この方法でコードをリファクタリングすると、タグもそれに応じて変更されます。
通常、別のパッケージに配置され、有用な静的メソッドを含むApp
クラスを作成します。メソッドの1つはgetTag()
メソッドです。これにより、どこでもTAGを取得できます。App
クラスは次のようになります。
[〜#〜] edit [〜#〜]:br mobコメントごとに改善(ありがとう:))
public class App {
public static String getTag() {
String tag = "";
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
for (int i = 0; i < ste.length; i++) {
if (ste[i].getMethodName().equals("getTag")) {
tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
}
}
return tag;
}
}
そして、私がそれを使いたいとき:
Log.i(App.getTag(), "Your message here");
getTag
メソッドの出力は、簡単にデバッグできるように、呼び出し元クラスの名前(パッケージ名付き)、およびgetTag
の呼び出し元の行番号です。
Android Studio->設定->ライブテンプレート-> AndroidLogに移動し、Log.d(TAG、String )。
InTemplate textreplace
Android.util.Log.d(TAG, "$METHOD_NAME$: $content$");
と
Android.util.Log.d("$className$", "$METHOD_NAME$: $content$");
次に、変数の編集をクリックし、次にExpression列にclassName()を入力しますclassNameName列に追加します。
ショートカットlogd
を入力すると、
Log.d("CurrentClassName", "currentMethodName: ");
もうTAGを定義する必要はありません。
ログがこの形式(filename.Java:XX)xx行番号である場合、エラーが発生したときに同じ方法でショートカットをリンクできるYanivの回答を改善するのが好きですlogcatをクリックするだけで
これを拡張アプリケーションに入れて、他のすべてのファイルで使用できるようにします
public static String getTag() {
String tag = "";
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
for (int i = 0; i < ste.length; i++) {
if (ste[i].getMethodName().equals("getTag")) {
tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
}
}
return tag;
}
スクリーンショット:
S
という名前の静的変数、メソッド、クラスのクラスを作成しました。
ロギング方法は次のとおりです。
public static void L(Context ctx, Object s) {
Log.d("CCC " + ctx.getClass().getName().replace(ctx.getPackageName(), ""), s.toString());
}
任意のクラスでS.L(this, whaterver_object);
として呼び出されます。getClass().getName()
はパッケージ名も追加するため、タグを不必要に長くしないように削除しています。
利点:
Log.d(TAG,
より短いtoString
と入力する必要はありませんLog.d
を削除することを忘れないでください。メソッドを削除するだけで、すべてのログの場所が赤でマークされます。CCC
(短い、入力しやすい文字列)というプレフィックスが付いているため、Android monitor in Android Studio。サービスまたは他のクラスを同時に実行している場合があります。アクティビティ名だけで検索する必要がある場合、サービス応答が取得され、アクティビティからのアクションがいつ発生したかを正確に確認できません。発生したアクティビティを時系列に記録するので役立ちますメソッド間でコードを移動したり、メソッドの名前を変更したりするときに、これらの文字列を更新することを犠牲にして、次のことをするのが好きです。哲学的には、メッセージではなくタグに「場所」または「コンテキスト」を保持する方が良いようです。
_public class MyClass {
// note this is ALWAYS private...subclasses should define their own
private static final LOG_TAG = MyClass.class.getName();
public void f() {
Log.i(LOG_TAG + ".f", "Merry Christmas!");
}
}
_
ここでの利点は、コンテンツが静的ではない場合でも、単一のメソッドを除外できることです。
_Log.i(LOG_TAG + ".f", String.valueOf(new Random().nextInt()));
_
唯一の欠点は、f()
の名前をg()
に変更するとき、その文字列を覚えておく必要があることです。また、自動IDEリファクタリングはこれらをキャッチしません。
しばらくの間、短いクラス名を使用するのが好きでした。つまり、LOG_TAG = MyClass.class.getSimpleName()
を意味します。続行するログが少ないため、ログでフィルタリングするのが難しいことがわかりました。
AndroidStudioには、デフォルトでlogt
テンプレートがあります(logt
と入力してTabキーを押すと、コードのコードに展開できます)。これを使用して、別のクラスからTAG定義をコピーペーストし、参照しているクラスの変更を忘れないようにすることをお勧めします。テンプレートはデフォルトで展開されます
_private static final String TAG = "$CLASS_NAME$"
_
リファクタリング後に古いクラス名を使用しないようにするには、それを次のように変更できます。
private static final String TAG = $CLASS_NAME$.class.getSimpleName();
[変数の編集]ボタンを確認し、className()
式を使用するように_CLASS_NAME
_変数が定義され、[定義時にスキップ]がオンになっていることを確認してください。
これは非常に古い質問ですが、2018年7月の更新された回答でさえ、Timberを使用する方が望ましいと考えられています。正しいログを記録するために、FirebaseやCrashlyticsなどのサードパーティのクラッシュライブラリにエラーと警告を送信できます。
Applicationを実装するクラスでは、これを追加する必要があります。
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.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);
}
}
}
}
Timberの依存関係を忘れないでください。
implementation 'com.jakewharton.timber:timber:4.7.1'
this.toString()
を使用して、ログに出力する特定のクラスの一意の識別子を取得できます。
iOschedアプリ2019にTimberを使用してデバッグ情報を表示します。
implementation 'com.jakewharton.timber:timber:4.7.1'
class ApplicationController: Application() {
override fun onCreate() {
super.onCreate()
if(BuildConfig.DEBUG){
Timber.plant(Timber.DebugTree())
}
}
// enables logs for every activity and service of the application
// needs to be registered in manifest like:
<application
Android:label="@string/app_name"
Android:name=".ApplicationController"
... >
使用法
Timber.e("Error Message")
// will print -> D/MainActivity: Error Message
Timber.d("Debug Message");
Timber.tag("new tag").e("error message");
これにより、ログはDEBUG状態でのみ使用可能になり、Google Playでの起動のためにログを手動で削除するタスクが容易になります-
playストアでアプリをリリースすると、アプリからすべてのLogステートメントを削除する必要があります。これにより、ユーザー情報、非表示のアプリケーションデータ、認証トークンなどのアプリケーションデータがプレーンテキストとしてlogcatでユーザーに利用できなくなります。
この記事をご覧ください https://medium.com/mindorks/better-logging-in-Android-using-timber-72e40cc2293d
この質問にアクセスするユーザーの場合:
private val TAG:String = this.javaClass.simpleName;