单例模式也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。本文就从单例模式的两种构建方式来带大家了解一下单例,最后介绍一种高级且简洁的单例模式。
单例听上去简单,但在 Java 里有不少容易踩坑的地方:双重检查锁要不要 volatile、静态内部类持有的初始化时机、用枚举实现单例为什么天然防反射和防序列化。本文会按”懒汉/饿汉的常规写法 → 双重检查锁 → 静态内部类 → 枚举”的顺序,把每种实现的适用场景和坑点串起来讲一遍。
单例模式也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。本文就从单例模式的两种构建方式来带大家了解一下单例,最后介绍一种高级且简洁的单例模式。
单例听上去简单,但在 Java 里有不少容易踩坑的地方:双重检查锁要不要 volatile、静态内部类持有的初始化时机、用枚举实现单例为什么天然防反射和防序列化。本文会按”懒汉/饿汉的常规写法 → 双重检查锁 → 静态内部类 → 枚举”的顺序,把每种实现的适用场景和坑点串起来讲一遍。
系列文章目录:
“If you can measure it, you can optimize it” is a common term in the computing world, and for Android’s rendering system, the same thing holds true. In order to optimize your pipeline to be more efficient for rendering, you need a tool to give you feedback on where the current perf problems lie.
And in this video, +Colt McAnlis walks you through an on-device tool that’s built for this exact reason. “Profile GPU Rendering” will help you understand the stages of the rendering pipeline, and also get a chance to see what portions of it might be taking too long, and what you can do about it for your application.
渲染性能问题往往是偷取你宝贵帧数的罪魁祸首,这种问题很容易产生,很容易出现,而且在一个非常方便的工具的帮助下,也非常容易去追踪. 使用Peofile GPU Rendering tool,你可以在手机上就可以看到究竟是什么导致你的应用程序出现卡顿,变慢的情况.
系列文章目录:
Unbeknown to most developers, there’s a simple hardware design that defines everything about how fast your application can draw things to the screen.
You may have heard the term VSYNC - VSYNC stands for vertical synchronization and it’s an event that happens every time your screen starts to refresh the content it wants to show you.
Effectively, VSYNC is the product of two components Refresh Rate (how fast the hardware can refresh the screen), and Frames Per Second (how fast the GPU can draw images), and in this video +Colt McAnlis walks through each of these topics, and discusses where VSYNC (and the 16ms rendering barrier) comes from, and why it’s critical to understand if you want a silky smooth application.
想要开发一个高性能的应用程序,首先你得了解他的硬件工作原理,那么最好的办法就是去使用它,应用程序运行速度的快慢,很容易被人误解为硬件进程的控制问题,然而这最主要的根源在于渲染性能.如果你想要提高你应用程序的渲染性能,你就必须知道什么是VSYNC.
系列文章目录:
One of the most problematic performance problems on Android is the easiest to create; thankfully, it’s also easy to fix.
OVERDRAW is a term used to describe how many times a pixel has been re-drawn in a single frame of rendering. It’s a troublesome issue, because in most cases, pixels that are overdrawn do not end up contributing to the final rendered image. As such, it amounts to wasted work for your GPU and CPU.
Fixing overdraw has everything to do with using the available on-device tools, like Show GPU Overdraw, and then adjusting your view hierarchy in order to reduce areas where it may be occurring.
视频开头作者举了一个例子,说如果你是一个粉刷匠,你应该会知道,给墙壁粉刷是一件工作量非常大的工作,而且如果你需要重新粉刷一遍的话(比如对颜色不满意),那么第一次的粉刷就白干了. 同样的道理,如果你的应用程序中出现了过度绘制问题,那么你之前所做的事情也就白费了.如果你想兼顾高性能和完美的设计,那么你的程序可能会出现一个性能问题:OverDraw!
OverDraw是一个术语, 它表示某些组件在屏幕上的一个像素点的绘制超过1次.如下面的图所示,我们有一堆重叠的卡片,被用户激活的卡片在最上面,而那些没有激活的卡片在下面,这意味着我们画大力气绘制的那些卡片,基本都是不可见的.问题就在于次,我们像素渲染的并不全是用户最后能看打的部分, 这是在浪费GPU的时间!
系列文章目录:
Rendering performance is all about how fast you can draw your activity, and get it updated on the screen. Success here means your users feeling like your application is smooth and responsive, which means that you’ve got to get all your logic completed, and all your rendering done in 16ms or less, each and every frame. But that might be a bit more difficult than you think.
In this video, +Colt McAnlis takes a look at what “rendering performance” means to developers, alongside some of the most common pitfalls that are ran into; and let’s not forget the important stuff: the tools that help you track down, and fix these issues before they become large problems.
当你觉得自己开发了一个改变世界的应用的时候,你的用户可能并不会这么认为,他们认为你的应用又慢又卡,达不到他们所期望的那种顺滑,更谈不上改变这该死的世界了,回收站走你!等等!明明我这个应用在我的Nexus5上非常顺滑啊?你咋能说又慢又卡呢?如果你对Android的碎片化有一定了解的话,你就应该知道,很多低配置的手机并不像Nexus5那样有强大的处理器和GPU,以及没有被怎么污染的原生系统。
如果有大量的用户投诉说你的应用又卡又慢的时候,不要总是抱怨用户的低端手机,有时候问题就出在你的应用本身,也就意味着你的Android存在比较严重的渲染性能问题。只有真正了解问题发生的根源,才能有效的解决问题。所以了解Android渲染相关的知识,是一个Android开发者必不可少的知识。
系列文章目录:
2015年1月6日,Google官方发布了一系列关于Android性能优化的小视频,将其命名为Android Performance Patterns,这一些列视频放在YouTube上,观看的话需要科学地上网。

