在发布之前优化Android应用程序

时间:2011-04-11 20:10:42

标签: java android optimization

我处于关于程序效率的“特殊”情况。现在我处于需要提高应用程序性能并减少电池消耗的阶段。

在提问之前:

现在,我很想知道其他开发人员用于优化自己应用程序的特殊修复程序。用户可能永远不会识别或注意的东西。但是,修复将延长电池寿命或帮助改善应用程序的维护。

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

我处在一个特殊的情况,我正在寻找知识,我认为这将是一个很好的机会,可以分享开发人员对他们所处过的情况的了解。

请投票给出好的答案,因为这会鼓励优秀的开发者分享他们的知识。

14 个答案:

答案 0 :(得分:66)

在某些时候,你将会达到使用已知技巧将达到极限的程度。此时要做的最好的事情是根据您的具体要求描述您的代码并查看瓶颈区域。

Investigating RAM usage using MATUsing Traceview:有关如何使用这些工具分析您的应用的文章。

答案 1 :(得分:37)

跟踪和挤压分配。您分配的越多,垃圾收集器运行所需的频率就越高,阻止您的进程在相对较长的时间内执行任何其他操作,例如100毫秒左右。

我所知道的最佳工具是DDMS中包含的分配跟踪器。

不仅GC会对用户体验产生影响,而且多余的分配和GC会消耗一些计算资源。

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

有很多这样的人。这是我的应用程序包含50%本机代码的原因之一(但还有其他原因)。

除此之外,我建议您尝试使用ProGuard。它执行多次优化传递,并在项目中记录诸如未使用方法之类的信息,这可以帮助您删除代码中的剩余内容。

答案 2 :(得分:21)

如果您的应用有大量的屏幕时间,可以在任何地方使用黑色。这将减少设备最糟糕部分的电池消耗:屏幕,特别是AMOLED手机和平板电脑。

答案 3 :(得分:16)

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

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

adb shell dumpsys meminfo 'your apps package name'

答案 4 :(得分:14)

使用SQLite时,要特别注意索引。不要假设任何事情。当我将索引放在常用于搜索的列上时,我在Zwitscher中获得了极大的加速。

答案 5 :(得分:13)

一些可以帮助您根据 UI 优化应用的提示:

  • 对列表适配器使用convertView - 如果在Adapter.getView()内创建新视图,则会非常昂贵,因为此例程会针对列表中的每个位置进行调用。使用convertView可以重用已创建的视图。在ApiDemos中可以找到好的示例(以及ViewHolder的使用)。

  • 可能会发生您的布局未完全优化且可以改进(例如,通过使用合并或删除父项)。 Android工具layoutopt会为您找到这样的情况。它可以与HierarchyViewer一起用于检查各个视图。更多信息here

  • 删除背景drawable - 以前的Android框架(它还有吗?)a problem,检测应该绘制哪些视图。您的(默认)背景绘制可能只会被随后的不透明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

答案 6 :(得分:9)

要考虑的事情:不要过度使用String,例如在一个巨大的循环中。 这将创建许多必须进行GC的String对象。 “错误编码”示例将在每个循环中生成2个字符串对象。下一个示例将只生成一个最终String和一个stringbuilder。这在为速度优化大循环时会产生巨大的差异。在制作我的Wordlist Pro Android应用程序时,我经常使用stringbuilder,并且在快速浏览270000个单词时速度非常快。

    //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);
    }

我写了一篇关于此事的更广泛的博文。 read here

答案 7 :(得分:6)

我想在任何地方使用“最终”变量都可以提高执行速度。

答案 8 :(得分:6)

使用OptiPNGPNGCrush等工具优化您的PNG图片,以便从APK尺寸中削减一些(千字节)字节。网站的图像优化技巧也适用于此:使用适当的图片格式,使用JPG压缩,考虑使用二进制透明度而不是8位透明度等。

如果您发送带有Alpha通道的大型PNG,则可以将一些APK大小用于启动速度和use separate JPGs for RGB and A channels

如果您正在建立HTTP连接,请检查您的HTTP客户端是否使用内容压缩。如果它缓存收到的HTTP响应,请检查它是否理解并正确使用与缓存相关的HTTP头。

答案 9 :(得分:5)

如果您有网络操作,请尝试重新使用相同的httpclient实例。避免使用正则表达式。

答案 10 :(得分:5)

尝试使用DDMS跟踪系统中运行的所有线程。例如,我注意到我使用webview来显示html内容,我注意到它为cookie管理会话管理等创建了很少的线程。这增加了我的内存占用量。因此,除非你非常需要显示复杂的html尝试在android中使用普通的实用程序类“Html”来显示html内容。这可能对显示Eula的人有用,因为eula typicall包含html文本。

如果你必须做网络操作,如果你是初学者,请尝试使用AndroidHttpClient,它有一些很好的缓存SSL会话功能,所有这些都有助于提高你的性能。始终将套接字连接超时设置为大约60秒或某些有限值,因为无限超时会导致死锁,尤其是在ssl握手期间断开连接时。

答案 11 :(得分:4)

使用Android Resource Tracker查找项目中可以删除的未使用资源。

答案 12 :(得分:4)

如果您可以使用字符串操作例程来解析XML输入以获取标记之间的文本,请避免使用XPath。在HTC Desire的50000项数据集中,我已经过测试并确认了这种情况下的10倍改进。

答案 13 :(得分:3)

我知道我稍后会加入这个对话但是在一个地方有很多好的提示是完美的,所以我希望这个帖子能够活着并经常更新。我的提示:

  • 不要使用昂贵的作业阻止UI线程,如果应用程序没有响应,用户将离开 (使用AsyncThreads)。
  • 使用the LINT新工具扫描Android项目源以查找潜在错误。

..将会更新..