activitylog怎么写( 二 )


另外一种误用log中时间戳的情况是用它来分析程序的性能 。一个有多年工作经验的工程师拿着他的性能分析结果给笔者看,但是笔者对这份和实际情况相差很远的报告表示怀疑,于是询问这位工程师是如何得出结论的 。
他的回答让笔者很惊讶,他计算所采用的数据就是log信息前面的时间戳 。前面我们已经讲过,log前面时间戳和调用log函数的时间并不相同,这是由于系统缓冲log信息引起的,而且这两个时间的时间差并不固定 。
所以用log信息前附带的时间戳来计算两段log间代码的性能会有比较大的误差 。正确的方法还是上面提到的:在程序中获取系统时间然后打印输出,利用我们打印的时间来计算所花费的时间 。
了解了时间,我们再谈谈进程Id和线程Id,它们也是分析log时很重要的依据 。我们看到的log文件,不同进程的log信息实际上是混杂在一起输出的,这给我们分析log带来了很大的麻烦 。
有时即使是一个函数内的两条相邻的log,也会出现不同进程的log交替输出的情况,也就是A进程的第一条log后面跟着的是B进程的第二条log,对于这样的组合如果不细心分析,就很容易得出错误的结论 。这时一定要仔细看log前面的进程Id,把相同Id的log放到一起看 。
不同进程的log有这样的问题,不同的线程输出的log当然也存在着相同的问题 。Logcat加上-vthread就能打印出线程Id 。
但是有一点也要引起注意,就是Android的线程Id和我们平时所讲的Linux线程Id并不完全等同 。首先,在Android系统中,C++层使用的Linux获取线程Id的函数gettid()是不能得到线程Id的,调用gettid()实际上返回的是进程Id 。
作为替代,我们可以调用pthread_self()得到一个唯一的值来标示当前的native线程 。Android也提供了一个函数androidGetThreaId()来获取线程Id,这个函数实际上就是在调用pthread_self函数 。
但是在Java层线程Id又是另外一个值,Java层的线程Id是通过调用Thread的getId方法得到的,这个方法的返回值实际上来自Android在每个进程的java层中维护的一个全局变量,所以这个值和C++层所获得的值并不相同 。这也是我们分析log时要注意的问题,如果是Java层线程Id,一般值会比较小,几百左右;如果是C++层的线程,值会比较大 。
在前里面的log样本中,就能很容易的看出,第一条log是Jave层输出的log,第二条是native层输出的 。明白了这些,我们在分析log时就不要看见两段log前面的线程Id不相同就得出是两个不同线程log的简单结论,还要注意Jave层和native层的区别,这样才能防止被误导 。
AndroidLog的优先级在打印输出时会被转换成V,I,D,W,E等简单的字符标记 。在做系统log分析时,我们很难把一个log文件从头看到尾,都是利用搜索工具来查找出错的标记 。
比如搜索“E/”来看看有没有指示错误的log 。所以如果参与系统开发的每个工程师都能遵守Android定义的优先级含义来输出log,这会让我们繁重的log分析工作变得相对轻松些 。
Android比较常见的严重问题 。
【activitylog怎么写】

activitylog怎么写

文章插图