java 安卓应用发布前优化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5626947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Optimising Android application before release
提问by Wroclai
I'm in a "special" situation about efficiencyof my program. Now I'm at a phase where I need to improve the performance of the application and reduce battery consumption.
我的程序效率处于“特殊”状态。现在我正处于需要提高应用程序性能和减少电池消耗的阶段。
Before the question:
提问前:
- Firstof all, my application work. It runs fine - no errors whatsoever.
- Secondly, I have read Optimizing Battery Life on Android developers websiteand I have optimised small things they've requested. No problems whatsoever.
- 首先,我的申请工作。它运行良好-没有错误无论如何。
- 其次,我已经阅读了 Android 开发者网站上的优化电池寿命,并且优化了他们要求的一些小东西。没有问题的任何。
Now, I'm curious to know about other developers' specialfixes which they have used to optimise their own applications. Stuff that users may never recognise or pay attention to. However, the fixes will either increase the battery life or help improve maintenance of the application.
现在,我很想知道其他开发人员用于优化他们自己的应用程序的特殊修复。用户可能永远不会认识或注意的东西。但是,修复将增加电池寿命或帮助改进应用程序的维护。
So, what's your unique optimizing trick(s)?
那么,您独特的优化技巧是什么?
I'm in a particular situation where I'm really looking for knowledge and I think this will be a great opportunity to share developers knowledge about a situation they've all been in.
我处于一种特殊情况,我真的在寻找知识,我认为这将是一个很好的机会来分享开发人员关于他们都曾遇到过的情况的知识。
Please, vote up great answers as that will encourage great developers to share their knowledge.
请投票选出优秀的答案,因为这将鼓励优秀的开发人员分享他们的知识。
采纳答案by unholysampler
At some point you are going to get to the point where using known tricks will hit their limits. The best thing to do at this point is profile your code and see what areas are the bottle-necks based on your specific requirements.
在某些时候,您将达到使用已知技巧将达到其极限的地步。此时最好的做法是分析您的代码,并根据您的特定要求查看哪些区域是瓶颈。
Investigating RAM usage using MATand Using Traceview: an article on how to use the tools to profile your application.
使用 MAT和使用 Traceview调查 RAM 使用情况:一篇关于如何使用这些工具来分析您的应用程序的文章。
回答by olivierg
Track and squash allocations. The more you allocate, the more often the garbage collector will need to run, stopping your process from doing anything else for relatively long periods of time, such as 100ms or so.
跟踪和压缩分配。您分配的越多,垃圾收集器需要运行的频率就越高,从而在相对较长的时间内(例如 100 毫秒左右)阻止您的进程执行任何其他操作。
The best tool I know for this is the Allocation Tracker included in DDMS.
我所知道的最好的工具是DDMS 中包含的分配跟踪器。
Not only GC can have an impact on the user experience, but superfluous allocations and GC do consume some computing resources.
不仅 GC 会影响用户体验,而且多余的分配和 GC 确实会消耗一些计算资源。
Here's an example and a small trick. In my app, I have a clock which shows the current (audio) time, including tenth of seconds. This is updated often. And TextView performs allocations internallywhenever you call setText() with a CharSequence. But it doesn't allocate anything with the setText(char[] text, int start, int len) variant. This isn't documented, and no one answered when I asked about it.
这是一个例子和一个小技巧。在我的应用程序中,我有一个时钟显示当前(音频)时间,包括十分之一秒。这是经常更新的。每当您使用 CharSequence 调用 setText() 时,TextView 都会在内部执行分配。但它没有为 setText(char[] text, int start, int len) 变体分配任何内容。这没有记录在案,当我询问时没有人回答。
There are many ones like this. And this is one of the reasons why my app contains 50% native code (but there are other reasons).
有很多这样的。这就是我的应用程序包含 50% 本机代码的原因之一(但还有其他原因)。
Apart from this, I can recommend that you experiment with ProGuard. It performs several optimization passes, and logs such informations as unused methods within the project, which can help you removing leftovers in your code.
除此之外,我可以建议您尝试ProGuard。它执行多次优化,并记录项目中未使用的方法等信息,这可以帮助您删除代码中的剩余部分。
回答by Aleadam
If your app will have a lot of screen time, use black wherever you can. That will reduce the battery consumption of the worst part of the device: the screen, specially in the AMOLED phones and tablets.
如果您的应用将有很多屏幕时间,请尽可能使用黑色。这将减少设备最糟糕部分的电池消耗:屏幕,特别是在 AMOLED 手机和平板电脑中。
回答by NickT
For applications with multiple activities, check you are not restarting activities that just need to be brought to the front by using the appropriate Intent flags. Check that your heap is under control, and that unnecessary views, bindings and contexts aren't being created.
对于具有多个活动的应用程序,请检查您是否没有重新启动只需使用适当的 Intent 标志置于最前面的活动。检查您的堆是否受到控制,并且没有创建不必要的视图、绑定和上下文。
I find the best tool for showing you all these as the app runs is:
我发现在应用程序运行时向您展示所有这些的最佳工具是:
adb shell dumpsys meminfo 'your apps package name'
回答by Heiko Rupp
When using SQLlite, put special attention on indexes. Don't assume anything. I got tremendous speedups in Zwitscher, when I put indexes on columns commonly used for search.
使用 SQLlite 时,要特别注意索引。不要假设任何事情。在 Zwitscher 中,当我在常用的搜索列上放置索引时,我获得了极大的加速。
回答by youri
A few tips that can help you optimize your app in terms of UI:
一些可以帮助您在UI方面优化应用的提示:
use
convertView
for list adapters - it would be very expensive if you create a new view insideAdapter.getView()
as this routine is called for every position in the list. UsingconvertView
lets you reuse the already created view. Good example (together with the use ofViewHolder
) can be found in ApiDemos.It might happen that your layouts are not fully optimized and can be improved (for instance by using merging or removing parents). Android tool layoutoptwill find such a situation for you. It can be used with HierarchyViewer for inspecting individual views. More info here.
remove the background drawable - Android framework used to have (does it still have?) a problemwith detecting what views should be drawn. There is a chance that your (default) background drawable will be drawn only to be subsequently hidden by your opaque UI. To get rid of this wasteful drawing simply remove background drawable.
使用
convertView
的名单适配器-如果你创建一个新的视图中这将是非常昂贵的Adapter.getView()
,因为这程序被调用列表中的每一个位置。使用convertView
允许您重用已创建的视图。ViewHolder
在ApiDemos 中可以找到很好的例子(连同 的使用)。可能会发生您的布局没有完全优化并且可以改进(例如通过使用合并或删除父项)。Android 工具layoutopt会为你找到这样的情况。它可以与 HierarchyViewer 一起用于检查单个视图。更多信息在这里。
删除背景可绘制 - Android 框架曾经(现在还有吗?)在检测应绘制哪些视图方面存在问题。有可能您的(默认)背景可绘制对象只会被绘制,随后被您的不透明 UI 隐藏。要摆脱这种浪费的绘图,只需删除背景可绘制对象。
It can be done using a custom style
可以使用自定义样式来完成
<resources>
<style name="Theme.NoBackground" parent="android:Theme">
<item name="android:windowBackground">@null</item>
</style>
</resources>
A few tips that can help you optimize your app in terms of batteryusage:
一些可以帮助您优化应用程序电池使用情况的提示:
check networking type and wait until user gets in the area with wifi or 3G (and not roaming) and only then allow him to use connection
use gzip for textual data whenever possible to speed up download and parsing
recycle complex java objects such as
XmlPullParserFactory
/BitmapFactory
/StringBuilder
/Matcher
etc.
检查网络类型并等待用户使用 wifi 或 3G(而不是漫游)进入该区域,然后才允许他使用连接
尽可能对文本数据使用 gzip 以加快下载和解析速度
再循环复杂Java对象诸如
XmlPullParserFactory
/BitmapFactory
/StringBuilder
/Matcher
等
For more battery tricks see Coding for Life - Battery Life, That Is.
有关更多电池技巧,请参阅Coding for Life - Battery Life, That Is。
回答by ernell
Something to think about: DO NOT overuse String, for example in a huge loop. This will create a lot of String objects that have to be GC'ed. The "Bad coding" example will produce 2 string objects every loop. Next example will produce only one final String and a single stringbuilder. This makes a huge difference when optimizing huge loops for speed. I used stringbuilder a lot when making my Wordlist Pro Android app, and it got really speedy when going through 270000 words in no time.
需要考虑的事情:不要过度使用 String,例如在一个巨大的循环中。这将创建许多必须被 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);
}
I wrote a more extended blogpost about the matter. read here
我写了一篇关于这个问题的更详细的博客文章。 在这里阅读
回答by Pēteris Caune
Optimize your PNG pictures with tools like OptiPNGand PNGCrushto shave off some (kilo)bytes from APK size. Image optimization tips for websites apply here too: use appropriate picture formats, play with JPG compression, consider using binary transparencies instead of 8-bit transparencies etc.
使用OptiPNG和PNGCrush等工具优化您的 PNG 图片,以减少 APK 大小的一些(千)字节。网站的图像优化技巧也适用于此:使用适当的图片格式、使用 JPG 压缩、考虑使用二进制透明胶片而不是 8 位透明胶片等。
If you ship big PNGs with alpha channel, you can trade some APK size for startup speed and use separate JPGs for RGB and A channels.
如果您发送带有 alpha 通道的大 PNG,您可以用一些 APK 大小来换取启动速度,并为 RGB 和 A 通道使用单独的 JPG。
If you're making HTTP connections, check that your HTTP client utilizes content compression. If it caches received HTTP responses, check that it understands and uses caching-related HTTP headers correctly.
如果您正在建立 HTTP 连接,请检查您的 HTTP 客户端是否使用了内容压缩。如果它缓存接收到的 HTTP 响应,请检查它是否理解并正确使用与缓存相关的 HTTP 标头。
回答by Stan
I guess using "final" variables everywhere where it's possible could also improve execution speed.
我想在任何可能的地方使用“最终”变量也可以提高执行速度。
回答by Naresh
Try using DDMS to track all the threads running in the system. For example i have noticed that I was using webview to display html content, i noticed that it creates few threads for cookie management session management etc..which increased my memory foot print. So unless you have a serious need for displaying complex html try using normal utility class "Html" in android to display html content. This might be useful for people who are displaying Eula since eula typicall contains html text.
尝试使用 DDMS 跟踪系统中运行的所有线程。例如,我注意到我使用 webview 来显示 html 内容,我注意到它为 cookie 管理会话管理等创建了几个线程。这增加了我的内存占用。因此,除非您非常需要显示复杂的 html,否则请尝试在 android 中使用普通实用程序类“Html”来显示 html 内容。这可能对显示 Eula 的人有用,因为 eula 通常包含 html 文本。
If you have to do network operations try using AndroidHttpClient if you are beginner, it has got some good capabilities for Caching SSL sessions and all it really helps in improving your performance. Always set your socket connection timeouts to something around 60 seconds or some finite values because infinite timeouts can cause deadlocks especially if you drop your connection during ssl handshake.
如果您必须进行网络操作,如果您是初学者,请尝试使用 AndroidHttpClient,它具有一些很好的缓存 SSL 会话的功能,并且它确实有助于提高您的性能。始终将套接字连接超时设置为 60 秒左右或一些有限值,因为无限超时可能导致死锁,尤其是在 ssl 握手期间断开连接时。