β

Android SQLite调试

AngelDevil 87 阅读

调试SQLite的神器,再也不用自己去打Log了,只需简单的几个命令。

adb shell setprop log.tag.SQLiteLog V
adb shell setprop log.tag.SQLiteStatements V
adb shell stop
adb shell start

结果如下所示

V/SQLiteStatements( 4405): /data/data/[package]/databases/[db_name].db: "UPDATE [table_name] SET state=-1 WHERE note_id='7556'"

想关闭Log也很简单,把上面代码中的 V 改为 "" 就行了

说明在源码 SQLiteDebug.java

/**
    * Controls the printing of informational SQL log messages.
    *
    * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE".
    */
   public static final boolean DEBUG_SQL_LOG =
           Log.isLoggable("SQLiteLog", Log.VERBOSE);

   /**
    * Controls the printing of SQL statements as they are executed.
    *
    * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE".
    */
   public static final boolean DEBUG_SQL_STATEMENTS =
           Log.isLoggable("SQLiteStatements", Log.VERBOSE);

   /**
    * Controls the printing of wall-clock time taken to execute SQL statements
    * as they are executed.
    *
    * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE".
    */
   public static final boolean DEBUG_SQL_TIME =
           Log.isLoggable("SQLiteTime", Log.VERBOSE);

源码中说要用 VERBOSE ,而我们使用 V 确也能起作用,看下 isLoggable 的实现就知道了, isLoggable 是native方法,实际执行的是 frameworks/base/core/jni/android_util_Log.cpp android_util_Log_isLoggable 方法, android_util_Log_isLoggable 调用同一文件内的 isLoggable

static jboolean isLoggable(const char* tag, jint level) {
    String8 key;
    key.append(LOG_NAMESPACE);
    key.append(tag);

    char buf[PROPERTY_VALUE_MAX];
    if (property_get(key.string(), buf, "") <= 0) {
        buf[0] = &apos;\0&apos;;
    }

    int logLevel = toLevel(buf);
    return logLevel >= 0 && level >= logLevel;
}

isLoggable 中通过 property_get 获取我们之前设定的值,然后对获取到的结果调用 toLevel

static int toLevel(const char* value)
{
    switch (value[0]) {
        case &apos;V&apos;: return levels.verbose;
        case &apos;D&apos;: return levels.debug;
        case &apos;I&apos;: return levels.info;
        case &apos;W&apos;: return levels.warn;
        case &apos;E&apos;: return levels.error;
        case &apos;A&apos;: return levels.assert;
        case &apos;S&apos;: return -1; // SUPPRESS
    }
    return levels.info;
}

toLevel 只判断了值的第一个字符,所以我们之前只设置 V 也可以,其实只要是 V 开头的,后接任何字符都无所谓。

调试SQLite的神器,再也不用自己去打Log了,只需简单的几个命令。

作者:AngelDevil
Focus on Android
原文地址:Android SQLite调试, 感谢原作者分享。