3

非常に単純な Android アクティビティを作成しました。

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d("TAG", "onCreate() Log call 1");
        Log.d("SMS", "onCreate() Log call 2");
        Log.d("TEST", "onCreate() Log call 3");

        finish();
    }

    @Override
    protected void onDestroy() {
        Log.d("TAG", "onDestroy() Log call 1");
        Log.d("SMS", "onDestroy() Log call 2");
        Log.d("TEST", "onDestroy() Log call 3");

        super.onDestroy();
    }
}

onCreate()これにより、6 つのログ メッセージ ( から 3 つ、 から3 つ)が生成されると予想されますonDestroy()。ログキャットは次のとおりです。

04-14 17:31:58.363: D/TAG(18084): onCreate() Log call 1
04-14 17:31:58.363: D/TEST(18084): onCreate() Log call 3
04-14 17:31:59.905: D/TAG(18084): onDestroy() Log call 1
04-14 17:31:59.905: D/TEST(18084): onDestroy() Log call 3

ご覧のとおり、「SMS」というタグの付いた回線は通過しません。文書化されたものを伝えることができる限り、これはそうではありません。問題は、なぜですか?

編集:答えの詳細。

以下のマシュー・バークによるかなり良い答えがあります。要するに、 のソース コードに基づいて、次のlogd_write.cように思われます。

  • Logradio次のタグを持つリクエストは、自動的にログ にリダイレクトされます。
    • HTC_RIL
    • で始まるタグRIL
    • AT
    • GSM
    • STK
    • CDMA
    • PHONE
    • SMS
  • ログ (またはログ、 http://elinux.org/Android_Logging_Systemも参照)Logにリダイレクトされるリクエストはありません。eventssystem
  • 他のすべてのLog要求mainは、通常監視されるログに送られます。
4

2 に答える 2

4

logcatソースを調べ始める前に、ドキュメントを読むべきでした。logcatのドキュメントによると:

Android ロギング システムは、ログ メッセージ用に複数の循環バッファを保持しており、すべてのログ メッセージがデフォルトの循環バッファに送信されるわけではありません。

のタグが付いたメッセージSMSは、メイン バッファではなく、無線バッファに送信されます。したがって、わざわざ行かない限り、それらを見ることはできません。コマンドを実行すると:

adb logcat -b radio

欠落しているログ メッセージが表示されるはずです。上記の情報はhttps://developer.android.com/tools/debugging/debugging-log.htmlにあります。


さて、コードスペランキングに興味のある方のために、以下は私の最初の答えです:

クラス内のメソッドLogはすべてprintln_native、JNI メソッドであるラッパーです。
println_nativeパラメータの検証を実行してから、 を呼び出します__android_log_buf_write

この後者のメソッドは、タグ パラメータ (元のLog.d呼び出しから) をいくつかのハードコードされた文字列 (タグSMSはこのリストの 1 つ) と比較し、一致が見つかった場合は、ログ メッセージを別のファイルに書き込みます。

ちなみに、再ルーティングされる他のタグは、GSM、STK、PHONE、CDMA、およびその他のいくつかです。

関連するソースを読むことができます

これらは公式のリンクではなく、ある時点で消える可能性があります。公式リンクを追跡して、今晩遅くに編集します。

于 2013-04-17T20:27:36.680 に答える
0

EDITこれを無視してください、私はどうやらこれによるとかなりベースから外れてます。

だから私はこれが面白いと思い、ソースを掘り下げた後、次のことを知りましたLog.isLoggable()

指定されたタグのログが指定されたレベルでログ可能かどうかを確認します。タグのデフォルト レベルは INFO に設定されています。これは、INFO を含むすべてのレベルがログに記録されることを意味します。ロギング メソッドを呼び出す前に、タグをログに記録する必要があるかどうかを確認する必要があります。システム プロパティを設定することで、デフォルト レベルを変更できます。' level は、VERBOSE、DEBUG、INFO、WARN、ERROR、ASSERT、または SUPPRESS のいずれかです。SUPPRESS は、タグのすべてのロギングをオフにします。また、「log.tag.=」を含む local.prop ファイルを作成し、それを /data/local.prop に配置することもできます。

パラメータ
tag チェックするタグ。
level チェックするレベル。

戻り値
これがログに記録されるかどうか。

一部のタグは特定のログ レベルでは許可されていないようで、 で定義されているよう/data/local.propですが、まだ見つかっていないシステム レベルのプロパティ ファイルがいくつかあるはずです。ただし、次のようなものを使用してそれを確認できます。

boolean isLoggableV = Log.isLoggable("SMS", Log.VERBOSE);
boolean isLoggableD = Log.isLoggable("SMS", Log.DEBUG);
boolean isLoggableI = Log.isLoggable("SMS", Log.INFO);
boolean isLoggableW = Log.isLoggable("SMS", Log.WARN);
boolean isLoggableE = Log.isLoggable("SMS", Log.ERROR);
boolean isLoggableA = Log.isLoggable("SMS", Log.ASSERT);

Log.v("LogTest", String.format("Verbose: %b Debug: %b Info: %b Warn: %b Error: %b Assert: %b", isLoggableV, isLoggableD, isLoggableI, isLoggableW, isLoggableE, isLoggableA));

私にとっては、次のものが返されました:

Verbose: false Debug: false Info: true Warn: true Error: true Assert: true

SMSそのため、以上のログ レベルでタグをログに記録できますが、またはINFOではできません。VERBOSEDEBUG

これは、アプリケーションが誤って個人情報をログに記録するのを防ぐためだと思われますが、かなり大雑把な方法のように思えます。

于 2013-04-17T19:16:50.757 に答える