‘壹’ 在android开发中,Logcat是什么
最后介绍一下Android的Log工具LogCat。
首先在Eclipse中选择Windows > Show View > Other... > Android > LogCat,确定后会出现LogCat显示框,用户添加的Log将会在这里显示。使用时直接在代码中插入“Log.i("info","this is a log");”,那么在执行到该语句时,LogCat显示框中将出现“this is a log”。
在Eclipse中安装ADT和android sdk包之后,运行以开发的android程序时,在LogCat窗口中会显示出一系列的信息,这些信息是每一个程序通过Dalvik虚拟机所传出的实时信息,可以方便我们对程序的了解。
在log窗口中,每条信息都包含五个部分,Time,标题空白,pid,tag和Message。
1、Time
表示执行的时间,这个信息对于学习生命周期,分析程序运行的先后顺序特别有用。
2、标题空白的列
表示的是信息的种类,分为V,D,I,W,E五种。
V:verbose,显示全部信息
D:Debug,显示调试信息
I:Info,显示一般信息
W:Warming,显示警告信息
E:Error,显示错误信息
可以通过点击LogCat上面的用圆圈括起来的V,D,I,W,E来改变显示的范围。比如选择了W,那就只有警告信息和错误信息可以显示出来了。
3、pid
表示程序运行时的进程号
4、tag
标签,通常表示系统中的一些进程名,比如我们运行helloworld程序的话,就会看到activitymanager在运行。
5、Message
表示进程运行时的一些具体信息,比如我们运行helloworld程序的话,就会看到starting activity...helloWorld的字样
可以输出LogCat的信息到文本文件中,以方便分析。在下拉框中选择输出选择的信息就可以了。
下面是输出到文件中的启动helloWorld程序时的一条信息的例子,分别用5个下划线标出了上面介绍的内容:
05-20 15:46:10.129: INFO/ActivityManager(60): Starting activity: Intent { act=android.intent.action.MAIN cat=
[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.android.helloworld/.HelloWorld }
6、Filter的使用
可以在Filter中输入筛选信息,使LogCat中只现实我们需要分析的信息。比如我们只想看和HelloWorld相关的信息,就可以在
Filter中输入HelloWorld,这样只有Message 中包含HelloWorld的内容才会显示出来。
7、LogCat中信息不能显示
上面说了这么多关于logCat的使用,可能LogCat中根本就什么信息都没有显示!没关系,只要在Eclipse中选择window-
>show view->other->android->devices就可以 了。
8、在LogCat中输出程序的运行信息
a、在程序中导入相应的包:import android.util.Log;
b、在需要输出信息的函数中增加相关的调试代码:Log.i("hi world","oncreate");
方法i是Log类的静态方法,可以直接使用,我们看着各类的定义可以看到,它提供了多种输出方法,分别对应我们上面提到的V,D,I,W,E。用哪个方法就决定了输出的类型,这里用i,表示输出的是information。
这个方法中的第一个参数就是要显示在Tag那一栏的内容,把这条语句加到OnCreate方法中,执行时LogCat中就会显示如下的信息: 05-22 21:58:22.894 I 3910 hi world onCreate
9、创建新的Filter
有时候只想看我们程序中用Log类的相关方法输出的各种信息,这时就可以考虑新建一个过滤器。点击LogCat的右上角的“+”号,可以创建一个新的过滤器。比如我们在by Log Tag的选项中填入上面程序输出的"hi world"这个tag。这样再运行时在我们新创建的Filter中就只显示hi world这个tag标记出来的信息了。
Android开发中的logcat工具使用详解--------
logcat是Android中一个命令行工具,可以用于得到程序的log信息。
logcat使用方法如下所示:
logcat [options] [filterspecs]
logcat的选项包括:
-s 设置过滤器,例如指定 '*:s'
-f <filename> 输出到文件,默认情况是标准输出。
-r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f
-n <count> Sets max number of rotated logs to <count>, default 4
-v <format> 设置log的打印格式, <format> 是下面的一种:
brief process tag thread raw time threadtime long
-c 清除所有log并退出
-d 得到所有log并退出 (不阻塞)
-g 得到环形缓冲区的大小并退出
-b <buffer> 请求不同的环形缓冲区 ('main' (默认), 'radio', 'events')
-B 输出log到二进制中。
过滤器的格式是一个这样的串:
<tag>[:priority]
其中 <tag> 表示log的component, tag (或者使用 * 表示所有) , priority 如下所示:
V Verbose
D Debug
I Info
W Warn
E Error
F Fatal
S Silent
事实上logcat的功能 是由Android的类android.util.Log决定的,在程序中log的使用方法如下所示:
Log.v() -------------------- VERBOSE
Log.d() -------------------- DEBUG
Log.i() -------------------- INFO
Log.w() -------------------- WARN
Log.e() -------------------- ERROR
以上log的级别依次升高,DEBUG信息应当只存在于开发中,INFO, WARN,ERROR这三种log将出现在发布版本中。
对于java类,可以声明一个字符串常量TAG,Logcat可以根据他来区分不同的log,例如在计算器(Calculator)的类中,定义如下所示:
public class Calculator extends Activity {
/* ...... */
private static final String LOG_TAG = "Calculator";
private static final boolean DEBUG = false;
private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
/* ...... */
由此,所有在Calculator中使用的log,均以"Calculator"为开头。
例如使用方法如下所示:
# logcat &
< 得到一个log片段 >
W/KeyCharacterMap( 130): No keyboard for id 0
W/KeyCharacterMap( 130): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
I/ActivityManager( 52): Displayed activity com.android.contacts/.: 983 ms
I/ARMAsse mbler( 52): generated scanline__00000077:03545404_00000A04_00000000 [ 29 ipp] (51 ins) at [0x25c978:0x25ca44] in 1764174 ns
I/ARMAssembler( 52): generated scanline__00000077:03515104_00000001_00000000 [ 46 ipp] (65 ins) at [0x25d1c8:0x25d2cc] in 776789 ns
D / dalvikvm ( 130 ): GC freed 834 objects / 81760 bytes in 63ms
D/dalvikvm( 52): GC freed 10588 objects / 425776 bytes in 94ms
其中W/I/D 表示log的级别,“dalvikvm ”“ARMAssembler ”等是不同组件(component)的名称,后面括号里面的数字 表示了发出log的进程号。
使用技巧:
1.使用logcat &在后台运行
2.使用-d得到所有log
3.使用-f或者重定向(>和>>)输出到文件
4.使用-s设置过滤器,得到想要的log。
当然,最重要的还是在程序中加入恰当的log.
许多初次接触Android开发的朋友会遇到调试的问题,如何能够根据错误提示迅速的找到“出事地点呢”?在Eclipse+ADT的开发环境中没有好的直接跟踪对象内容的方法,通过使用android.util.Log类可以帮助你自己查找错误和打印系统日志消息。它是一个进行日志输出的API,我们在Android 程序中可以随时为某一个对象插入一个Log,然后在DDMS中观察Logcat的输出是否正常。
android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。根据首字母对应VERBOSE,DEBUG,INFO, WARN,ERROR。当我们在DDMS进行调试时他们的区别并不大,只是显示的颜色不同,但通过Logcat的过滤器我们可以过滤显示某类的,一般对于执行错误的断点,下在Log.e比较合适。但是Android开发网根据规范建议VERBOSE,DEBUG信息应当只存在于开发中,最终版本只可以包含 INFO, WARN,ERROR这三种日志信息。在实际使用中,我们最好为每一个类声明一个字符串常量TAG,这样在Logcat中我们可以容易区分不同的类的日志。例如:
private static final String TAG = "MyActivity";
接下来我们就可以用Log随心所欲的观察Android代码中的每个细节:Log.e(TAG, "android123.com.cn"); 但是要记住这个Log类的参数都是String类型的。
‘贰’ 在android程序中,log.w用于输出什么级别的日志信息 a调试 b信息 c警告 d
[W]:警告(Warn)信息,输出颜色为橙色
在LogCat的右上方的5个字母分别表示了5种不同类型的日志信息(并以不同颜色加以区分,级别越高,颜色越突出):
1. [V]:详细(Verbose)信息,输出颜色为黑色
2. [D]:调试(Debug)信息,输出颜色是蓝色
3. [I]:通告(Info)信息,输出颜色为绿色
4. [W]:警告(Warn)信息,输出颜色为橙色
5. [E]:错误(Error)信息,输出颜色为红色,这里错误信息的级别最高,其次是警告信息,然后是通知信息和调试信息,级别最低的是详细信息。
6.[assert],新版本加入的。
‘叁’ android开发中, Log.e(TAG )与System打印有什么区别,我用System打印一样
用log的话你可以自定tag,还可以用v、d、i、w、e等,它们打印的颜色是不同的,如v是黑色,w是黄色,e是红色……在你输出调试信息、错误信息等的时候可以更容易从众多信息中找出
‘肆’ Android SDK Manager log 里面有红色字体是什么情况
Log.e出现的。其它Log.i Log.d颜色绿色的。红色就是为了提示一下用户出错了。
‘伍’ 如何分析Android的Log
首先,让我们看一看AndroidLog的格式。下面这段log是以所谓的long格式打印出来的。从前面Logcat的介绍中可以知道,long格式会把时间,标签等作为单独的一行显示。
[ 12-09 21:39:35.510 396: 416 I/ActivityManager ]
Start procnet.coollet.infzmreader:umengService_v1 for service
net.coollet.infzmreader/com.umeng.message.
UmengService:pid=21745 uid=10039 gids={50039, 3003, 1015,1028}
[ 12-09 21:39:35.518 21745:21745I/dalvikvm ]
Turning on JNI app bug workarounds fortarget SDK version 8...
[ 12-09 21:39:35.611 21745:21745D/AgooService ]
onCreate()
我们以第一行为例:12-09 是日期,21:39:35.510是时间396是进程号,416是线程号;I代表log优先级,ActivityManager是log标签。
在应用开发中,这些信息的作用可能不是很大。但是在系统开发中,这些都是很重要的辅助信息。开发工程师分析的log很多都是由测试工程师抓取的,所以可能有些log根本就不是当时出错的log。如果出现这种情况,无论你怎么分析都不太可能得出正确的结论。如何能最大限度的避免这种情况呢?笔者就要求测试工程师报bug时必须填上bug发生的时间。这样结合log里的时间戳信息就能大致判断是否是发生错误时的log。而且根据测试工程师提供的bug发生时间点,开发工程师可以在长长的log信息中快速的定位错误的位置,缩小分析的范围。
同时我们也要注意,时间信息在log分析中可能被错误的使用。例如:在分析多线程相关的问题时,我们有时需要根据两段不同线程中log语句执行的先后顺序来判断错误发生的原因,但是我们不能以两段log在log文件中出现的先后做为判断的条件,这是因为在小段时间内两个线程输出log的先后是随机的,log打印的先后顺序并不完全等同于执行的顺序。那么我们是否能以log的时间戳来判断呢?同样是不可以,因为这个时间戳实际上是系统打印输出log时的时间,并不是调用log函数时的时间。遇到这种情况唯一的办法是在输出log前,调用系统时间函数获取当时时间,然后再通过log信息打印输出。这样虽然麻烦一点,但是只有这样取得的时间才是可靠的,才能做为我们判断的依据。
另外一种误用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比较常见的严重问题有两大类,一是程序发生崩溃;二是产生了ANR。程序崩溃和ANR既可能发生在java层,也可能发生在native层。如果问题发生在java层,出错的原因一般比较容易定位。如果是native层的问题,在很多情况下,解决问题就不是那么的容易了。我们先看一个java层的崩溃例子:
I/ActivityManager( 396): Start proccom.test.crash for activity com.test.crash/.MainActivity:
pid=1760 uid=10065 gids={50065, 1028}
D/AndroidRuntime( 1760): Shutting downVM
W/dalvikvm( 1760): threadid=1: threadexiting with uncaught exception(group=0x40c38930)
E/AndroidRuntime( 1760): FATALEXCEPTION: main
E/AndroidRuntime( 1760):java.lang.RuntimeException: Unable to start activityComponentInfo
{com.test.crash/com.test.crash.MainActivity}:java.lang.NullPointerException
E/AndroidRuntime( 1760): atandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
E/AndroidRuntime( 1760): atandroid.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
E/AndroidRuntime( 1760): atandroid.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime( 1760): atandroid.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
E/AndroidRuntime( 1760): atandroid.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 1760): atandroid.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 1760): atandroid.app.ActivityThread.main(ActivityThread.java:5050)
E/AndroidRuntime( 1760): atjava.lang.reflect.Method.invokeNative(NativeMethod)
E/AndroidRuntime( 1760): atjava.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 1760): atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:793)
E/AndroidRuntime( 1760): atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime( 1760): atdalvik.system.NativeStart.main(NativeMethod)
E/AndroidRuntime( 1760): Caused by:java.lang.NullPointerException
E/AndroidRuntime( 1760): atcom.test.crash.MainActivity.setViewText(MainActivity.java:29)
E/AndroidRuntime( 1760): atcom.test.crash.MainActivity.onCreate(MainActivity.java:17)
E/AndroidRuntime( 1760): atandroid.app.Activity.performCreate(Activity.java:5104)
E/AndroidRuntime( 1760): atandroid.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
E/AndroidRuntime( 1760): atandroid.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
E/AndroidRuntime( 1760): ... 11more
I/Process ( 1760): Sending signal.PID: 1760 SIG: 9
W/ActivityManager( 396): Force finishing activitycom.test.crash/.MainActivity
Jave层的代码发生crash问题时,系统往往会打印出很详细的出错信息。比如上面这个例子,不但给出了出错的原因,还有出错的文件和行数。根据这些信息,我们会很容易的定位问题所在。native层的crash虽然也有栈log信息输出,但是就不那么容易看懂了。下面我们再看一个native层crash的例子:
F/libc ( 2102): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread2102 (testapp)
D/dalvikvm(26630):GC_FOR_ALLOC freed 604K, 11% free 11980K/13368K, paused 36ms, total36ms
I/dalvikvm-heap(26630):Grow heap (frag case) to 11.831MB for 102416-byteallocation
D/dalvikvm(26630):GC_FOR_ALLOC freed 1K, 11% free 12078K/13472K, paused 34ms, total34ms
I/DEBUG ( 127):*** *** *** *** *** *** *** *** *** *** *** *** *** *** ******
I/DEBUG ( 127):Build fingerprint:
'Android/full_maguro/maguro:4.2.2/JDQ39/eng.liuchao.20130619.201255:userdebug/test-keys'
I/DEBUG ( 127):Revision: '9'
I/DEBUG ( 127):pid: 2102, tid: 2102, name: testapp >>>./testapp <<<
I/DEBUG ( 127):signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr00000000
I/DEBUG ( 127): r0 00000020 r173696874 r2 400ff520 r300000000
I/DEBUG ( 127): r4 400ff469 r5beb4ab24 r6 00000001 r7beb4ab2c
I/DEBUG ( 127): r8 00000000 r900000000 sl 00000000 fpbeb4ab1c
I/DEBUG ( 127): ip 4009b5dc spbeb4aae8 lr 400ff46f pc400ff45e cpsr 60000030
I/DEBUG ( 127): d0 000000004108dae8 d1 4108ced84108cec8
I/DEBUG ( 127): d2 4108cef84108cee8 d3 4108cf184108cf08
I/DEBUG ( 127): d4 4108c5a84108c598 d5 4108ca084108c5b8
I/DEBUG ( 127): d6 4108ce684108ce58 d7 4108ce884108ce78
I/DEBUG ( 127): d8 0000000000000000 d9 0000000000000000
I/DEBUG ( 127): d10 0000000000000000 d110000000000000000
I/DEBUG ( 127): d120000000000000000 d130000000000000000
I/DEBUG ( 127): d14 0000000000000000 d150000000000000000
I/DEBUG ( 127): d16 c1dcf7c087fec8b4 d173f50624dd2f1a9fc
I/DEBUG ( 127): d18 41c7b1ac89800000 d190000000000000000
I/DEBUG ( 127): d20 0000000000000000 d210000000000000000
I/DEBUG ( 127): d22 0000000000000000 d230000000000000000
I/DEBUG ( 127): d24 0000000000000000 d250000000000000000
I/DEBUG ( 127): d26 0000000000000000 d270000000000000000
I/DEBUG ( 127): d28 0000000000000000 d290000000000000000
I/DEBUG ( 127): d30 0000000000000000 d310000000000000000
I/DEBUG ( 127): scr 00000010
I/DEBUG ( 127):
I/DEBUG ( 127):backtrace:
I/DEBUG ( 127): #00 pc0000045e /system/bin/testapp
I/DEBUG ( 127): #01 pc0000046b /system/bin/testapp
I/DEBUG ( 127): #02 pc0001271f /system/lib/libc.so (__libc_init+38)
I/DEBUG ( 127): #03 pc00000400 /system/bin/testapp
I/DEBUG ( 127):
I/DEBUG ( 127):stack:
I/DEBUG ( 127): beb4aaa8 000000c8
I/DEBUG ( 127): beb4aaac 00000000
I/DEBUG ( 127): beb4aab0 00000000
I/DEBUG ( 127): beb4aab4 401cbee0 /system/bin/linker
I/DEBUG ( 127): beb4aab8 00001000
I/DEBUG ( 127): beb4aabc 4020191d /system/lib/libc.so (__libc_fini)
I/DEBUG ( 127): beb4aac0 4020191d /system/lib/libc.so (__libc_fini)
I/DEBUG ( 127): beb4aac4 40100eac /system/bin/testapp
I/DEBUG ( 127): beb4aac8 00000000
I/DEBUG ( 127): beb4aacc 400ff469 /system/bin/testapp
I/DEBUG ( 127): beb4aad0 beb4ab24 [stack]
I/DEBUG ( 127): beb4aad4 00000001
I/DEBUG ( 127): beb4aad8 beb4ab2c [stack]
I/DEBUG ( 127): beb4aadc 00000000
I/DEBUG ( 127): beb4aae0 df0027ad
I/DEBUG ( 127): beb4aae4 00000000
I/DEBUG ( 127): #00 beb4aae8 00000000
I/DEBUG ( 127): ........ ........
I/DEBUG ( 127): #01 beb4aae8 00000000
I/DEBUG ( 127): beb4aaec 401e9721 /system/lib/libc.so (__libc_init+40)
I/DEBUG ( 127): #02 beb4aaf0 beb4ab08 [stack]
I/DEBUG ( 127): beb4aaf4 00000000
I/DEBUG ( 127): beb4aaf8 00000000
I/DEBUG ( 127): beb4aafc 00000000
I/DEBUG ( 127): beb4ab00 00000000
I/DEBUG ( 127): beb4ab04 400ff404 /system/bin/testapp
I/DEBUG ( 127):
这个log就不那么容易懂了,但是还是能从中看出很多信息,让我们一起来学习如何分析这种log。首先看下面这行:
pid: 2102, tid: 2102,name: testapp >>>./testapp <<<
从这一行我们可以知道crash进程的pid和tid,前文我们已经提到过,Android调用gettid函数得到的实际是进程Id号,所以这里的pid和tid相同。知道进程号后我们可以往前翻翻log,看看该进程最后一次打印的log是什么,这样能缩小一点范围。
接下来内容是进程名和启动参数。再接下来的一行比较重要了,它告诉了我们从系统角度看,出错的原因:
signal 11 (SIGSEGV), code 1(SEGV_MAPERR), fault addr 00000000
signal11是Linux定义的信号之一,含义是Invalidmemory reference,无效的内存引用。加上后面的“faultaddr 00000000”我们基本可以判定这是一个空指针导致的crash。当然这是笔者为了讲解而特地制造的一个Crash的例子,比较容易判断,大部分实际的例子可能就没有那么容易了。
再接下来的log打印出了cpu的所有寄存器的信息和堆栈的信息,这里面最重要的是从堆栈中得到的backtrace信息:
I/DEBUG ( 127):backtrace:
I/DEBUG ( 127): #00 pc0000045e /system/bin/testapp
I/DEBUG ( 127): #01 pc0000046b /system/bin/testapp
I/DEBUG ( 127): #02 pc0001271f /system/lib/libc.so (__libc_init+38)
I/DEBUG ( 127): #03 pc00000400 /system/bin/testapp
因为实际的运行系统里没有符号信息,所以打印出的log里看不出文件名和行数。这就需要我们借助编译时留下的符号信息表来翻译了。Android提供了一个工具可以来做这种翻译工作:arm-eabi-addr2line,位于prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin目录下。用法很简单:
#./arm-eabi-addr2line -f -eout/target/proct/hammerhead/symbols/system/bin/testapp0x0000045e
参数-f表示打印函数名;参数-e表示带符号表的模块路径;最后是要转换的地址。这条命令在笔者的编译环境中得到的结果是:
memcpy /home/rd/compile/android-4.4_r1.2/bionic/libc/include/string.h:108
剩余三个地址翻译如下:
main /home/rd/compile/android-4.4_r1.2/packages/apps/testapp/app_main.cpp:38
out_vformat /home/rd/compile/android-4.4_r1.2/bionic/libc/bionic/libc_logging.cpp:361
_start libgcc2.c:0
利用这些信息我们很快就能定位问题了。不过这样手动一条一条的翻译比较麻烦,笔者使用的是从网上找到的一个脚本,可以一次翻译所有的行,有需要的读者可以在网上找一找。
‘陆’ Android studio怎么自定义logcat提示信息
进行点击android studio菜单中的file的选项之后,弹出了下拉菜单中进行选择为“settings”的选项。
进入到了settings的选项框中,进行选中列表中的editor的选项。
进行点击editor的会展开,进行点击android logcat的选项。
由于默认的设置是不能修改的所以需要自己进行创建,进行点击save as的选项,需要输入文件名,名字可以随意去
新建的android logcat还是不能直接修改,把use inherited attribute的沟去掉。
这些设置主要进行设置颜色的选项,进行点击颜色按钮。
弹出了select color的窗口之后,进行选择需要的颜色,然后进行点击choose。
可以看到assert在logcat预览中显示为深蓝的颜色。其它设置的设置也是类似。
‘柒’ android中的几个log的功能及作用
android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e()
Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v("","");
Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择.
Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息
Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。
Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了。
以下是使用方法:
Log.v(LogDemo.ACTIVITY_TAG, "This is Verbose.");
Log.d(LogDemo.ACTIVITY_TAG, "This is Debug.");
Log.i(LogDemo.ACTIVITY_TAG, "This is Information");
Log.w(LogDemo.ACTIVITY_TAG, "This is Warnning.");
Log.e(LogDemo.ACTIVITY_TAG, "This is Error.");
‘捌’ android studio怎么设置android Logcat字体颜色
获得文本控件TextView,取名为tv。 通过TextView的setTextColor方法进行文本颜色的设置,这里可以有3种方式进行设置。 tv.setTextColor(android.graphics.Color.RED);//系统自带的颜色类。 tv.setTextColor(0xffff00ff);//0xffff00ff是int类型的数据,分组一下0xffff00ff,0x 是代表颜色整数的标记,ff是表示透明度,ff00ff表示颜色,注意:这里ffff00ff必须是8个的颜色表示,不接受ff00ff这种6个的颜色表 示。 tv.setTextColor(this.getResources().getColor(R.color.red));//通过获得资源文件 进行设置。根据不同的情况R.color.red也可以是R.string.red或者R.drawable.red,当然前提是需要在相应的配置文件里 做相应的配置。 6 通过在Activity类中设置文本颜色,我们可以实现文本颜色的动态化。如果想保持文本颜色静态不变的话,可以直接通过上一篇中讲的通过直接配置即可。
‘玖’ Android 各种log 的介绍
包含设备日志,堆栈跟踪和其他诊断信息,可帮助您查找和修复应用中的错误。
安卓bugreport主要用于分析手机的状态。其包含: main log , kernel log ,cpuinfo等信息。bugreport是一个可执行文件,编译后的路径为system/bin/bugreport,源码位于framework/native/cmds/bugreport。其核心在于启动mpsys服务。bugreport同mpstate服务建立socket通信(建立连接20次,超时3min无数据等容错)。连接之后,将接收到的数据定向到文件中。
因此我们看到的bugreport数据均来自mpstate。
bugreport通过socket与mpstate服务建立通信,在mpstate.cpp中的mpstate()方法完成核心功能。分别输出: current log、 last log、 vm trace、 mpsys、 system info
其详细内容主要有: 系统build及运行时长等信息、 内存和CPU进程的信息、 kernel log、 system log、 radio log、 event log 等等。实际来说,bugreport中显示的大部分为信息,都有对应的命令方式可以获取。bugreport只是作为一个在不打扰用户的前提下执行的一套命令集合。
1). main_log 记录手机android上层app以及framework相关活动的log,比如你写的app打印的log,就在这里面
2). events_log 主要是ActivityManager、powerManager等相关的log
3). kernel Log 驱动相关的log
Logcat是内置在Android系统中的一个可执行工具,用于转储系统消息日志,其中包括设备引发错误时的堆栈追踪以及从您的应用当使用 Log 类编写的消息。可以在主机上通过adb logcat命令来查看模拟机上日志信息。
Android tcpmp是命令行数据包捕获实用程序。它可以捕获来自您的Wi-Fi连接,蜂窝连接以及您在android设备上可能具有的任何其他网络连接的数据包
modem 是手机里负责搜网和sim卡数据操作底层模块,每个手机都有,md log 用于分析掉网、掉话、无信号等问题
系统崩溃时留下的遗言,怎么死的,死哪了,死的多惨。
当一个动态库(native 程序)开始执行时,系统会注册一些连接到 debuggerd 的 signal handlers,当系统 crash(崩溃) 的时候,会保存一个 tombstone 文件到/data/tombstones目录下(Logcat中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。
6. netlog 网络相关
看网络链接情况,抓取网络包等等
7. QXDM(the Qualcomm eXtensible Diagnostic Monitor)高通可扩展诊断监视器
该工具适用于拥有使用Qualcomm ASIC和试用硬件的设备的人,并允许他们测试,评估和潜在诊断其移动设备的RF性能问题。通常使用它来促进这些设备的产品开发。
使用该软件,用户可以查看他们的移动设备发出的所有信令消息,因为该软件会生成它们的日志。这些日志也可以通过软件进行注释。可以将网络和电话参数的任何混合添加到屏幕,并且允许用户在使用其参数时使用复杂的公式。该程序还实时生成大量统计数据,以便用户可以更好地识别潜在的性能问题。用户可以访问Markov统计信息,Mux统计信息,RLP统计信息,块错误率,移动性管理数据,寻呼和访问统计信息,前向和反向链路统计信息等等。该程序还为用户提供了便携式设备信号的图形显示。该程序与Windows操作系统兼容。
8. init Log(init进程log)
9. Crashlog(崩溃日志)
‘拾’ android,log.d()与log.i()什么区别
1、概念不同
Log.d()是仅输出debug调试的意思。
Log.i()指一般提示性的消息information。
2、输出颜色不同
Log.d()的输出颜色是蓝色的。
Log.i()的输出颜色为绿色。
3、作用不同
Log.d()会输出上层信息,过滤起来可以通过DDMS的Logcat标签来选择;
Log.i()不会输出Log.v和Log.d的信息,但会显示i、w和e的信息。
4、打印方法不同
Log.d()打印一些调试信息(logd+tab)。
Log.i()打印一些比较重要的数据,可帮助用户分析行为数据(logi+tab)。