[Android] Android开发优化之——从代码角度进行优化
通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻辑,但是性能不一定是最优化的。一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构。重构的好处有很多,其中一点,就是对代码进行优化,提高软件的性能。下面我们就从几个方面来了解Android开发过程中的代码优化。
1)静态变量引起内存泄露
在代码优化的过程中,我们需要对代码中的静态变量特别留意。静态变量是类相关的变量,它的生命周期是从这个类被声明,到这个类彻底被垃圾回收器回收才会被销毁。所以,一般情况下,静态变量从所在的类被使用开始就要一直占用着内存空间,直到程序退出。如果不注意,静态变量引用了占用大量内存的资源,造成垃圾回收器无法对内存进行回收,就可能造成内存的浪费。
先来看一段代码,这段代码定义了一个Activity。
private static Resources mResources; @Override protected void onCreate(Bundle state) { super.onCreate(state); if (mResources == null) { mResources = this.getResources(); } } |
这段代码中有一个静态的Resources对象。代码片段mResources = this.getResources()对Resources对象进行了初始化。这时Resources对象拥有了当前Activity对象的引用,Activity又引用了整个页面中所有的对象。
如果当前的Activity被重新创建(比如横竖屏切换,默认情况下整个Activity会被重新创建),由于Resources引用了第一次创建的Activity,就会导致第一次创建的Activity不能被垃圾回收器回收,从而导致第一次创建的Activity中的所有对象都不能被回收。这个时候,一部分内存就浪费掉了。
经验分享: 在实际项目中,我们经常会把一些对象的引用加入到集合中,如果这个集合是静态的话,就需要特别注意了。当不需要某对象时,务必及时把它的引用从集合中清理掉。或者可以为集合提供一种更新策略,及时更新整个集合,这样可以保证集合的大小不超过某值,避免内存空间的浪费。 |
2)使用Application的Context
在Android中,Application Context的生命周期和应用的生命周期一样长,而不是取决于某个Activity的生命周期。如果想保持一个长期生命的对象,并且这个对象需要一个Context,就可以使用Application对象。可以通过调用Context.getApplicationContext()方法或者Activity.getApplication()方法来获得Application对象。
依然拿上面的代码作为例子。可以将代码修改成下面的样子。
private static Resources mResources; @Override protected void onCreate(Bundle state) { super.onCreate(state); if (mResources == null) { // mResources = this.getResources(); mResources = this.getApplication().getResources(); } } |
在这里将this.getResources()修改为this.getApplication().getResources()。修改以后,Resources对象拥有的是Application对象的引用。如果Activity被重新创建,第一次创建的Activity就可以被回收了。
3)及时关闭资源
Cursor是Android查询数据后得到的一个管理数据集合的类。正常情况下,如果我们没有关闭它,系统会在回收它时进行关闭,但是这样的效率特别低。如果查询得到的数据量较小时还好,如果Cursor的数据量非常大,特别是如果里面有Blob信息时,就可能出现内存问题。所以一定要及时关闭Cursor。
下面给出一个通用的使用Cursor的代码片段。
Cursor cursor = null; try{ cursor = mContext.getContentResolver().query(uri,null,null,null,null); if (cursor != null) { cursor.moveToFirst(); // 处理数据 } } catch (Exception e){ e.printStatckTrace(); } finally { if (cursor != null){ cursor.close(); } } |
即对异常进行捕获,并且在finally中将cursor关闭。
同样的,在使用文件的时候,也要及时关闭。
4)使用Bitmap及时调用recycle()
前面的章节讲过,在不使用Bitmap对象时,需要调用recycle()释放内存,然后将它设置为null。虽然调用recycle()并不能保证立即释放占用的内存,但是可以加速Bitmap的内存的释放。
在代码优化的过程中,如果发现某个Activity用到了Bitmap对象,却没有显式的调用recycle()释放内存,则需要分析代码逻辑,增加相关代码,在不再使用Bitmap以后调用recycle()释放内存。
5)对Adapter进行优化
下面以构造ListView的BaseAdapter为例说明如何对Adapter进行优化。
在BaseAdapter类中提供了如下方法:
public View getView(int position, View convertView, ViewGroup parent) |
当ListView列表里的每一项显示时,都会调用Adapter的getView方法返回一个View,
来向ListView提供所需要的View对象。
下面是一个完整的getView()方法的代码示例。
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.text.setText("line" + position); return convertView; } private class ViewHolder { TextView text; } |
当向上滚动ListView时,getView()方法会被反复调用。getView()的第二个参数convertView是被缓存起来的List条目中的View对象。当ListView滑动的时候,getView可能会直接返回旧的convertView。这里使用了convertView和ViewHolder,可以充分利用缓存,避免反复创建View对象和TextView对象。
如果ListView的条目只有几个,这种技巧并不能带来多少性能的提升。但是如果条目有几百甚至几千个,使用这种技巧只会创建几个convertView和ViewHolder(取决于当前界面能够显示的条目数),性能的差别就非常非常大了。
6)代码“微优化”
当今时代已经进入了“微时代”。这里的“微优化”指的是代码层面的细节优化,即不改动代码整体结构,不改变程序原有的逻辑。尽管Android使用的是Dalvik虚拟机,但是传统的Java方面的代码优化技巧在Android开发中也都是适用的。
下面简要列举一部分。因为一般Java开发者都能够理解,就不再做具体的代码说明。
创建新的对象都需要额外的内存空间,要尽量减少创建新的对象。
将类、变量、方法等等的可见性修改为最小。
针对字符串的拼接,使用StringBuffer替代String。
不要在循环当中声明临时变量,不要在循环中捕获异常。
如果对于线程安全没有要求,尽量使用线程不安全的集合对象。
使用集合对象,如果事先知道其大小,则可以在构造方法中设置初始大小。
文件读取操作需要使用缓存类,及时关闭文件。
慎用异常,使用异常会导致性能降低。
如果程序会频繁创建线程,则可以考虑使用线程池。
经验分享: 代码的微优化有很多很多东西可以讲,小到一个变量的声明,大到一段算法。尤其在代码Review的过程中,可能会反复审查代码是否可以优化。不过我认为,代码的微优化是非常耗费时间的,没有必要从头到尾将所有代码都优化一遍。开发者应该根据具体的业务逻辑去专门针对某部分代码做优化。比如应用中可能有一些方法会被反复调用,那么这部分代码就值得专门做优化。其它的代码,需要开发者在写代码过程中去注意。 |
优化系列相关博文:
---------------------------------------------------------------------------
http://blog.csdn.net/arui319
《Android应用开发精解》已出版,本文是初稿的部分内容。欢迎购买阅读。
本文可以转载,但是请保留以上作者信息。
谢谢。
---------------------------------------------------------------------------
[Android] Android开发优化之——从代码角度进行优化的更多相关文章
- 解析Android开发优化之:从代码角度进行优化的技巧
下面我们就从几个方面来了解Android开发过程中的代码优化,需要的朋友参考下 通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻辑,但是性能不一定是最优化的.一般来说 ...
- Android开发优化之——从代码角度进行优化
通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻 辑,但是性能不一定是最优化的.一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构.重构的好处有很多,其中一点, ...
- iOS开发UI篇—从代码的逐步优化看MVC
iOS开发UI篇—从代码的逐步优化看MVC 一.要求 要求完成下面一个小的应用程序. 二.一步步对代码进行优化 注意:在开发过程中,优化的过程是一步一步进行的.(如果一个人要吃五个包子才能吃饱,那么他 ...
- Android App开发常用专题开源代码
Android App开发中用到过的专题类开源代码: 项目的需求多了,不知不觉成了Github摘抄员,感谢分享精神,节省了很多弯路和时间.不过想要实现指定效果,还是要看懂作者的思路才好下手改造. 主题 ...
- [Android] Android开发优化之——使用软引用和弱引用
Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. ...
- Android开发优化之——对Bitmap的内存优化
http://blog.csdn.net/arui319/article/details/7953690 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitm ...
- [Android] Android开发优化之——对界面UI的优化(2)
在Android应用开发过程中,屏幕上控件的布局代码和程序的逻辑代码通常是分开的.界面的布局代码是放在一个独立的xml文件中的,这个文件里面是树型组织的,控制着页面的布局.通常,在这个页面中会用到很多 ...
- [Android] Android开发优化之——对界面UI的优化(1)
在Android应用开发过程中,屏幕上控件的布局代码和程序的逻辑代码通常是分开的.界面的布局代码是放在一个独立的xml文件中的,这个文件里面是树型组织的,控制着页面的布局.通常,在这个页面中会用到很多 ...
- C#-Xamarin的Android项目开发(二)——控件应用
相信我,这不是一篇吐槽文章.... 基础控件 Android的控件和控件样式非常特别,它是一种内联特别高的设计模式,换句话说,它是非常烂的设计.... 但在这种特别的关系里还是有一定的规律的,下面我们 ...
随机推荐
- NFS的搭建(sudo apt-get install nfs-kernel-server),TFTP服务器(sudo apt-get install tftpd-hpa tftp-hpa)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Osean_li/article/details/53240705 ***************** ...
- nyoj--74--小学生算术(水)
小学生算术 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 很多小学生在学习加法时,发现"进位"特别容易出错.你的任务是计算两个三位数在相加时需要多少 ...
- 基础apache命令
在启动Apache服务之前,可以使用下面的命令来检查配置文件的正确性. C:\Apache2.2\bin> httpd -n Apache2.2 -t 还可以通过命令行控制Apache服务 ...
- 获取sqlserver数据字典的完整sql。
SELECTsysobjects.name AS 表名称 , --------------as 的作用:为字段起一个别名 --sysproperties.[value] AS 表说明 , ------ ...
- VS自动注释——GhostDoc
直接上图片,使用步骤是按顺序来的: 安装就不多说了,直接下一步,下一步.直接讲讲如何自定义注释规则 软件下载链接:http://pan.baidu.com/s/1dF5TSel 密码:peuz 链接: ...
- php.ini配置文件参数优化
用于生产环境中的PHP需要对其进行优化,让PHP自身发挥更好的性能,除了写好PHP代码,还要配置好php-fpm以及php.ini调优.本文从内存.OPcache.上传.会话以及安全等方面讲解php. ...
- WebAssembly学习(二):Windows10下WebAssembly C/C++编译环境的搭建与Hello World尝试
首先,不论是在Windows.Linux还是Mac上,Webassembly的编译都是主要依赖于Emscripten SDK这个工具的.但是,在这里必须要吐槽一下,不论是WebAssembly官网.W ...
- NuSOAP笔记:如何创建复杂数据类型
PHP已经有了内置的SOAP扩展,但是它不具备自动生成WSDL的能力,所以很多时候,NuSOAP还是有一定诱惑力的. 在应用稍微复杂点的时候,单靠integer, string等简单数据类型是不能满足 ...
- NOI 2015 品酒大会 (后缀数组+并查集)
题目大意:略 40分暴力还是很好写的,差分再跑个后缀和 和 后缀最大值就行了 一种正解是后缀数组+并查集 但据说还有后缀数组+单调栈的高端操作蒟蒻的我当然不会 后缀数组求出height,然后从大到小排 ...
- BZOJ 3510 首都 (LCT)
洛谷P4299传送门 题目大意:给你一颗树,边是一条一条连上去的 在连接过程中会存在询问,询问当前节点所在联通块(其实是一颗树)的重心是哪个节点 以及森林中所有树的重心的异或和 在做这道题之前,要先了 ...