失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android日志[进阶篇]一-使用 Logcat 写入和查看日志

Android日志[进阶篇]一-使用 Logcat 写入和查看日志

时间:2023-07-28 12:54:55

相关推荐

Android日志[进阶篇]一-使用 Logcat 写入和查看日志

Android日志[进阶篇]一-使用 Logcat 写入和查看日志

Android日志[进阶篇]二-分析堆栈轨迹(调试和外部堆栈)

Android日志[进阶篇]三-Logcat命令行工具

Android日志[进阶篇]四-获取错误报告

Android日志[进阶篇]五-阅读错误报告

目录

查看应用日志写入日志消息Logcat 消息格式设置日志级别搜索 logcat 消息过滤 logcat 消息读取垃圾回收消息Dalvik 日志消息ART 日志消息

Android Studio 中的Logcat窗口会显示系统消息,例如在进行垃圾回收时显示的消息,以及使用Log类添加到应用的消息。此窗口可以实时显示消息,也可以保留历史记录,因此可以查看较早的消息。

要仅显示感兴趣的信息,可以创建过滤器、修改消息中显示的信息量、设置优先级、仅显示通过应用代码生成的消息以及搜索日志。默认情况下,logcat 仅显示与最近运行的应用相关的日志输出。

如果应用抛出异常,logcat 会显示一条消息,后跟相关联的堆栈轨迹,其中包含指向相应代码行的链接。

从 Android Studio 2.2 开始,Run窗口还会显示当前正在运行的应用的日志消息。请注意,可以配置 logcat 输出显示,但无法配置Run窗口。

查看应用日志

如需显示应用的日志消息,请执行以下操作:

在设备上构建和运行应用。 依次点击View > Tool Windows > Logcat(或点击工具窗口栏中的Logcat图标 )。

Logcat 窗口会显示所选应用(从窗口顶部的下拉列表中选择)的日志消息,如图 1 所示。

图 1.Logcat 窗口

默认情况下,Logcat 仅显示在设备上运行的应用的日志消息。要更改此默认设置,请参阅如何过滤 logcat 消息。

Logcat 工具栏中提供的按钮(如图1标号):

Clear logcat:点击此按钮可以清除显示的日志。Scroll to the end:点击此按钮可以跳转到日志底部并查看最新的日志消息。如果先点击此按钮,然后点击日志中的某一行,则视图会在相应位置暂停滚动。Up the stack trace 和Down the stack trace:点击相应按钮可以在日志的堆栈轨迹中进行上下导航,从而选择输出的异常中显示的后续文件名(以及在编辑器中查看相应行号)。这与日志中点击某个文件名时的行为相同。Use soft wraps:点击此按钮可以启用换行并防止水平滚动(尽管所有非间断字符串仍然需要进行水平滚动)。Print:点击此按钮可以输出 logcat 消息。在显示的对话框中选择输出偏好设置后,还可以选择将其保存为 PDF 格式。Restart:点击此按钮可以清除日志并重启 logcat。与Clear logcat按钮不同,此按钮可以恢复并显示之前的日志消息,因此当 Logcat 无响应而又不想失去日志消息时,此按钮是最有用的。Logcat header:点击此按钮可以打开Configure Logcat Header对话框,在该对话框中,可以自定义各个 Logcat 消息的外观,例如是否显示日期和时间。Screen capture:点击此按钮可以截取屏幕截图。Screen record:点击此按钮可以录制设备屏幕的视频(时长不超过 3 分钟)。

写入日志消息

通过Log类,可以创建(输出)日志消息,这些消息会显示在 logcat 中。一般来说,使用以下日志方法,这些方法按照优先级从高到低(或者从最简略到最详细)的顺序列示:

Log.e(String, String)(错误)Log.w(String, String)(警告)Log.i(String, String)(信息)Log.d(String, String)(调试)Log.v(String, String)(详细)

有关更完整的选项列表,请参阅Log类说明。

除开发期间外,其他任何时候都绝不应将详细日志编译到您的应用中。虽然会编译调试日志,但会在运行时将其去掉,而错误、警告和信息日志会始终保留。

对于每种日志方法,第一个参数都应是唯一标记,第二个参数都应是消息。系统日志消息的标记是一个简短的字符串,指示消息所源自的系统组件(例如ActivityManager)。标记可以是有用的任何字符串,例如当前类的名称。

一种比较好的做法是,在要用于第一个参数的类中声明TAG常量。例如,可以按如下方式创建一条信息日志消息:

private static final String TAG = "MyActivity";...Log.i(TAG, "MyClass.getView() — get item number " + position);

注意:长度超过 23 个字符的标记名称在 logcat 输出中会被截断。

Logcat 消息格式

每个 Android 日志消息都有一个与之相关联的标记和优先级。系统日志消息的标记是一个简短的字符串,指示消息所源自的系统组件(例如ActivityManager)。用户定义的标记可以是任何字符串,例如当前类的名称(建议的标记)。可以在Log方法调用中定义它,例如:

