authors are vetted experts in their fields 和 write on topics in which they have demonstrated experience. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
吉拉德Haimov的头像

吉拉德Haimov

Gilad拥有超过19年的安卓手机开发经验, 服务器端, 以及通信系统.

专业知识

以前在

bmc软件
<但ton aria-label="分享" class="_2foqyr9I">分享
分享

发展是一件棘手的事情. 目标一直在移动, 新技术和新领域周期性地出现, 新工具不时出现, 语言 这似乎是一场精心策划的浩劫.

然而,即使发生了所有这些变化,基本规则仍然保持不变. 这些基本规则中最重要的一条是,要创造真正了不起的软件, 你必须深入, 持续的和详细的 自省 进入执行系统. 诊断, 调试, 分析 术语有时在这种情况下使用,但规则更深入. 一流的开发人员会“感觉”自己的系统. 他知道这将导致等待更多内存释放的分块, 什么会使它的线程陷入CPU饥饿, 哪些操作会导致大量的I/O或网络访问,从而减慢整个操作速度.

没有别的办法了. 你可能是一个非常聪明的开发人员,写着很棒的代码, 但, 直到你没有上述技能, 即能够监视和研究系统运行时行为的细节, 在交付真正一流的应用程序时,您仍然会落后.

事实上, 在获得一些经验之后, you will detect a whole category of “code diseases” which can be traced to neglecting the rule of 自省: Briefly put, writing code (sometimes smart code) without continuous monitoring of its effects on the actual platform.

安卓中的摘要讨论:我自省的首选武器

我们很幸运, 安卓社区已经成功地提供了许多一流的自省工具. Facebook的 Stetho 是最好的,AT&T’s ARO (“应用程序资源优化器”)是一个有点老,但仍然是一流的, 拥有最好的网络监控控制台, 而 LeakCanary takes a way more limited approach concentrating (和 doing great at it) on runtime memory leak detection library. 长话短说,市面上不乏安卓调试工具.

仍然, 王冠上的钻石, 关键时刻值得信赖的自省工具, 准确的, well formatted data needs to be extracted regarding the runtime behavior of your app is still the good old Dalvik调试监控服务器(摘要讨论) 在安卓 Studio中, which has been with us (alas underused by so many teams) since the days of the Eclipse 安卓 plugin.

摘要讨论在安卓开发中有多重要? 好吧, 我现在对摘要讨论和移动应用监控的了解大概是5-6年前, 作为一个经验不足的安卓开发者, 就能帮我省个 很多 头痛和夜晚的调试.

安卓 摘要讨论封面插图:开发人员调试摘要讨论.

问题是摘要讨论很容易掌握!

当然, 很大一部分是正确使用它, 与任何其他软件工具一样, 来自于经验. You need to hone your professional skills for some time until you become 真的 good at runtime performance monitoring. 但即使是在几个小时内, 读完这篇文章后说, 如果你遵循我的建议并将它们应用到你的下一个应用程序中, 结果将是惊人的! 分析和调优即使是复杂的系统也不是那么难. 它也可以很有趣!

A question often gets asked regarding the difference between novice 和 master-level mobile developers. 精通安卓中的摘要讨论——或者一般来说, 应用程序分析和自省功能是其中一个主要区别.

注意: A major portion of becoming a top notch developer is using the best libraries available in your domain. 在之前 Toptal文章,我列出了一些适用于安卓的最佳开发者库. 从某种意义上说,这篇文章是“库”那篇文章的续集,涵盖了众多安卓工具中的一个. 不用说,如果你的目标是提高你的安卓开发技能,现在阅读它!

安卓 Studio中的摘要讨论快速指南

现在, 废话不多说, 现在让我们深入研究摘要讨论的描述, 安卓开发者的终极工具之一.

在权衡努力与利益时, 可能没有其他工具可以提高你的应用程序的质量,并帮助你定位 真的 它可能含有混乱和难以捉摸的虫子. 但是,由于某种原因(懒惰),任何人?),因此许多团队无法使用摘要讨论.

让我们从摘要讨论速成班开始:

摘要讨论可通过 Studio > 工具 > 安卓 > 安卓 Device Monitor 点击菜单上的摘要讨论按钮. 你也可以把它作为一个快捷图标(我就是这么做的)放在你的上面板上.

