Log与logcat
1. 概述
应用开发与调试中,可以使用Log增加日志打印;然后通过logcat观察&分析日志,定位问题。
2. Log调用
2.1 方法
Log的调用非常简单,通常包括两个步骤:
- 定义TAG;
- Log.e(), w(), i(), d(), v()打印日志
当然,第一步定义TAG不是必须的,但是惯用法。通常一个Activity或Service会定义这个类的一个TAG,从而和其他的组件区分开来;然后在这个组件直接Log(TAG, msg)调用。
2.2 示例
public class MainActivity extends ActionBarActivity {private static final String TAG = "MyActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (savedInstanceState == null) {getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();}Log.d(TAG, "onCreate()");}
2.3 源码
Log的源码如下,包括了前面提到的使用方法:
/*** API for sending log output.** <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()* methods.** <p>The order in terms of verbosity, from least to most is* ERROR, WARN, INFO, DEBUG, VERBOSE. Verbose should never be compiled* into an application except during development. Debug logs are compiled* in but stripped at runtime. Error, warning and info logs are always kept.** <p><b>Tip:</b> A good convention is to declare a <code>TAG</code> constant* in your class:** <pre>private static final String TAG = "MyActivity";</pre>** and use that in subsequent calls to the log methods.* </p>** <p><b>Tip:</b> Don't forget that when you make a call like* <pre>Log.v(TAG, "index=" + i);</pre>* that when you're building the string to pass into Log.d, the compiler uses a* StringBuilder and at least three allocations occur: the StringBuilder* itself, the buffer, and the String object. Realistically, there is also* another buffer allocation and copy, and even more pressure on the gc.* That means that if your log message is filtered out, you might be doing* significant work and incurring significant overhead.*/
public final class Log {
2.4 注意事项
Log的调用应该谨慎,不能使用泛滥。一方面,这样不利于定位,大量的无价值的日志会淹没真正有价值的信息,降低定位问题的效率;另一方面,大量的日志会影响程序的运行效率。而且对于手机设备来讲,会影响电池的续航能力(如前面源码中的描述)。
3. logcat
logcat用于捕获(不限于)Log输出的日志信息,包括adb logcat和Eclipse (ADT)的logcat窗口两种方法。
3.1 adb logcat
直接通过adb logcat查看日志,示例:
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat
--------- beginning of /dev/log/system
I/Vold ( 78): Vold 2.1 (the revenge) firing up
D/Vold ( 78): Volume sdcard state changing -1 (Initializing) -> 0 (No-Media)
W/DirectVolume( 78): Kernel block uevent 'PARTN' 1 pendingparts 0
D/Vold ( 78): Volume sdcard state changing 0 (No-Media) -> 2 (Pending)
W/DirectVolume( 78): Kernel block uevent 'PARTN' 1, 1 minor 1
D/Vold ( 78): Volume sdcard state changing 2 (Pending) -> 1 (Idle-Unmounted)
E/NetlinkEvent( 78): NetlinkEvent::FindParam(): Parameter 'SWITCH_NAME' not found
E/NetlinkEvent( 78): NetlinkEvent::FindParam(): Parameter 'SWITCH_STATE' not found
W/Vold ( 78): Switch /devices/virtual/switch/usb_mass_storage event missing name/state info
E/NetlinkEvent( 78): NetlinkEvent::FindParam(): Parameter 'SWITCH_NAME' not found
E/NetlinkEvent( 78): NetlinkEvent::FindParam(): Parameter 'SWITCH_STATE' not found
W/Vold ( 78): Switch /devices/virtual/switch/usb_mass_storage event missing name/state info
W/Vold ( 78): open sys/devices/platform/msm_hsusb/gadget/lun1/file fail:(No such file or directory)
D/VoldCmdListener( 78): volume list
D/VoldCmdListener( 78): share status ums
D/VoldCmdListener( 78): share status ums
D/VoldCmdListener( 78): volume mount /mnt/sdcard
E/DirectVolume( 78): getDeviceNodes i 0 j 0 1
E/Vold ( 78): /dev/block/vold/179:1 being considered for volume sdcard
D/Vold ( 78): Volume sdcard state changing 1 (Idle-Unmounted) -> 3 (Checking)
I/Vold ( 78): Filesystem check completed OK
I/Vold ( 78): Device /dev/block/vold/179:1, target /mnt/sdcard mounted @ /mnt/secure/staging
D/Vold ( 78): Volume sdcard state changing 3 (Checking) -> 4 (Mounted)
D/VoldCmdListener( 78): asec list
E/NetlinkEvent( 78): NetlinkEvent::FindParam(): Parameter 'SWITCH_NAME' not found
E/NetlinkEvent( 78): NetlinkEvent::FindParam(): Parameter 'SWITCH_STATE' not found
W/Vold ( 78): Switch /devices/virtual/switch/usb_mass_storage event missing name/state info
E/NetlinkEvent( 78): NetlinkEvent::FindParam(): Parameter 'SWITCH_NAME' not found
可以看到简单的logcat会输出大量的日志信息。手机厂商通常会预置一些app,消费者拿到手机之后,也会安装一些。由于某些app会滥用Log,因此会导致大量的日志打印出来。
为此,需要对logcat的结果进行过滤。
3.2 adb logcat --help
最简单地,我们直接查阅logcat的帮助信息:
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat --help
Usage: logcat [options] [filterspecs]
options include:-s Set default filter to silent.Like specifying filterspec '*:s'-f <filename> Log to file. Default to stdout-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> Sets the log print format, where <format> is one of:brief process tag thread raw time threadtime long-c clear (flush) the entire log and exit-d dump the log and then exit (don't block)-t <count> print only the most recent <count> lines (implies -d)-g get the size of the log's ring buffer and exit-b <buffer> request alternate ring buffer('main' (default), 'radio', 'events')-B output the log in binary
filterspecs are a series of <tag>[:priority]where <tag> is a log component tag (or * for all) and priority is:V VerboseD DebugI InfoW WarnE ErrorF FatalS Silent (supress all output)'*' means '*:d' and <tag> by itself means <tag>:vIf not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.
If no filterspec is found, filter defaults to '*:I'If not specified with -v, format is set from ANDROID_PRINTF_LOG
or defaults to "brief"flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$
或者从Android官网查阅详细信息。由于众所周知的原因,频繁进入developer.android.com是很费劲的,因此最好把Android SDK docs下载一份到本地,具体请参考 Ubuntu下面搭建Android应用开发环境。示例:
3.3 adb logcat使用示例
只显示特定的Activity的debug及以上的日志:
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat MyActivity:d *:S
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
D/MyActivity( 1939): onCreate()
D/MyActivity( 1939): onResume()
D/MyActivity( 1939): onStop()
如果显示MyActivity的所有日志,则可以直接adb logcat MyActivity *:S
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat MyActivity *:S
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
D/MyActivity( 1939): onCreate()
D/MyActivity( 1939): onResume()
D/MyActivity( 1939): onStop()
或者
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat -s MyActivity
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
D/MyActivity( 1939): onCreate()
D/MyActivity( 1939): onResume()
D/MyActivity( 1939): onStop()
如果日志非常多,希望重定向到文件中,事后分析,也是可以的,只需要> mylog即可:
其他几种常用法:
a. 每条日志前面增加时间戳:-v time
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat -s -v time MyActivity
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
06-05 19:13:57.089 D/MyActivity( 1939): onCreate()
06-05 19:13:57.099 D/MyActivity( 1939): onResume()
06-05 19:14:00.259 D/MyActivity( 1939): onStop()
b. 取完日志之后就退出adb进程:-d
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat -s -v time -d MyActivity
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
06-05 19:13:57.089 D/MyActivity( 1939): onCreate()
06-05 19:13:57.099 D/MyActivity( 1939): onResume()
06-05 19:14:00.259 D/MyActivity( 1939): onStop()
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$
c. 日志本身是缓存的,如果要清除历史日志,则使用-c,然后再用前面的命令:
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat -c
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat -s -v time -d MyActivity
--------- beginning of /dev/log/main
flying-bird@flyingbird:~/software/android/adt-bundle-linux-x86-20140321/sdk/platform-tools$ ./adb logcat -s -v time MyActivity
--------- beginning of /dev/log/main
06-05 19:17:07.769 D/MyActivity( 1939): onCreate()
06-05 19:17:07.769 D/MyActivity( 1939): onResume()
06-05 19:17:16.299 D/MyActivity( 1939): onStop()
3.4 Eclipse Logcat View
几种常用的过滤方法:
1. 指定某个Activity的日志:tag:MyActivity
2. 某个app:app:com.example.helloworld
Log与logcat相关推荐
- 【android9.0】system/core下的usbhost模块无法输出log到logcat
2019独角兽企业重金招聘Python工程师标准>>> 现象:原生android9.0 sdk,system/core/libusbhost是usb模块用来和驱动通信的模块,在调试时 ...
- Android——调试之 Log和LogCat的详解
QQ 1274510382 Wechat JNZ_aming 商业互捧 QQ群538250800 技术搞事 QQ群599020441 技术合作 QQ群152889761 加入我们 QQ群6493473 ...
- 国美金融贷款调试之 Log和LogCat(国美金融贷款)
国美金融贷款为什么使用Log而不使用System.out 国美金融贷款System.out.println()方法来打印日志 这个方法除了使用方便一点之外,其他就一无是处了. 国美金融贷款在Eclip ...
- Android 打印log 在logcat 看不到
今天调试一个问题,因为是插件,只能通过打印log 定位问题. 但是打印了log 一直没有看到. 代码如下: Log.d("","aaaa24"); 后来发现是需 ...
- android 6.0 logcat机制(一)java层写log,logd接受log
第一篇博客,讲的主要是c++,java中打印log,然后通过socket传给logd,然后logd是如何处理接受log的. 一.logcat常用命令 logcat -c 清除已有log信息 logca ...
- Android logcat命令详解
一.logcat命令介绍 1.android log系统 2.logcat介绍 logcat是android中的一个命令行工具,可以用于得到程序的log信息 log类是一个日志类,可以在代码中使用lo ...
- 总结调试过程中怎么去抓log
开发调试中的办法非常多,LOG是其中重要的一个方法,一些常见的LOG的抓取办法(主要针对QUALCOMM平台,未经详细整理): 1.ADB查看或保存kernel的启动LOG: kernel log: ...
- Android使用adb抓完整Log
点击打开链接 前言 最新项目里一直在做 Android RIL 方面的研究,非常最终项目还是未能解决通信底层模块的问题,但是在使用adb抓log上还是有一些收获的,这里记录一下. Log分类 Andr ...
- Android之如何用cmd方法查看logcat
使用cmd命令查看logcat 使用adb logcat命令可查看android系统和应用的log adb logcat //显示全部日志 adb logcat > c:\test.lo ...
最新文章
- 吴忠强:刷LeetCode的正确姿势!
- VirtualBox安装Fedora文件共享
- C语言 课设 最新版 学生成绩管理系统
- 怎么在mysql创建数据库怎么加入学号_数据库怎么创建学生信息表
- 数据库:SQLServer中游标的用法笔记
- Spring Framework 3.2 M1发布
- 全球链界科技发展大会_科技界女性占五席
- excel二极管伏安特性曲线_从交流电转直流电出发调研二极管的使用
- 越是牛逼的人,越是不在意面子
- CentOS7和win7双系统启动项
- 【模板】质数判断(Miller_Rabin)
- poj 2406 Power Strings kmp基础
- 破解版PDF编辑器————Adobe Acrobat DC
- Flex Builder 中视图状态
- YUV420->RGB888格式转换的CPP实现
- oneNote笔记名不同步
- 鸿蒙os系统使用技巧,鸿蒙OS 应用权限管理
- 推荐几款ReactJS最优秀的UI框架
- 金融信贷风控中的机器学习
- R语言基础学习记录4:重要函数