发布前优化Android应用程序

120

我在关于程序效率的"特殊"情况下。现在我需要改进应用程序性能并减少电池消耗

在提问之前:

现在,我想知道其他开发人员采用的特殊解决方案,以优化他们自己的应用程序。这些用户可能永远不会注意或关注,但修复程序将增加电池寿命或帮助改进应用程序的维护。

那么,你的独特优化技巧是什么?

我处于一个非常渴望知识的特定情况下,我认为这将是分享开发人员在其中所遇到的情况的知识的绝佳机会。

请投票支持出色的答案,因为这将鼓励出色的开发人员分享他们的知识。


2
由于效率最终归结为不做任何你不需要做的事情(或者比你需要做的更频繁),我认为很多事情都取决于你的应用程序需要完成什么类型的任务... 如果没有具体说明,你只能得到一些“常见嫌疑人”的集合。 - Chris Stratton
1
@Chris Stratton:嗯,你是对的。但是,“惯用的嫌疑犯”或者一个关于特定技巧的简短回答会让其他人更容易决定是否这个“猜测”就是他们正在寻找的(以及它是否对他们的具体情况有用)。 - Wroclai
这个网站上有很多非常有趣的问题被关闭,真是荒谬。 - Patrick
阅读此博客文章 https://medium.com/@hammad_tariq/android-application-performance-improvement-tips-c4ec4d045d6d - Developine
14个回答

68

在某个时候,你会发现使用已知的技巧已经达到了极限。此时最好的方法是对你的代码进行分析,看哪些区域是根据你的具体要求的瓶颈。

使用MAT调查RAM使用情况使用Traceview: 一篇关于如何使用工具来分析你的应用程序的文章。


谢谢!我真的很喜欢带有资源的答案。 :-) - Wroclai
1
阅读此博客文章。https://medium.com/@hammad_tariq/android-application-performance-improvement-tips-c4ec4d045d6d - Developine

37

追踪和清除分配。你分配的越多,垃圾收集器就需要更频繁地运行,导致你的进程在相对较长的时间内停止做任何其他事情,例如100毫秒左右。

我知道的最好的工具是包含在DDMS中的Allocation Tracker。

不仅仅是GC会影响用户体验,过多的分配和GC也会消耗一些计算资源。

这里有一个例子和一个小技巧。在我的应用程序中,我有一个时钟显示当前(音频)时间,包括十分之一秒。这经常更新。当您使用CharSequence调用setText()时,TextView内部会执行分配,但是当您使用setText(char[] text, int start, int len)变量时,它不会分配任何内容。这并没有记录在文档中,当我询问时也没有人回答。

还有很多类似的情况。这就是为什么我的应用程序包含50%本机代码的原因之一(但还有其他原因)。

除此之外,我建议您尝试使用ProGuard进行实验。它执行几个优化步骤,并记录项目中未使用的方法等信息,这可以帮助您在代码中删除剩余部分。


1
很棒的回答!具体的技巧受到赞赏。 - Wroclai

22

如果你的应用程序将具有很长的屏幕使用时间,尽可能使用黑色。这将减少设备最耗电的部分-屏幕的能量消耗,特别是在AMOLED手机和平板电脑上。


明智地使用暗色调可以为电池带来胜利。 - Robert Massaioli
7
另一方面,在LCD屏幕上,黑色比白色消耗更多功率,因为光线(来自背光源)最初是白色的,必须积极地被封锁才能产生黑色。底线:不要过分依赖这种颜色优化。 - Sparky

16

对于具有多个活动的应用程序,请检查您是否正在重新启动只需要使用适当的Intent标志将其带到前台的活动。检查您的堆是否受控制,并且不要创建不必要的视图、绑定和上下文。

我发现最好的工具是在应用程序运行时显示所有这些内容:

adb shell dumpsys meminfo 'your apps package name'

1
哦,这是新的。谢谢分享! - Wroclai

15

在使用SQLite时,要特别注意索引。不要做任何假设。当我为Zwitscher的常用搜索列建立索引时,我获得了巨大的加速。