打开后,你会看到:

截图:通过安卓设备监视器访问摘要讨论

The left panel allows for device/app selection 和 the right console provides you will multiple views, 每个都在自己的TAB中, 每个都展示了应用程序的特定视图.

Dalvik调试监控服务器提供的主要服务有:

  • 应用程序内存使用统计(总堆和对象分配统计)
  • 应用程序线程统计
  • 设备屏幕截图
  • 设备文件管理器
  • 来电和短信欺骗
  • 位置数据欺骗
  • Logcat

要获取应用程序使用的当前堆内存值,只需执行以下操作:

  • 连接正在运行应用程序的设备
  • 单击Update Heap按钮以启用堆状态收集
  • 打开堆选项卡
  • 单击“Cause GC”强制运行GC. 只有在这样的运行之后,堆数据收集才会开始
  • 打开标签, 继续开发你的应用, 并定期重新单击“Cause GC”以刷新堆统计数据

最后一行可能需要额外的解释. 内存使用率是其中一个分析值 动力学 比初始值更重要吗. 对于大多数应用程序,我们不会太关心初始堆使用值. 我们会非常关注这个值的进展, as it will provide us with a clear indication of one the true nightmares awaiting mobile developers—安卓 memory leaks:

截图:堆数据用于识别摘要讨论中的安卓内存泄漏

My usage of the heap stat module is simple; as part of the lifecycle of developing the app, 在引入影响堆使用的更改之后, 我来启动模块, “导致GC”初始化状态收集, 激活(通常不止一次)应用程序的堆密集位置, 并定期“导致GC”刷新. 如果堆使用率持续增长, 我有一个内存泄漏在我的手上,我需要解决它(详细说明如何-下面). 如果不是,不管实际堆大小如何,我都很好.

如果检测到内存泄漏,我将使用的下一个工具是对象分配跟踪器. 让我们看看它对安卓的内存管理能做些什么.

对象分配跟踪器

分配跟踪器, 简单地说, will provide you with the information required to figure out who’s the party to “blame” for the current heap size. This module will tell you from which threads 和 methods did the allocation comm和s came from in a real-time manner, 这对于安卓的内存分析来说是非常宝贵的.

要开始跟踪,请按以下步骤进行:

  • 如前所述,选择相关设备/工艺
  • 切换到“分配跟踪器”选项卡,单击“开始跟踪”开始.
  • 从现在开始,所有新的分配都会被跟踪
  • 点击“获取分配”以获取所有最新分配的列表视图(自上次“开始”以来的最新分配)
  • 要查找分配机构是谁,请单击列表中的特定行

摘要讨论中的对象分配跟踪器,用户界面

现在, 根据我自己的经验, performing allocation-intensive actions on your app followed by clicking “Get 所有ocations” to view allocation counters 应该 typically direct you to the leak in a straightforward manner; sometimes, 当泄漏是非线性的(例如.e.或者当你的应用包含多个可能无法工作的泄漏时. 在这种情况下, 而我并没有遇到过很多这样的人, 您将需要手动创建转储HPROF文件并对其进行分析. 本文不会深入讨论内存分析和安卓内存管理. 看到 在这里 对于一些线索.

线程信息控制台:安卓 CPU使用变得容易

任何开发人员都知道这一点, 执行逻辑的同步路径被分组成线程, 它们构成了应用程序中的一个串行执行流. 实际上,所有应用程序都使用不止一个执行线程. 有些人用几十个.

An overall examination of potential problems when using threads is way out of the scope of this article. 让我们把注意力集中在一个问题上, 即线程饥饿, 您访问线程信息控制台的主要问题是什么.

在所有的移动应用程序中,不同的线程会竞争CPU时间. 根本就没有足够的人手. 如果, 出于某种原因, 如果这些线程无法获得所需的执行时间,则使用一个或多个? 通常是坏事. 系统不会像你计划的那样运行,这总是一个坏主意. 这个问题的潜在原因可能是设置低优先级, 同时执行的其他线程将自己设置为过高的优先级, 在同步监视器上花费很长时间, 和更多的. 所有 出了名的 很难单独通过代码审查来检测.

安卓 摘要讨论线程控制台的救援!

摘要讨论中的线程信息控制台,用户界面

进入线程视图时, 您将看到一个由线程记录组成的列表, 每个包含线程的名称和ID, 还有两个额外的计数器,分别是utime和stime. Utime measures the total time spent by the thread executing user code (think your functions 和 third-party libraries), 而stime则度量花费在系统代码(睡眠)上的总时间, 同步, 系统调用- 很多). 第一次的一次性通常对我们来说更有趣, 尽管我能想到的问题大多会通过stime计数器显示出来.