Log.d(tag, message)

优先级低到高:

V:详细(优先级最低)D:调试I:信息W:警告E:错误A:断言

日志消息的格式为:

date time PID-TID/package priority/tag: message

例如,下面的日志消息的优先级为V,标记为Eagle

12-10 13:02:50.071 1901-4229/com.eagle.app V/Eagle: Handling delegate intent.

PID 代表进程标识符,TID 则为线程标识符;如果仅有一个线程,两者可以相同。

设置日志级别

可以通过设置日志级别来控制 logcat 中显示的消息数量。可以显示所有消息,也可以仅显示指示最严重情况的消息。

请注意,无论日志级别设置如何,logcat 都会继续收集所有消息。此设置仅决定 logcat 显示什么。

在“Log level”菜单中,选择以下值之一:

Verbose:显示所有日志消息(默认值)。Debug:显示仅在开发期间有用的调试日志消息,以及此列表中较低的消息级别。Info:显示常规使用情况的预期日志消息,以及此列表中较低的消息级别。Warn:显示尚不是错误的潜在问题,以及此列表中较低的消息级别。Error:显示已经引发错误的问题,以及此列表中较低的消息级别。Assert:显示开发者预计绝不会发生的问题。

搜索 logcat 消息

要搜索 logcat 中当前显示的消息,请执行以下操作:

(可选)如果想要使用正则表达式搜索模式,请选择Regex。 在搜索框中输入字符序列。

Logcat 输出会相应地显示更改。

按 Enter 键以在此会话期间将搜索字符串保存到菜单中。 要重复搜索,请从搜索菜单中选择。根据需要选择或取消选择Regex(不建议使用此设置)。

过滤 logcat 消息

将日志输出减少至可管理水平的一种方法是,使用过滤器施加限制。

注意:过滤器会应用于 logcat 的全部历史记录,而不仅仅是 logcat 中当前显示的消息。确保适当地设置其他显示选项,以便能够看到想要检查的过滤器输出。

要定义并应用过滤器,请执行以下操作:

在过滤器菜单中,选择一个过滤选项:Show only selected application:仅显示通过应用代码生成的消息(默认选项)。Logcat 使用正在运行的应用的 PID 来过滤日志消息。No Filters:不应用过滤器。无论选择哪个进程,logcat 都会显示设备中的所有日志消息。Edit Filter Configuration:创建或修改自定义过滤器。例如,创建一个过滤器,以同时查看两个应用中的日志消息。 定义过滤器后,可以在菜单中选择它们。要从菜单中移除过滤器,删除即可。 如果选择了Edit Filter Configuration,请创建或修改过滤器: 在“Create New Logcat Filter”对话框中指定过滤器参数:Filter Name:输入要设定的过滤器的名称,或者从左侧窗格中进行选择以修改现有过滤器。名称只能包含小写字符、下划线和数字。Log Tag:(可选)指定标记。如需了解详情,请参阅 Logcat 消息格式。Log Message:(可选)指定日志消息文本。如需了解详情,请参阅 Logcat 消息格式。Package Name:(可选)指定软件包名称。如需了解详情,请参阅 Logcat 消息格式。PID:(可选)指定进程 ID。如需了解详情,请参阅 Logcat 消息格式>。Log Level:(可选)选择日志级别。如需了解详情,请参阅设置日志级别。Regex:选择此选项可以为相应参数使用正则表达式语法。 点击+,将过滤器定义添加到左侧窗格中。

要移除过滤器,请在左侧窗格中将其选中,然后点击-

完成后,点击OK

如果没有看到想要检查的日志消息,请尝试选择No filters再clean一下日志, 并搜索特定日志消息。

读取垃圾回收消息

有时,发生垃圾回收事件时,相应消息会输出到 Logcat 中。

如需详细了解应用的内存,请使用内存性能分析器。

Dalvik 日志消息

在 Dalvik(而不是 ART)中,每个 GC 都会将以下信息输出到 logcat 中:

D/dalvikvm(PID): GC_Reason Amount_freed, Heap_stats, External_memory_stats, Pause_time

示例:

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

GC 原因什么触发了 GC 以及是哪种回收。可能的原因包括:GC_CONCURRENT在app的堆开始占用内存时释放内存的并发 GC。GC_FOR_MALLOC堆已满而系统不得不停止应用并回收内存时,应用尝试分配内存而引起的 GC。GC_HPROF_DUMP_HEAP当请求创建 HPROF 文件来分析堆时发生的 GC。GC_EXPLICIT显式 GC,例如当调用gc()时(开发者应避免调用它,而应信任 GC 会根据需要运行)。GC_EXTERNAL_ALLOC这仅适用于 API 级别 10 及更低级别(更新的版本会在 Dalvik 堆中分配任何内存)。外部分配内存的 GC(例如存储在原生内存或 NIO 字节缓冲区中的像素数据)。 释放量从此次 GC 中回收的内存量。 堆统计数据堆的可用空间百分比与(活动对象数量)/(堆总大小)。 外部内存统计数据API 级别 10 及更低级别的外部分配内存(已分配内存量)/(发生回收的限值)。 暂停时间堆越大,暂停时间越长。并发暂停时间显示两个暂停:一个出现在回收开始时,另一个出现在回收快要完成时。

