【问题标题】:Optimising Android application before release [closed]在发布前优化 Android 应用程序 [关闭]
【发布时间】:2011-08-03 08:57:18
【问题描述】:

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

提问前:

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

那么,您有什么独特的优化技巧?

我正处于一种特殊情况,我真的在寻找知识,我认为这将是一个很好的机会,可以让开发人员分享他们所经历的情况的知识。

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

【问题讨论】:

  • 因为效率最终归结为不做任何你不需要做的事情(或者比你需要做的事情更多)我认为很大程度上取决于你的应用程序必须完成的事情类型。 .. 如果不指定,您所能做的就是收集“通常的嫌疑人”
  • @Chris Stratton:嗯,你是对的。而且,“通常的嫌疑人”或对特定技巧的一点回答将使其他人更容易做出决定,如果“猜测”是他们正在寻找的东西(并且它是否对他们的特定情况有用)。
  • 荒谬的是,有多少真正有趣的问题在这个网站上被关闭了。
  • 阅读这篇博文medium.com/@hammad_tariq/…

标签: java android optimization


【解决方案1】:

在某些时候,您将达到使用已知技巧将达到极限的地步。此时最好的做法是分析您的代码,并根据您的具体要求查看哪些区域存在瓶颈。

Investigating RAM usage using MATUsing Traceview:一篇关于如何使用这些工具来分析您的应用程序的文章。

【讨论】:

【解决方案2】:

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

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

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

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

这样的有很多。这也是我的应用包含 50% 原生代码的原因之一(但还有其他原因)。

除此之外,我建议您尝试使用ProGuard。它会执行多个优化过程,并将此类信息记录为项目中未使用的方法,这可以帮助您删除代码中的剩余部分。

【讨论】:

  • 很好的答案!具体技巧值得赞赏。
【解决方案3】:

如果您的应用会占用大量屏幕时间,请尽可能使用黑色。这将减少设备最糟糕部分的电池消耗:屏幕,特别是 AMOLED 手机和平板电脑。

【讨论】:

  • 明智地使用深色意味着电池的胜利。
  • 另一方面,在 LCD 屏幕上,黑色比白色消耗更多的能量,因为光(来自背光源)一开始是白色的,必须主动阻挡才能产生黑色。 [ scientificamerican.com/article.cfm?id=fact-or-fiction-black-is ] 底线:不要太指望这种颜色优化。
【解决方案4】:

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

我发现在应用运行时向您展示所有这些的最佳工具是:

adb shell dumpsys meminfo 'your apps package name'

【讨论】:

  • 哦,那是新的。感谢分享!
【解决方案5】:

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

【讨论】:

    【解决方案6】:

    一些可以帮助您在UI方面优化应用的提示:

    • convertView 用于列表适配器——如果在Adapter.getView() 中创建一个新视图会非常昂贵,因为该例程会为列表中的每个位置调用。使用convertView 可以让您重用已创建的视图。很好的例子(连同ViewHolder的使用)可以在ApiDemos中找到。

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

    • 删除背景可绘制对象 - Android 框架曾经拥有(现在还有吗?)problem,用于检测应该绘制哪些视图。您的(默认)背景可绘制对象有可能被绘制,随后被您的不透明 UI 隐藏。要摆脱这种浪费的绘图,只需删除背景可绘制对象。

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

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

    一些提示可以帮助您在电池使用方面优化您的应用:

    • 检查网络类型并等待用户进入有 wifi 或 3G 的区域(而不是漫游),然后才允许他使用连接

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

    • 回收XmlPullParserFactory/BitmapFactory/StringBuilder/Matcher等复杂的java对象

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

    【讨论】:

    • "回收复杂的java对象,例如..." 怎么样?而Java有GC
    【解决方案7】:

    需要考虑的一点:不要过度使用字符串,例如在一个巨大的循环中。 这将创建许多必须进行 GC 处理的 String 对象。 “错误编码”示例将在每个循环中生成 2 个字符串对象。下一个示例将只生成一个最终字符串和一个字符串生成器。在优化大型循环以提高速度时,这会产生巨大的差异。在制作我的 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

    【讨论】:

      【解决方案8】:

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

      【讨论】:

      • 我记得在某个地方读到过,你能提供一个链接吗?
      • 不确定最终变量是否如此,但可以用于静态最终变量 - 请参阅stackoverflow.com/questions/3117770/…
      • 无法提供链接,但我在 Reto Meier(2010 年 5 月 19 日)/Google IO 的“Android 初学者指南”中看到了有关它的通知。它很短,可以免费下载,并且对如何构建一个好的应用程序提供了很好的建议。
      • 最终变量可以使代码更高效,因为这意味着所有对象都将在同一次运行中被 GC。根据您将它们设置为 null 的时间,不在不同的时间。
      • 问题:编译器没有明确地为你做这件事吗?我认为它应该在代码分析阶段这样做。
      【解决方案9】:

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

      如果您发布带有 alpha 通道的大型 PNG,您可以用一些 APK 大小来换取启动速度和use separate JPGs for RGB and A channels

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

      【讨论】:

      • 感谢您的洞察!我从来没有听说过这个!
      【解决方案10】:

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

      【讨论】:

      • 原因?你能解释一下为什么吗?
      【解决方案11】:

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

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

      【讨论】:

        【解决方案12】:

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

        【讨论】:

          【解决方案13】:

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

          【讨论】:

            【解决方案14】:

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

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

            ..将更新..

            【讨论】:

              猜你喜欢
              • 2011-01-24
              • 1970-01-01
              • 2017-05-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-04-01
              • 2013-02-08
              • 2013-08-24
              相关资源
              最近更新 更多