Android SQLite调试

调试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.cppandroid_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] = '\0';
    }

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

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

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

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

posted @ 2014-07-24 21:26  AngelDevil  阅读(4000)  评论(0编辑  收藏  举报