在此类日志消息积聚时,请注意堆统计数据(上面示例中的3571K/9991K值)的增大情况。如果此值继续增大,可能会出现内存泄露。

ART 日志消息

与 Dalvik 不同,ART 不会为未明确请求的 GC 记录消息。只有在系统认为 GC 速度较慢时才会输出 GC 消息。更确切地说,仅在 GC 暂停时间超过 5 毫秒或 GC 持续时间超过 100 毫秒时。如果应用未处于可察觉到暂停的状态(例如应用在后台运行时,这种情况下,用户无法察觉 GC 暂停),则其所有 GC 都不会被视为速度较慢。系统一直会记录显式 GC。

ART 会在其垃圾回收日志消息中包含以下信息:

I/art: GC_Reason GC_Name Objects_freed(Size_freed) AllocSpace Objects,Large_objects_freed(Large_object_size_freed) Heap_stats LOS objects, Pause_time(s)

示例:

I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects,21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms

GC 原因什么触发了 GC 以及是哪种回收。可能的原因包括:Concurrent不会挂起应用线程的并发 GC。此 GC 在后台线程中运行,而且不会阻止分配。Alloc应用在堆已满时尝试分配内存而引起的 GC。在这种情况下,垃圾回收在分配线程中发生。Explicit由应用明确请求的垃圾回收,例如,通过调用gc()gc()。与 Dalvik 一样,在 ART 中,最佳做法是信任 GC 并避免请求显式 GC(如果可能)。不建议请求显式 GC,因为它们会阻止分配线程并不必要地浪费 CPU 周期。此外,如果显式 GC 导致其他线程被抢占,则也可能会导致卡顿(应用出现卡顿、抖动或暂停)。NativeAlloc原生分配(例如位图或 RenderScript 分配对象)导致出现原生内存压力,进而引起的回收。CollectorTransition由堆转换引起的回收;这由在运行时变更 GC 策略引起(例如应用在可察觉到暂停的状态之间切换时)。回收器转换包括将所有对象从空闲列表空间复制到碰撞指针空间(反之亦然)。

回收器转换仅在以下情况下出现:在 Android 8.0 之前的低内存设备上,应用将进程状态从可察觉到暂停的状态(例如应用在前台运行时,这种情况下,用户可以察觉 GC 暂停)更改为察觉不到暂停的状态(反之亦然)。

HomogeneousSpaceCompact同构空间压缩是空闲列表空间到空闲列表空间压缩,通常在应用进入到察觉不到暂停的进程状态时发生。这样做的主要原因是减少内存使用量并对堆进行碎片整理。DisableMovingGc这不是真正的 GC 原因,但请注意,由于在发生并发堆压缩时使用了 GetPrimitiveArrayCritical,回收遭到阻止。一般情况下,强烈建议不要使用 GetPrimitiveArrayCritical,因为它在移动回收器方面存在限制。HeapTrim这不是 GC 原因,但请注意,在堆修剪完成之前,回收会一直受到阻止。GC 名称ART 具有可以运行的多种不同的 GC。Concurrent mark sweep (CMS)整个堆回收器,会释放和回收除映像空间以外的所有其他空间。Concurrent partial mark sweep几乎整个堆回收器,会回收除映像空间和 Zygote 空间以外的所有其他空间。Concurrent sticky mark sweep分代回收器,只能释放自上次 GC 后分配的对象。此垃圾回收比完整或部分标记清除运行得更频繁,因为它更快速且暂停时间更短。Marksweep + semispace非并发、复制 GC,用于堆转换以及同构空间压缩(对堆进行碎片整理)。 释放的对象此 GC 从非大型对象空间回收的对象数量。 释放的大小此 GC 从非大型对象空间回收的字节数量。 释放的大型对象此垃圾回收从大型对象空间回收的对象数量。 释放的大型对象大小此垃圾回收从大型对象空间回收的字节数量。 堆统计数据可用空间百分比与(活动对象数量)/(堆总大小)。 暂停时间通常情况下,暂停时间与 GC 运行时修改的对象引用数量成正比。当前,ART CMS GC 仅在 GC 即将完成时暂停一次。 移动 GC 的暂停时间较长,会在 GC 的大部分时间持续。

如果在 logcat 中看到大量 GC,请注意堆统计数据(上面示例中的25MB/38MB值)的增大情况。如果此值继续增大,且始终没有变小的趋势,可能会出现内存泄漏。或者,如果看到原因为“Alloc”的 GC,则您已快要达到堆容量上限,并且很快会出现 OOM 异常。

如果觉得《Android日志[进阶篇]一-使用 Logcat 写入和查看日志》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。