现在回看这组视频,需要把“渲染机制”和“工具入口”分开理解。16ms 帧预算、过度绘制、VSYNC、主线程/渲染线程协作这些机制仍然是图形性能的基础;但当年配套使用的 Hierarchy Viewer、TraceView、Android Device Monitor、Google+ 社群已经不是今天的主线。现在应该用 Layout Inspector/Compose Layout Inspector 看 View 或 Compose 层级,用 Profile GPU Rendering 和 Debug GPU Overdraw 做快速可视化,用 Perfetto Frame Timeline/System Trace 看真实帧生命周期、SurfaceFlinger、CPU 调度和 Binder 关系,用 Macrobenchmark FrameTimingMetric 把滑动/页面切换场景固化成可回归测试。
官方简介:
Android Performance Patterns is a collection of videos focused entirely on helping developers write faster, more performant Android Applications. On one side, it’s about peeling back the layers of the Android System, and exposing how things are working under the hood. On the other side, it’s about teaching you how the tools work, and what to look for in order to extract the right perf out of your app.
But at the end of the day, Android Performance Patterns is all giving you the right resources, at the right time to help make the fastest, smoothest, most awesome experience for your users. And that’s the whole point, right?
总之就是一系列讲解Android性能相关的视频。这些小视频的时间非常短,在3-5分钟之内,主讲人的英文语速也非常快,初期这些视频没有翻译的时候,着实考验了一把听力。好消息是现在这些视频已经都有中英文字幕了。
这些视频的时间虽然很短,但是信息量却非常大,有些他一句话带过的内容,我们却需要花费很多的时间去研究他的原理,或者研究一个调试工具如何使用。也就是说,这一系列视频并没有真正教你如何去优化你的应用,而是告诉你关于Android性能优化你需要知道的知识,这样你去优化你的Android应用的时候,知道该用什么工具,该采取什么样的步骤,需要达到什么样的目标。
本文是 MAT 工具使用系列的第二篇,这个系列共三篇,详细介绍了如何使用 MAT 来分析内存问题,既可以是 Java 应用的内存问题,也可以是 Android 应用的内存问题:
本文介绍的是从 MAT 里手工还原 Bitmap 原图的旧排查技巧,适合在离线 heap 里确认“到底是哪张图”被错误持有。现在排查图片内存问题时,第一步通常不是直接打开 MAT,而是先用 Android Studio Memory Profiler 的 heap dump/retained size/reference 视图确认 Bitmap、BitmapDrawable 或图片缓存的持有链;如果问题涉及 Native Bitmap、纹理、图片库缓存或系统内存压力,还需要结合 dumpsys meminfo、Perfetto/native heap profiling、图片库自身缓存统计一起判断。MAT 仍然可以作为最后的离线取证工具,而不是默认入口。
在使用MAT查看应用程序内存使用情况的时候,我们经常会碰到Bitmap对象以及BitmapDrawable$BitmapState对象,而且在内存使用上,Bitmap所占用的内存占大多数.在这样的情况下, Bitmap所造成的内存泄露尤其严重, 需要及时发现并且及时处理.在这样的需求下, 当我们在MAT中发现和图片相关的内存泄露的时候, 如果能知道是那一张图片,对分析问题会有很大的帮助.
本文就介绍如何将MAT中的Bitmap数组对象还原成一张图片。
本文是 MAT 工具使用系列的第二篇,这个系列共三篇,详细介绍了如何使用 MAT 来分析内存问题,既可以是 Java 应用的内存问题,也可以是 Android 应用的内存问题:
本文的 Histogram、Dominator Tree、Thread 信息仍然是 heap 分析的核心方法,但抓取和第一轮分析入口应换成现在的工具链:先用 Android Studio Memory Profiler 捕获 heap dump,必要时在关键点调用 Debug.dumpHprofData(),再用 Profiler 的 retained size、reference 和 Activity/Fragment leak 过滤做初筛;如果要离线做大文件分析,再导出 .hprof 并按需用 hprof-conv 转给 MAT。对于线上或自动化场景,LeakCanary 更适合做泄漏发现,dumpsys meminfo/Perfetto/native allocation recording 更适合补齐 Java heap 之外的内存证据。
Android Studio的最新版本可以直接获取hprof文件:

本文是 MAT 工具使用系列的第一篇,这个系列共三篇,详细介绍了如何使用 MAT 来分析内存问题,既可以是 Java 应用的内存问题,也可以是 Android 应用的内存问题:
这组文章里的 MAT 技巧仍然适合学习 Java heap、Dominator Tree、Retained Size、引用链这些基础概念,但默认抓取流程已经变了。早期流程是 Eclipse/DDMS 导出 Android HPROF,再用 hprof-conv 转成 MAT 能读的格式;现在应优先在 Android Studio Memory Profiler 里直接 Capture heap dump,先用 Android Studio 的 class/package、retained size、reference 视图定位,再在需要离线处理大 HPROF 或做更复杂 Dominator Tree 分析时导出给 MAT。泄漏检测优先接入 LeakCanary,系统/Native 内存问题则要结合 dumpsys meminfo、Android Studio native allocation recording 或 Perfetto native heap profiling,而不是只看 MAT。
MAT(Memory Analyzer Tool),一个基于 Eclipse 的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

当然MAT也有独立的不依赖Eclipse的版本,只不过这个版本在调试Android内存的时候,需要将DDMS生成的文件进行转换,才可以在独立版本的MAT上打开。不过Android SDK中已经提供了这个Tools,所以使用起来也是很方便的。
本文是一篇译文,原文Android Performance Case Study Follow-up的作者是大名鼎鼎的Romain Guy。本文讲述了Android性能优化的一些技巧、方法和工具。
两年前,我发表了一篇名为Android Performance Case Study 的文章,来帮助Android开发者了解需要使用什么工具和技术手段来确定、追踪和优化性能问题。
那篇文章以一个Twitter客户端 Falcon Pro为典范,其开发人员为 Joaquim Vergès. Joaquim人不错,他允许我在我的文章中使用它的程序作为例子,并且快速处理了我发现的所有问题。一切都OK,直到Joaquim 从头开始开发Falcon Pro 3,前不久在他准备发布它的新应用的时候,他联系了我,因为他有一个和滚动相关的性能问题需要我来帮助他,这一次我依然没有源代码可以参考。
本文是一篇译文,这篇是这个系列的第四篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.
第四篇集中讲两类东西:一类是被 XML 属性藏起来的特性,android:weightSum、android:duplicateParentState、android:clipChildren、android:fillViewport、android:tileMode、android:scaleType 这些点一上手就能直接省一段自定义 View 的代码;另一类是 SDK 里靠搜文档才能发现的工具,Activity.isChangingConfigurations 区分配置变化导致的销毁、ViewTreeObserver 监听布局节点变化、DatabaseUtils 处理 Cursor 与 ContentValues、AtomicFile 保证文件读写原子性、Layout 里的 <merge> 节省层级。
这篇是 2015 年的 Systrace 工具介绍,里面提到的 Eclipse、Device Monitor、sdk/tools/systrace、User 版本不能抓 Trace 等流程,已经不适合作为今天的默认操作路径。旧文章保留的是 Systrace 的基本概念:它为什么能把 SurfaceFlinger、WindowManager、View、CPU 调度等系统行为放到一张时间线上。今天真正抓取和分析 Trace,应优先看 Android Perfetto 系列目录。
现在的工具流程可以直接按下面理解:
| 旧流程 | 新流程 |
|---|---|
| Eclipse / Android Studio Device Monitor 里点 Systrace | 开发者选项里打开 System Tracing,或使用 adb shell perfetto |
python systrace.py --time=10 -o trace.html ... |
adb shell perfetto -t 10s -b 64mb ... --out /data/misc/perfetto-traces/trace.perfetto-trace |
| 输出 HTML,用 Chrome 打开 | 输出 .perfetto-trace,用 Perfetto UI 或 trace_processor 打开 |
| 主要靠肉眼在 HTML 里缩放和点击 | 先看轨道和 Slice,再结合搜索、SQL、metrics 做证据收敛 |
| User 版本基本不可用 | User 版本可以先抓有限信息;系统级细节仍建议 Userdebug/eng |
本文是Android性能优化工具系列的第一篇,这个系列主要介绍Android性能优化过程中会使用到的一些工具,以及如何用这些工具来发现问题和解决问题。在性能优化方面,Android有不少性能工具供大家来使用,按照我们一贯地 “发现问题-解决问题”的思路来看,发现问题才是最主要的,一上来就想着如何去解决问题,反而会事倍功半。
这一篇先来简单介绍一下Systrace这个工具。
Systrace是Android4.1中新增的性能数据采样和分析工具。它可帮助开发者收集Android关键子系统(如surfaceflinger、WindowManagerService等Framework部分关键模块、服务,View系统等)的运行信息,从而帮助开发者更直观的分析系统瓶颈,改进性能。
Systrace的功能包括跟踪系统的I/O操作、内核工作队列、CPU负载以及Android各个子系统的运行状况等。在Android平台中,它主要由3部分组成:
博客有一段时间没有更新了,到了新公司后,一直比较忙,博客也更新地不那么频繁了。最近一直在看Android上和性能相关的部分,也就是所谓的Android性能优化,才发现Android性能这一块,自己懂得还是太少了,所以从上层开始看,也算是一点一点入门吧。这个系列将讲解学习过程中总结的和性能相关的内容。
首先将讲解一下GPU过渡绘制,也是开发者最直接接触的部分吧,这个内容将分为两个部分来将讲,第一部分初步讲解一下gpu过渡绘制的原理,和一些优化建议,第二部分将用实际例子来讲解优化GPU过渡绘制的一般步骤。
GPU过渡绘制的概念:GPU过度绘制指的是在屏幕一个像素上绘制多次(超过一次),比如一个TextView后有背景,那么显示文本的像素至少绘了两次,一次是背景,一次是文本。GPU过度绘制或多或少对性能有些影响,设备的内存带宽是有限的,当过度绘制导致应用需要更多的带宽(超过了可用带宽)的时候性能就会降低。带宽的限制每个设备都可能是不一样的。
本文是一篇译文,这篇是这个系列的第二篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.
第二篇里挑出来的 API 大多是工具级别的:DateUtils.formatDateTime 直接帮你按系统区域格式化日期、Formatter.formatFileSize 处理文件大小的本地化显示、AlarmManager.setInexactRepeating 用粗略间隔合并闹钟事件来省电;UI 侧有 StaticLayout 自己控制文字测量、ViewStub 延迟 inflate、GestureDetector 拼装常见手势;还有 Linkify 自动识别文本里的链接、ActivityManager.getMemoryClass 判断当前进程内存上限、Pair.create 这种小到容易忘的工具。
本文是一篇译文,这篇是这个系列的第一篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.
第一篇里挑出来的都是 SDK 里早就存在但容易被忽略的小工具:批量启动 Activity 的 startActivities、统一手势识别阈值的 ViewConfiguration、写 Adapter 几乎一定用得到的 LayoutInflater.from,还有 Space、ContextThemeWrapper、ArgbEvaluator 这种很少被介绍但用上一次就忘不掉的类。下面正文按 API 逐条列出,每条都带官方文档链接和简短的使用建议。
这篇文章最早是在我的CSDN博客上面发布了:http://blog.csdn.net/grackergao/article/details/18322749 .现在讲他转移到了这里,代码的Github地址 :https://github.com/Gracker/Android-Utils/blob/master/Log2File.java
上一篇文章介绍了什么是Accessibility以及简单的使用,这一篇文章就来讲讲如何使用Accessibility服务来创建一个简单的Android通知中心。Android中通知中心是一个系统层面的服务,负责显示应用和系统发来的通知(Notification,比如USB插入、选择输入法、未接来电、截图、天气信息、新闻推送等等)。在android4.3之前,一般的第三方应用是无法获取Notification list的(在Android4.3之后,有了一个新的接口,NotificationListenerService.getActiveNotifications(),可以获取当前的Notification)。但是利用Accessibility服务可以监听到各种事件的特性,可以开发一个第三方的通知中心,实现与系统通知栏类似的功能。
最近开发Nokia项目,遇到的问题如下:
插入Nokia x后,电脑没有反应,即不识别,同事的windows也不识别,最后在谷歌上搜索了良久,才找到了解决方案,但是没有记录,后来又要给别人配置的时候,发现忘记怎么配置了。想想这也是一个具有通性的问题,还是记录下来,分享给大家。
首先问题是:执行adb命令提示找不到设备,在做其他操作之前,请先确认已经做了如下操作:
辅助性服务是安卓框架的一个特性,它的设计是为了让已经安装在安卓设备上的应用程序能够为用户提供一种导航式(引导式)回应。一个辅助性服务能够传达给
用户关于这个应用程序的利益,例如把文本转换成语音、当用户手指停留屏幕的一个重要区域时的haptic反馈。这一节涵盖了怎样去创建一个辅助性服务,如何处理应用程序的信息接收,还有如何把信息反馈给用户。
创建自己的辅助性服务
本文先把辅助性服务的设计目标和能力边界讲清楚,包括它能拿到的事件类型、能反馈给用户的渠道,以及它和普通 Service、IntentService 的区别。后半部分会动手写一个最小可用的辅助性服务,覆盖继承 AccessibilityService、在 manifest 里声明、配置 service 元数据,以及响应 AccessibilityEvent 这四步,按顺序走一遍就能跑起来。