您的位置:首页 > 移动开发 > Android开发

Android最佳性能实践(

2015-07-16 13:21 411 查看
1、节制性使用service,请一定要注意只有当任务正在执行的时候才应该让Service运行起来,当任务执行完之后去停止Service的时候,要小心Service停止失败导致内存泄漏的情况。

2、


当界面不可见时释放内存

那么我们如何才能知道程序界面是不是已经不可见了呢?其实很简单,只需要在Activity中重写onTrimMemory()方法,然后在这个方法中监听TRIM_MEMORY_UI_HIDDEN这个级别,一旦触发了之后就说明用户已经离开了我们的程序,那么此时就可以进行资源释放操作了,如下所示:

[java] view
plaincopy





@Override

public void onTrimMemory(int level) {

super.onTrimMemory(level);

switch (level) {

case TRIM_MEMORY_UI_HIDDEN:

// 进行资源释放操作

break;

}

}

注意onTrimMemory()方法中的TRIM_MEMORY_UI_HIDDEN回调只有当我们程序中的所有UI组件全部不可见的时候才会触发,这和onStop()方法还是有很大区别的,因为onStop()方法只是当一个Activity完全不可见的时候就会调用,比如说用户打开了我们程序中的另一个Activity。因此,我们可以在onStop()方法中去释放一些Activity相关的资源,比如说取消网络连接或者注销广播***等,但是像UI相关的资源应该一直要等到


当内存紧张时释放内存


避免在Bitmap上浪费内存

在一个很小的ImageView上显示一张高分辨率的图片不会带来任何视觉上的好处,但却会占用我们相当多宝贵的内存。


使用优化过的数据集合

Android API当中提供了一些优化过后的数据集合工具类,如SparseArray,SparseBooleanArray,以及LongSparseArray等,使用这些API可以让我们的程序更加高效。


知晓内存的开支情况

我们还应当清楚我们所使用语言的内存开支和消耗情况,并且在整个软件的设计和开发当中都应该将这些信息考虑在内。可能有一些看起来无关痛痒的写法,结果却会导致很大一部分的内存开支,例如:

使用枚举通常会比使用静态常量要消耗两倍以上的内存,在Android开发当中我们应当尽可能地不使用枚举。
任何一个Java类,包括内部类、匿名类,都要占用大概500字节的内存空间。
任何一个类的实例要消耗12-16字节的内存开支,因此频繁创建实例也是会一定程序上影响内存的。
在使用HashMap时,即使你只设置了一个基本数据类型的键,比如说int,但是也会按照对象的大小来分配内存,大概是32字节,而不是4字节。因此最好的办法就是像上面所说的一样,使用优化过的数据集合。


谨慎使用抽象编程

,在Android上使用抽象会带来额外的内存开支,因为抽象的编程方法需要编写额外的代码,虽然这些代码根本执行不到,但是却也要映射到内存当中,不仅占用了更多的内存


尽量避免使用依赖注入框架

下面我们来模拟一种Activity内存泄漏的场景,内部类相信大家都有用过,如果我们在一个类中又定义了一个非静态的内部类,那么这个内部类就会持有外部类的引用,如下所示:

[java] view
plaincopy





public class MainActivity extends ActionBarActivity {



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

LeakClass leakClass = new LeakClass();

}



class LeakClass {



}

......

}

目前来看,代码还是没有问题的,因为虽然LeakClass这个内部类持有MainActivity的引用,但是只要它的存活时间不会长于MainActivity,就不会阻止MainActivity被垃圾回收器回收。那么现在我们来将代码进行如下修改:

[java] view
plaincopy





public class MainActivity extends ActionBarActivity {



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

LeakClass leakClass = new LeakClass();

leakClass.start();

}



class LeakClass extends Thread {



@Override

public void run() {

while (true) {

try {

Thread.sleep(60 * 60 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

......

}

这下就有点不太一样了,我们让LeakClass继承自Thread,并且重写了run()方法,然后在MainActivity的onCreate()方法中去启动LeakClass这个线程。而LeakClass的run()方法中运行了一个死循环,也就是说这个线程永远都不会执行结束,那么LeakClass这个对象就一直不能得到释放,并且它持有的MainActivity也将无法得到释放,那么内存泄露就出现了。

现在我们可以将程序运行起来,然后不断地旋转手机让程序在横屏和竖屏之间切换,因为每切换一次Activity都会经历一个重新创建的过程,而前面创建的Activity又无法得到回收,那么长时间操作下我们的应用程序所占用的内存就会越来越高,最终出现OutOfMemoryError。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: