一般咱们写程序,都是在项目计划的压力下完成的,此时完成的代码能够完成具体业务逻辑,可是性能不必定是最优化的。通常来讲,优秀的程序员在写完代 码以后都会不断的对代码进行重构。重构的好处有不少,其中一点,就是对代码进行优化,提升软件的性能。下面咱们就从几个方面来了解Android开发过程 中的代码优化。程序员
1)静态变量引发内存泄露算法
在代码优化的过程当中,咱们须要对代码中的静态变量特别留意。静态变量是类相关的变量,它的生命周期是从这个类被声明,到这个类完全被垃圾回收器回收 才会被销毁。因此,通常状况下,静态变量从所在的类被使用开始就要一直占用着内存空间,直到程序退出。若是不注意,静态变量引用了占用大量内存的资源,造 成垃圾回收器没法对内存进行回收,就可能形成内存的浪费。缓存
先来看一段代码,这段代码定义了一个Activity。
安全
@Overrideide
protected void onCreate(Bundle state) {性能
super.onCreate(state);优化
if (mResources == null) {this
mResources = this.getResources();spa
}线程
}
这段代码中有一个静态的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对象。
依然拿上面的代码做为例子。能够将代码修改为下面的样子。
@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的代码片断。
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类中提供了以下方法:
当ListView列表里的每一项显示时,都会调用Adapter的getView方法返回一个View,
来向ListView提供所须要的View对象。
下面是一个完整的getView()方法的代码示例。
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的过程当中,可能会反复审查代码是否能够优化。不过我 认为,代码的微优化是很是耗费时间的,没有必要从头至尾将全部代码都优化一遍。开发者应该根据具体的业务逻辑去专门针对某部分代码作优化。好比应用中可能 有一些方法会被反复调用,那么这部分代码就值得专门作优化。其它的代码,须要开发者在写代码过程当中去注意。