OK, 我们的代码在运行, 包括几个线程, 我们希望确保所有的线程都能得到它们的CPU时间份额. 对于这个, 我们先让系统运行一段时间, 然后打开线程选项卡,开始查找“特殊的”utime值. 0当然表示问题——线程实际上没有CPU时间,也没有CPU利用率. 但过高的值可能代表了同一问题的不同方面:即, 优先级高到导致其他线程饿死的线程.

请注意,对于一种类型的线程,零或接近零的utime值并不表示存在真正的问题. 这些是I/O绑定线程,主要用于网络或磁盘(或数据库)访问. 这些线程 应该 将大部分时间花在等待数据到达或阻塞挂起的系统调用上, 这两种操作都不会增加utime计数器. 了解你的思路!

提示: 永远不要使用线程的默认名称. 它没有任何意义,您通常无法在摘要讨论视图中检测到它. 相反,无论何时创建线程或从线程池中获取线程,都应该通过 为其分配一个不言自明的名称. 这将使您的生活比调试/分析系统简单得多. I usually prepend the app’s name so to distinguish between 安卓 generated thread 和 those spawned by my own code, 例如:MyApp-server-connector, MyApp-db-interactor, 等.

提示: A thread’s priority denotes (loosely speaking) the amount of CPU time it will be granted by the scheduler. The priority assigned to your worker threads are of critical importance to the overall performance 和 “smoothness” of your app, 在许多情况下,这可能是光滑的快速行为和颠簸的缓慢行为之间的区别. 这里的规则很简单:安卓分配的默认优先级, 哪个是NORMAL=5, 几乎总是不是你想用的. 相反,对于大多数工作线程,您希望对总体CPU使用的影响较小. 要做到这一点,在线程启动时, 设置优先级 对于较小的值,我通常使用priority=3.

网络统计控制台

Network statistics is about allowing you to monitor both incoming 和 outgoing communication channels to your app in a reasonably human-readable manner.

网络图中的y轴表示传输的传输速度,单位为KB/秒, 而x轴表示以秒为单位的经过时间. 因此, 以获得对传输大小的快速估计, 试着估计一下相关尖峰的面积. 一段时间后,这变得相当容易.

请注意,, 进入这个控制台后, 您需要点击上方的“启用”按钮,网络测量才会开始出现.

在网络控制台成熟到现在的水平之前, developers usually had to resort to using sniffer apps (some still do) to obtain similar information.

The great thing about this console is the way it visualizes one of the major battery draining behaviors—that of ongoing small-packet size communication. 你们很多人都知道, what will make your app a battery drainer is not the five minutes of intensive networking that it does, 而是长时间的短暂, 重复组网.g.,用于保持活动、诊断或状态更新.

一旦检测到这种模式, 网络控制台的可视化数据包显示使其变得非常容易, 马上想 批处理. 我可以将多个小传输批处理成一个大传输吗? The battery impact of this change is bound to move apps from a battery-drainer to a well-behaved category!

摘要讨论中的网络统计控制台

提示: 永远不要将图像原样加载到内存中. 这是即将发生的内存不足崩溃. 相反,执行 缩小加载,或者用a更好 第三方库 为您管理缩放.

虽然你很少会用到这些信息, 请注意,摘要讨论依赖于安卓 Debug Bridge (ADB)堆栈来从设备传回数据. 如果摘要讨论无法显示您的应用程序, 或者在摘要讨论会话中间冻结, 你最好打开一个控制台,然后输入:

亚洲开发银行设备

以确保您的设备是可访问的,并与ADB授权. 如果不是这样的话, 在很多情况下, 重新启动本地ADB服务器应该可以解决问题:

