热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

将终端上打印的信息到一个日志文件_调试利器:【日志工具】的使用与掌握...

通过前面的学习,我们已经成功创建了你的第一个Android程序,并且对Android项目的目录结构和运行流程都有了一定的了解。现在本应该是你继续前行的时

通过前面的学习,我们已经成功创建了你的第一个 Android 程序,并且对 Android 项目的目录结构和运行流程都有了一定的了解。现在本应该是你继续前行的时候,不过我想在这里给你穿插一点内容,讲解一下 Android 中日志工具的使用方法,这对你以后的 Android 开发之旅会有极大的帮助。


使用 Android 的日志工具 Log

Android 中的日志工具类是 Log( android.util.Log ),这个类中提供了如下 5 个方法来供我们打印日志。

Log.v() 。用于打印那些最为琐碎的、意义最小的日志信息。对应级别 verbose,是 Android 日志里面级别最低的一种。

Log.d() 。用于打印一些调试信息,这些信息对你调试程序和分析问题应该是有帮助的。对应级别 debug,比 verbose 高一级。

Log.i() 。用于打印一些比较重要的数据,这些数据应该是你非常想看到的、可以帮你分析用户行为数据。对应级别 info,比 debug 高一级。

Log.w() 。用于打印一些警告信息,提示程序在这个地方可能会有潜在的风险,最好去修复一下这些出现警告的地方。对应级别 warn,比 info 高一级。

Log.e() 。用于打印程序中的错误信息,比如程序进入到了 catch 语句当中。当有错误信息打印出来的时候,一般都代表你的程序出现严重问题了,必须尽快修复。对应级别 error,比 warn 高一级。

其实很简单,一共就 5 个方法,当然每个方法还会有不同的重载,但那对你来说肯定不是什么难理解的地方了。我们现在就在 HelloWorld 项目中试一试日志工具好不好用吧。

打开 HelloWorldActivity ,在 onCreate() 方法中添加一行打印日志的语句,如下所示:

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.hello_world_layout);Log.d("HelloWorldActivity", "onCreate execute");
}

Log.d()方法中传入了两个参数:第一个参数是 tag,一般传入当前的类名就好,主要用于对打印信息进行过滤;第二个参数是 msg,即想要打印的具体的内容。

现在可以重新运行一下 HelloWorld 这个项目了,点击顶部工具栏上的运行按钮,或者使用快捷键 Shift + F10(Mac 系统是 control + R),等程序运行完毕,点击 Android Studio 底部工具栏的 Android Monitor ,在 logcat 中就可以看到打印信息了,如图 1.31 所示。

logcat 中的打印信息

其中,你不仅可以看到打印日志的内容和 tag 名,就连程序的包名、打印的时间以及应用程序的进程号都可以看到。

另外,不知道你有没有注意到,你的第一行代码已经在不知不觉中写出来了,我也总算是交差了。


为什么使用 Log 而不使用 System.out

我相信很多的 Java 新手都非常喜欢使用 System.out.println() 方法来打印日志,不知道你是不是也喜欢这么做。不过在真正的项目开发中,是极度不建议使用 System.out.println() 方法的!如果你在公司的项目中经常使用这个方法,就很有可能要挨骂了。

为什么 System.out.println() 方法会这么遭大家唾弃呢?经过我仔细分析之后,发现这个方法除了使用方便一点之外,其他就一无是处了。方便在哪儿呢?在 Eclipse 中你只需要输入 syso,然后按下代码提示键,这个方法就会自动出来了,相信这也是很多 Java 新手对它钟情的原因。那缺点又在哪儿了呢?这个就太多了,比如日志打印不可控制、打印时间无法确定、不能添加过滤器、日志没有级别区分……

听我说了这些,你可能已经不太想用 System.out.println() 方法了,那么 Log 就把上面所说的缺点全部都改好了吗?虽然谈不上全部,但我觉得 Log 已经做得相当不错了。我现在就来带你看看 Log 和 logcat 配合的强大之处。


首先刚才提到的快捷输入,在 Android Studio 当中也是有的,比如你想打印一条 debug 级别的日志,那么只需要输入 logd,然后按下 Tab 键,就会帮你自动补全一条完整的打印语句。输入 logi,然后按下 Tab 键,会自动补全一条 info 级别的打印日志。输入 logw,按下 Tab 键,会自动补全一条 warn 级别的打印日志,以此类推。另外,由于 Log 的所有打印方法都要求传入一个 tag 参数,每次写一遍显然太过麻烦。这里还有一个小技巧,我们在 onCreate() 方法的外面输入 logt,然后按下 Tab 键,这时就会以当前的类名作为值自动生成一个 TAG 常量,如下所示:

public class HelloWorldActivity extends AppCompatActivity {private static final String TAG = "HelloWorldActivity";...
}

