轻量级日志类Log

来源:互联网 发布:有哪些大数据查询的app 编辑:程序博客网 时间:2024/05/20 16:36
      Log在android应用开发中是使用频率非常高的一个类,在没有了解这个类之前都是使用System.out.println(),这个 是Java中的一个方法。Log类定义了六个静态变量:
public static final int VERBOSE = 2;    /**         * Priority constant for the println method; use Log.d.     */    public static final int DEBUG = 3;    /**     * Priority constant for the println method; use Log.i.     */    public static final int INFO = 4;    /**     * Priority constant for the println method; use Log.w.     */    public static final int WARN = 5;    /**     * Priority constant for the println method; use Log.e.     */    public static final int ERROR = 6;    /**     * Priority constant for the println method.     */    public static final int ASSERT = 7;
    Log.v()、Log.d()、 Log.i()、 Log.w()、  Log.e() 首字母分别对应分VERBOSE(详细的),DEBUG(调试),INFO(信息), WARN(警告),ERROR(错误)。从v到e,v总是会打印的,当发生错误时,e才会打印,v仍然会打印。ASSERT是为了让错误不要再报告而设置的,对应Log.wtf()方法。还有一个方法是isLoggable(),通过这个方法可用日志的级别做设置,默认是Log.i(),当长度大于23时会抛出异常。这些方法是native方法。在android源码的frameworks\base\core\jni下的android_util_Log.cpp文件中有相应的实现。代码如下:
static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,        jint bufID, jint priority, jstring tagObj, jstring msgObj){    const char* tag = NULL;    const char* msg = NULL;    if (msgObj == NULL) {        jniThrowNullPointerException(env, "println needs a message");        return -1;    }    if (bufID < 0 || bufID >= LOG_ID_MAX) {        jniThrowNullPointerException(env, "bad bufID");        return -1;    }    if (tagObj != NULL)        tag = env->GetStringUTFChars(tagObj, NULL);    msg = env->GetStringUTFChars(msgObj, NULL);    int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);    if (tag != NULL)        env->ReleaseStringUTFChars(tagObj, tag);    env->ReleaseStringUTFChars(msgObj, msg);    }
    __android_log_buf_write位于Android源代码的system\core\liblog中的logd_write.c文件中。
int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg){    struct iovec vec[3];    char tmp_tag[32];    if (!tag)        tag = "";    /* XXX: This needs to go! */    if ((bufID != LOG_ID_RADIO) &&         (!strcmp(tag, "HTC_RIL") ||        !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */        !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */        !strcmp(tag, "AT") ||        !strcmp(tag, "GSM") ||        !strcmp(tag, "STK") ||        !strcmp(tag, "CDMA") ||        !strcmp(tag, "PHONE") ||        !strcmp(tag, "SMS"))) {            bufID = LOG_ID_RADIO;            // Inform third party apps/ril/radio.. to use Rlog or RLOG            snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);            tag = tmp_tag;    }    vec[0].iov_base   = (unsigned char *) &prio;//优先级    vec[0].iov_len    = 1;    vec[1].iov_base   = (void *) tag;       //tag标志    vec[1].iov_len    = strlen(tag) + 1;    vec[2].iov_base   = (void *) msg;     //msg 日志内容    vec[2].iov_len    = strlen(msg) + 1;    return write_to_log(bufID, vec, 3);}
    从代码上看就是我们要调用的Log是带缓冲区的,接下来它自己又调用了不带缓冲区的。

static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;//初始化

__write_to_log_init接下来会调用内核提供的API

static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr){#ifdef HAVE_PTHREADS    pthread_mutex_lock(&log_init_lock);#endif    if (write_to_log == __write_to_log_init) {        log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);        log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);        log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);        log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);        write_to_log = __write_to_log_kernel;        if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0 ||                log_fds[LOG_ID_EVENTS] < 0) {            log_close(log_fds[LOG_ID_MAIN]);            log_close(log_fds[LOG_ID_RADIO]);            log_close(log_fds[LOG_ID_EVENTS]);            log_fds[LOG_ID_MAIN] = -1;            log_fds[LOG_ID_RADIO] = -1;            log_fds[LOG_ID_EVENTS] = -1;            write_to_log = __write_to_log_null;        }        if (log_fds[LOG_ID_SYSTEM] < 0) {            log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];        }    }#ifdef HAVE_PTHREADS    pthread_mutex_unlock(&log_init_lock);#endif    return write_to_log(log_id, vec, nr);}
这样就成了文件IO操作了,原来打个日志还这么麻烦。
0 0
原创粉丝点击