亚行kill-server
Adb devices #重新启动Adb服务器并显示所有检测到的设备

如果你仍然有问题,并且你的应用安装在物理设备上, 尝试断开所有模拟器实例的连接. 为什么? 因为摘要讨论将自己连接到物理设备、设备和模拟器实例, 默认是后者.

现实生活中摘要讨论使用的例子: 应用程序停止(不是崩溃,只是停止). 用户立即赶往附近的工作站, 连接USB, 并在线程视图中打开摘要讨论以查找线程堆栈»失败线程»堆栈跟踪-在我的情况下, 由于同步死锁, 一旦检测到, 换一个就能解决吗.

提示: 如果安卓分配给应用程序的标准RAM内存不够,例如,e.g., 媒体密集型应用, 注意,在大多数设备上,通过提高_可以获得大约15-20%的额外内存largeHeap 舱单标志:http://developer.安卓.com/guide/topics/manifest/application-element.html_

安卓 摘要讨论中的设备状态仿真

一般来说,手机应用并不是线性结构. 而不是, they deploy awareness strategies that allow them to monitor 和 react to changes in the device’s state. 一个应用程序可以, 例如, 收听来电或短信, 能否根据网络状态重新调整其状态, 并且可以跟踪设备位置的变化并做出反应.

后者的一个小例子是GPS应用程序. 我们大多数人都不会开发这样的应用程序(唉, 市场还不够大…)但仍然, 在很多情况下, 我们部署逻辑, 这与位置有关, 无论是用户当前位置的简单地图视图, 路由跟踪, 或者位置敏感的数据显示.

对这种状态敏感条件的测试是出了名的复杂, 有时比编写实际代码更重要. 如果你有一个带有SIM卡的物理设备,你当然可以发出和接收电话和短信. 改变设备的通话状态要困难得多,但仍然可以做到. Test location changes could be trickier, though strolling around town with your laptop is an option…

但是,我们如何处理模拟器实例呢? 我们如何测试这些更改呢?

摘要讨论中的设备状态仿真示例

摘要讨论再一次拯救了我们. One of the stronger yet often overlooked features of the 摘要讨论 is its ability to issue (“spoof”) mock events into a running emulator instance. 摘要讨论可以从特定号码向模拟器发出呼叫, 发送短信, 更改电话状态数据, 和更多的.

一旦进入模拟器, 所有这些恶搞事件将不再与“真实”事件区分开来, i.e.,就像被底层硬件传感器接收到一样. 具体地说, all of your relevant app’s receivers will be activated in the same manner they would have upon receiving a real call/SMS message.

激活电话状态和动作相当简单:

To test your app for cases of low network connectivity (which you 应该 in any network-centered app) go to Telephony Status section 和 set the speed 和 latency values to the desired values. 我通常使用GPRS值作为模拟低连接的有效方法, 但你可以自由设定自己的价值观.

模拟电话或短信, 转到电话操作部分, 设置起始电话号码, 如果需要,可以添加文本信息, 然后开火. This tool is especially effective when you have set a dedicated code route for calls from abroad 和 want to test it on budget.

当涉及到嘲笑一个新地点时,事情变得更加有趣.

如果您的目标是为模拟器实例设置新位置, 选择手动, 设置所需的纬度/经度值, 点击发送.

摘要讨论中用于欺骗的手动位置控制

但是如果, 而不是设置一个固定的位置, 你希望你的应用程序通过一个预先设置的路线, 当用户从一个城市旅行到另一个城市时,检查它的行为? Such a test can have great value for any map-backed app as well as other location-sensitive apps which set their data window per user location. 在这里, you will want to see that location shifting at different speed will keep the displayed data window up to date.

对于这个, 我们将使用一种称为KML的特殊格式, 是专门为谷歌地球开发的吗, 代表路线, 或路径, 作为空间中相连点的集合, 可以通过启用GPS的设备进行定位吗.

GPX是摘要讨论支持的另一种路径格式. 为了所有实际目的, 当用于移动位置欺骗时,这两者应该被认为是可互换的.

现在让我们介绍一下在模拟器中设置模拟路由的各个阶段.

  1. 创建路由. By far the simplest way would be to use Google Maps direction option setting the appropriate origin 和 destination.