除了快捷输入之外,logcat 中还能很轻松地添加过滤器,你可以在图 1.32 中看到我们目前所有的过滤器。

46e6711aab42ca7ec4544d28d033191d.png

目前只有 3 个过滤器,Show only selected application 表示只显示当前选中程序的日志,Firebase 是谷歌提供的一个分析工具,我们可以不用管它,No Filters 相当于没有过滤器,会把所有的日志都显示出来。那可不可以自定义过滤器呢?当然可以,我们现在就来添加一个过滤器试试。

点击下图中的 Edit Filter Configuration ,会弹出一个过滤器配置界面。我们给过滤器起名叫 data,并且让它对名为 data 的 tag 进行过滤,如图下所示。

e6a65c8b8a2d85cd38683344979f57da.png

点击 OK,你就会发现你已经多出了一个 data 过滤器。当你点击这个过滤器的时候,你会发现刚才在 onCreate() 方法里打印的日志没了,这是因为 data 这个过滤器只会显示 tag 名称为 data 的日志。你可以尝试在 onCreate() 方法中把打印日志的语句改成 Log.d("data", "onCreate execute") ,然后再次运行程序,你就会在 data 过滤器下看到这行日志了。

不知道你有没有体会到使用过滤器的好处,可能现在还没有吧。不过当你的程序打印出成百上千行日志的时候,你就会迫切地需要过滤器了。

看完了过滤器,再来看一下 logcat 中的日志级别控制吧。logcat 中主要有 5 个级别,分别对应着上一节介绍的 5 个方法,如下图所示。

3a04a49b997397f5f3326fa2fd5026c6.png

当前我们选中的级别是 verbose,也就是最低等级。这意味着不管我们使用哪一个方法打印日志,这条日志都一定会显示出来。而如果我们将级别选中为 debug,这时只有我们使用 debug 及以上级别方法打印的日志才会显示出来,以此类推。你可以做一下试验,当你把 logcat 中的级别选中为 info、warn 或者 error 时,我们在 onCreate() 方法中打印的语句是不会显示的,因为我们打印日志时使用的是 Log.d()方法。

日志级别控制的好处就是,你可以很快地找到你所关心的那些日志。相信如果让你从上千行日志中查找一条崩溃信息,你一定会抓狂的吧。而现在你只需要将日志级别选中为 error,那些不相干的琐碎信息就不会再干扰你的视线了。

最后我们再来看一下关键字过滤。如果使用过滤器加日志级别控制还是不能锁定到你想查看的日志内容的话,那么还可以通过关键字进行进一步的过滤,如图 1.35 所示。

e8da4eef5b0500bacf60f5929a4d9689.png

我们可以在输入框里输入关键字的内容,这样只有符合关键字条件的日志才会显示出来,从而能够快速定位到任何你想查看的日志。另外还有一点需要注意,关键字过滤是支持正则表达式的,有了这个特性,我们就可以构建出更加丰富的过滤条件。

关于 Android 中日志工具的使用我就准备讲到这里,logcat 中其他的一些使用技巧就要靠你自己去摸索了。今天你已经学到了足够多的东西,我们来总结和梳理一下吧。


小结

我们入门安卓开发的第一季课程就到这里了。

你现在一定会觉得很充实,甚至有点沾沾自喜。确实应该如此,因为你已经成为一名真正的 Android 开发者了。通过本章的学习,你首先对 Android 系统有了更加充足的认识,然后成功将 Android 开发环境搭建了起来,接着创建了你自己的第一个 Android 项目,并对 Android 项目的目录结构和执行过程有了一定的认识,在本章的最后还学习了 Android 日志工具的使用,这难道还不够充实吗?

不过你也别太过于满足,相信你很清楚,Android 开发者和出色的 Android 开发者还是有很大的区别的,你还需要付出更多的努力才行。即使你目前在 Java 领域已经有了不错的成绩,我也希望在 Android 的世界你可以放下身段,以一只萌级小菜鸟的身份起飞,在后面的旅途中你会不断地成长。

现在你可以非常安心地休息一段时间,因为今天你已经做得非常不错了。储备好能量,准备进入到下一章的旅程当中。



推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文介绍了Java中Hashtable的clear()方法,该方法用于清除和移除指定Hashtable中的所有键。通过示例程序演示了clear()方法的使用。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了GregorianCalendar类的基本信息,包括它是Calendar的子类,提供了世界上大多数国家使用的标准日历系统。默认情况下,它对应格里高利日历创立时的日期,但可以通过调用setGregorianChange()方法来更改起始日期。同时,文中还提到了GregorianCalendar类为每个日历字段使用的默认值。 ... [详细]
author-avatar
采蘑菇的灵的fans
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有