13
一些有助于优化应用程序的UI的提示:
  • 在列表适配器中使用convertView - 如果您在Adapter.getView()内部创建新视图,则非常昂贵,因为此例程会针对列表中的每个位置调用。使用convertView允许您重用已经创建的视图。示例(以及使用ViewHolder)可以在ApiDemos中找到。

  • 可能会出现您的布局未完全优化并且可以改进的情况(例如通过合并或删除父级)。 Android工具layoutopt将为您找到这种情况。它可以与HierarchyViewer一起使用来检查单个视图。更多信息在此处

  • 删除背景drawable - Android框架曾经(现在还有吗?)存在问题,无法检测哪些视图应该绘制。你的(默认)背景drawable有可能只是为了随后被不透明的UI隐藏而被绘制。为了摆脱这种浪费的绘图,只需删除背景drawable。

可以使用自定义样式来完成。

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>

以下是一些可以帮助您在电池使用方面优化应用程序的小技巧:

  • 检查网络类型,并等待用户进入具有WiFi或3G(且未漫游)的区域,然后才允许其使用连接

  • 尽可能地使用gzip来加快文本数据的下载和解析速度

  • 回收复杂的Java对象,如XmlPullParserFactory/BitmapFactory/StringBuilder/Matcher

更多电池技巧请参见Coding for Life - Battery Life, That Is


如何回收复杂的Java对象?虽然Java有垃圾回收机制,但是如何处理复杂的对象呢? - Yousha Aleayoub

9

有些需要考虑的事情:不要在大循环中过度使用String。 这将创建许多必须被回收的字符串对象。 “糟糕的编码”示例将在每个循环中产生2个字符串对象。下一个示例将仅生成一个最终的字符串和一个单一的stringbuilder。这在优化速度较慢的大型循环时会产生巨大的差异。当我制作Wordlist Pro Android应用程序时,我经常使用stringbuilder,在短时间内处理了27万个单词,速度非常快。

    //Bad coding:
    String s = "";
    for(int i=0;i<999999;i++){
        s = "Number=";
        s = s + i;
        System.out.println(s);
    }

    //Better coding
    final String txt = "Number=";
    StringBuilder sb = new StringBuilder();
    for(int i=0;i < 999999;i++){
        sb.setLength(0);
        sb.append(txt);
        sb.append(i);
        System.out.println(sb);
    }

我写了一篇更详细的关于这个问题的博客文章。 阅读此处


6
我认为在可能的情况下,到处使用“final”变量也可以提高执行速度。

1
我记得在某个地方看到过这个,你能提供一个链接吗? - Wesley Wiser
1
不太确定对于最终变量是否正确,但对于静态最终变量可能是正确的 - 请参见https://dev59.com/rnA75IYBdhLWcg3wxcDV#3117832 - Alistair Collins
无法提供链接,但我在Reto Meier的《Android入门指南》(2010年5月19日)/Google IO中看到了一份通知。这是一个简短的免费下载资源,并提供了有关如何构建好应用程序的良好建议。 - Stan
2
最终变量可以使代码更加高效,因为这意味着所有对象将在同一运行中被垃圾回收。而不是根据您设置它们为null的时间而在不同的时间进行回收。 - Robert Massaioli
1
问题:编译器不是会明确地为你做这件事吗?我认为它应该在其代码分析阶段完成。 - Pawan

6
使用类似于OptiPNGPNGCrush的工具来优化PNG图片,可以从APK大小中删减一些(千)字节。网站的图像优化技巧也适用于此处:使用适当的图片格式,尝试JPG压缩,考虑使用二进制透明度而非8位透明度等。
如果您在使用带有Alpha通道的大型PNG文件,则可以通过使用单独的JPG文件来处理RGB和A通道来交换一些APK大小以获得启动速度。
如果您正在进行HTTP连接,请检查您的HTTP客户端是否利用内容压缩。如果它缓存接收到的HTTP响应,请检查它是否正确理解并使用与缓存相关的HTTP头。

谢谢您的见解!我从未听说过这个! - Wroclai

5
如果您有网络操作,请尝试重复使用同一个httpclient实例。避免使用正则表达式。

原因是什么?你能解释一下为什么吗? - Yousha Aleayoub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接