在摘要讨论与谷歌地图的位置欺骗

  1. 一旦路由显示在地图上,转到地址行并复制URL

  2. 带着剪贴板中的URL,转到 GPS可视化工具,粘贴到“提供URL”文本框中,点击转换按钮:

摘要讨论位置欺骗:GPS Wisualizer设置

并点击下载生成的GPX文件(有一个有点乱的名字).g., 20170520030103 - 22192的数据.gpx)

  1. 回到摘要讨论位置控制, 打开GPX选项卡, 单击Load GPX并选择新下载的文件

在摘要讨论位置控制中导入GPX

  1. 我们做完了! 现在,您可以通过单击后退和前进按钮在不同的路线位置之间导航, 或者通过点击播放按钮,以设定的速度自动通过路线.

您不需要创建自己的路由. 很多路线可以从OpenStreetMap等网站下载(参见 “GPS跟踪” 部分).

最后, 请注意,与旧的摘要讨论版本不同, 哪里的路由文件加载是一件轻而易举的事, 较新的版本在加载特定的路由时可能需要一些试验和错误.

例如,它只显示GPX 1.摘要讨论支持1. 新的GPX版本可能需要一些手动调整.

此外,GPX航点格式不再支持. 相反,使用GPX Track格式:


      
      
      
        
          0
          
        
      
   

调试安卓:一周一小时会有不同!

足够的理论! 现在是练习的时候了. 我建议,假设你是 安卓开发者,开始你的下一个项目,你会奉献 每周只要一小时 通过摘要讨论获得对应用程序性能的内省.

你会惊讶于数量 质量信息 (i.e., information which may be used to immediately improve the state of your app) this will provide you with!

安卓 摘要讨论, 就像我在新手开发者身上多次看到的那样, 一个工具能够极大地提高开发人员的能力吗, 只要它被掌握和正确使用. The ability of an 安卓开发者 to deliver top-notch systems will literally go up a notch or two once they tap the full potential of 摘要讨论 in 安卓 development. 因此, 留出几个小时好好利用摘要讨论听起来是个聪明的投资, 因为它可以大大提高安卓的性能和效率.

做一个聪明的人. 使用它.

了解基本知识

  • 摘要讨论在安卓中的用途是什么?

    作为安卓 Studio的一部分, 摘要讨论是安卓开发人员可用的最重要的自省工具之一. 它用于调试、诊断和分析.

  • 什么是安卓设备监视器?

    安卓 Device Monitor为多个调试工具提供了一个用户界面. 它很轻, 独立的工具, 因此用户不需要安装安卓 Studio或任何其他IDE.

  • 什么是安卓调试桥?

    安卓 Debug Bridge (adb) is a comm和 line tool designed to facilitate communication with an 安卓 device. 它用于调试、安装应用程序和访问Unix shell以在设备上运行命令.

  • 安卓设备管理器的用途是什么?

    ADM用于通过web控制台定位、呼叫或擦除您的设备.

  • 安卓中的Logcat是什么?

    Logcat是安卓应用程序和系统模块的内部日志系统.

聘请Toptal这方面的专家.
现在雇佣
吉拉德Haimov的头像
吉拉德Haimov

位于 特拉维夫-雅福,以色列

成员自 2015年7月27日

作者简介

Gilad拥有超过19年的安卓手机开发经验, 服务器端, 以及通信系统.

Toptalauthors are vetted experts in their fields 和 write on topics in which they have demonstrated experience. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

专业知识

以前在

bmc软件

世界级的文章,每周发一次.

<但ton class="_2bg14bwf _1Yko3Q2K _1SZtmxGM _2Yt-rhsd _1S6tHuDo" data-ga-category="bottom_sticky_bar" data-ga-event="cta_clicked" data-ga-label="Sign me up - Sticky - 0%" type="submit">帮我报名

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

<但ton class="_2bg14bwf _1Yko3Q2K _1SZtmxGM _2Yt-rhsd _1S6tHuDo" data-ga-category="bottom_sticky_bar" data-ga-event="cta_clicked" data-ga-label="Sign me up - Bottom - 0%" type="submit">帮我报名

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.