通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻 辑,但是性能不一定是最优化的。一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构。重构的好处有很多,其中一点,就是对代码进行优化,提高 软件的性能。下面我们就从几个方面来了解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的过程中,可能会反复审查代码是否可以优化。不过我认为,代 码的微优化是非常耗费时间的,没有必要从头到尾将所有代码都优化一遍。开发者应该根据具体的业务逻辑去专门针对某部分代码做优化。比如应用中可能有一些方 法会被反复调用,那么这部分代码就值得专门做优化。其它的代码,需要开发者在写代码过程中去注意。 |
优化系列相关博文:
相关推荐
在这个“安卓Android源码——android姿态传感器源代码.zip”压缩包中,我们很可能会找到与这些传感器相关的原始代码,以便开发者能够深入理解其工作原理并进行定制化开发。 加速度计是测量设备在三维空间中线性加...
在Android游戏开发中,物理引擎是一个至关重要的组成部分,它负责模拟真实世界中的物理现象,如重力、碰撞、弹力等,...实际编码时,应结合具体的物理引擎API和示例代码进行实践,不断调试优化,以达到理想的游戏效果。
在本项目"Android项目之——漂亮的平台书架"中,我们关注的是一个专门为安卓平台设计的应用程序,它可能是一个电子书阅读器或者图书管理应用,旨在提供美观且用户友好的界面,供用户浏览、搜索和管理书籍。...
本资源“安卓Android源码——安卓Android加速度传感器源代码.rar”包含了一套完整的加速度传感器的实现源码,可以帮助开发者深入了解其工作原理并进行自定义开发。 在Android中,加速度传感器的使用涉及到以下几个...
为了保证游戏在各种Android设备上都能流畅运行,他们可能对游戏进行了多层优化,包括资源加载策略、内存管理以及代码性能调优等。此外,考虑到不同设备的屏幕尺寸和分辨率,游戏界面应该具备良好的自适应性。 总的...
这个压缩包“安卓Android源码——转盘抽奖实例.zip”很可能是提供了一个完整的转盘抽奖功能的示例代码,我们可以从以下几个方面来深入理解其中的知识点: 1. **用户界面(User Interface, UI)设计**:在Android中,...
在Android开发中,自定义View是一项重要的技能,它允许开发者创造出独特且富有创意的用户界面。本篇文章将探讨如何创建一个仿雷达扫描效果的自定义View。雷达扫描效果常见于许多应用中,如游戏、安全监控或者定位...
《安卓Android源码——TankWar....总的来说,分析和学习《安卓Android源码——TankWar.zip》不仅能帮助开发者掌握Android游戏开发的基本技能,还能深入理解Android应用的各个层面,对于提高Android开发能力大有裨益。
1. **Android开发环境**:理解并设置Android Studio,这是官方推荐的集成开发环境,用于编写和调试Android应用。 2. **OpenGL ES**:Android系统中的3D图形库,它是一个轻量级版本的OpenGL,专为嵌入式设备设计。...
2. easyandroid.zip:这个名字暗示可能包含一套简化Android开发的框架或工具,可能有自定义库、模板代码或其他方便开发的功能。 3. abs4.2.0.zip:Action Bar Sherlock库的版本4.2.0,这是一个为早期Android版本提供...
在安卓(Android)开发中,实现首页转盘(通常指的是抽奖转盘)功能是一个常见的需求,这涉及到用户界面(UI)...通过深入研究这个源码,开发者不仅可以掌握转盘组件的实现方法,还能提升对Android开发整体流程的理解。
《Android从入门到精通》是一本专为初学者和进阶者设计的Android开发书籍,由编著者精心编写,由中国工信出版社和人民邮电出版社联合出版,责任编辑为张翼。这本书涵盖了Android开发的各个方面,从基础概念到高级...
这份“Android源码——指南针程序.zip”包含了实现这样一个功能的完整源代码。下面,我们将详细探讨Android指南针应用程序的关键技术和知识点。 首先,Android指南针应用的核心是利用设备的传感器系统,特别是磁力...
这个压缩包“安卓Android源码——左右翻页翻书.zip”提供了一个实现此类功能的示例项目,名为“android-flip-master”。这个项目可以帮助开发者理解如何在Android应用中创建类似真实书籍翻页的动态效果。 1. **...
在Android开发中,实现各种动画效果是提升用户体验的重要手段之一。这个"Android源码——风车效果源码_new_76.7z"压缩包文件提供了实现一个风车旋转效果的示例代码,这对于开发者来说是一个很好的学习资源,尤其是...
这份"Android源码——指南针程序.7z"压缩包很可能包含了一个完整的Android指南针应用的源代码,对于学习和理解Android应用开发,尤其是地理位置和传感器相关的功能,具有很高的参考价值。下面将详细探讨Android指南...
总的来说,这个"安卓画廊照片转换器"的源码是Android开发中的一个实战案例,它揭示了如何利用Android系统提供的工具和库来创建一个功能完善的图片查看和管理应用。通过研究这个源码,开发者可以提升自己在Android...
在安卓(Android)系统中,源码是理解其工作原理的关键。...通过分析这些源码,我们可以学习到Android图形系统、事件处理、文件存储等多个方面的知识,这对于安卓应用开发和系统级优化具有很高的价值。
"安卓Android源码——仿随手记的炫酷饼图.zip"是一个针对Android应用开发的学习资源,其核心在于实现类似随手记应用中的动态、炫酷的饼图展示功能。下面将详细解析这个项目的知识点。 首先,我们要了解饼图在数据...