Android Log原理分析

在android开发的过程中,需要查看log信息来帮助分析。那么知晓log的原理就是比较重要的了。

Framework 中的Log

Framework中的Log比较简单,主要就是封装接口,在接口中调用println_native函数。下面只以其中的一个进行分析。

public static int v(String tag, String msg) {
   
   if (tag == null) {
   
		tag = "NullTag";
	 }
	 if (msg == null) {
   
		msg = "NullMsg";
	 }
	return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
}

默认情况下,log id为main,这个ID的作用后面会提到。这个函数会检查tag & msg。之后就是调用println_native。

JNI中的Log

在JNI中的对应文件为:android_util_Log.cpp

 static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,
         jint bufID, jint priority, jstring tagObj, jstring msgObj)
 {
   
	int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
 }

在这里需要说明一下BufID & priority

  typedef enum android_LogPriority {
   
      ANDROID_LOG_UNKNOWN = 0,
      ANDROID_LOG_DEFAULT,    // only for SetMinPriority()
      ANDROID_LOG_VERBOSE,
      ANDROID_LOG_DEBUG,
      ANDROID_LOG_INFO,
      ANDROID_LOG_WARN,
      ANDROID_LOG_ERROR,
      ANDROID_LOG_FATAL,
      ANDROID_LOG_SILENT,     // only for SetMinPriority(); must be last
 } android_LogPriority;
 
typedef enum {
   
     LOG_ID_MAIN = 0,
     LOG_ID_RADIO = 1,
     LOG_ID_EVENTS = 2,
     LOG_ID_SYSTEM = 3, 
     LOG_ID_MAX
} log_id_t;

上面对应的输入那种等级的打印信息。下面的对应打印哪种log。用过 logcat -b system/main/events/main来进行log输出。

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 = "";
	//特殊处理radio的log
    /* 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;
    vec[1].iov_len    = strlen(tag) + 1;
    vec[2].iov_base   = (void *) msg;
    vec[2].iov_len    = strlen(msg) + 1;

    return write_to_log(bufID, vec, 3);
}

这部分是使用linux中的iov的数据格式进行传递的。最后调用write_to_log函数,是一个函数指针。下面看一下这个函数的定义

static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
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<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值