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

Android——最佳性能实战

2015-11-06 15:23 274 查看
看了 郭霖前辈写的Android最佳性能实践(一)——合理管理内存 
后的一些简单总结




合理的管理内存可以从如下几个方面来着手:



节制的使用Service:

当我们启动一个Service的时候系统会倾向于将这个service所依赖的进程进行保留,这样就会导致这个进程变得非常的消耗内存。官方推荐我们使用IntentService这个service的好处在于当后台任务执行结束后会自动的停止,从而极大的避免了service内存泄露的可能性。
当界面不可见时释放内存:
当用户开启另外一个程序的时候,可以释放跟界面(UI)相关的资源,这样系统缓存后台进程的能力就会显著的增强,与onStop()不同的是,onStop是在同一个程序中从一个Activity跳转到另外一个Acrtivity,可以在onStop中关闭一些比如网络资源或者是广播等。
在Activity中重写onTrimMemory()方法,然后在这个方法中监听TRIM_MEMORY_UI_HIDDEN这个级别,一旦触发了之后就说明用户已经离开了我们的程序,那么此时就可以进行资源释放操作了

@Override
public void onTrimMemory(int level) {
 super.onTrimMemory(level);
 switch (level) {
 case TRIM_MEMORY_UI_HIDDEN:
  // 进行资源释放操作
  break;
 }
}
当内存紧张的时候释放资源:
onTrimMemory中还有其它类型的回调,可以在手机内存降低的时候及时的通知我们

TRIM_MEMORY_RUNNING_MODERATE    表示应用程序正常运行,并且不会被杀掉。但是目前手机的内存已经有点低了,系统可能会开始根据LRU缓存规则来去杀死进程了。
TRIM_MEMORY_RUNNING_LOW    表示应用程序正常运行,并且不会被杀掉。但是目前手机的内存已经非常低了,我们应该去释放掉一些不必要的资源以提升系统的性能,同时这也会直接影响到我们应用程序的性能。
TRIM_MEMORY_RUNNING_CRITICAL    表示应用程序仍然正常运行,但是系统已经根据LRU缓存规则杀掉了大部分缓存的进程了。这个时候我们应当尽可能地去释放任何不必要的资源,不然的话系统可能会继续杀掉所有缓存中的进程,并且开始杀掉一些本来应当保持运行的进程,比如说后台运行的服务。

以上是当我们的应用程序正在运行时的回调,那么如果我们的程序目前是被缓存的,则会收到以下几种类型的回调:
TRIM_MEMORY_BACKGROUND    表示手机目前内存已经很低了,系统准备开始根据LRU缓存来清理进程。这个时候我们的程序在LRU缓存列表的最近位置,是不太可能被清理掉的,但这时去释放掉一些比较容易恢复的资源能够让手机的内存变得比较充足,从而让我们的程序更长时间地保留在缓存当中,这样当用户返回我们的程序时会感觉非常顺畅,而不是经历了一次重新启动的过程。
TRIM_MEMORY_MODERATE    表示手机目前内存已经很低了,并且我们的程序处于LRU缓存列表的中间位置,如果手机内存还得不到进一步释放的话,那么我们的程序就有被系统杀掉的风险了。
TRIM_MEMORY_COMPLETE    表示手机目前内存已经很低了,并且我们的程序处于LRU缓存列表的最边缘位置,系统会最优先考虑杀掉我们的应用程序,在这个时候应当尽可能地把一切可以释放的东西都进行释放。

避免在Bitmap上浪费内存:不要去加载我们不需要的分辨率。将一张图片解析成一个Bitmap对象时所占用的内存并不是这个图片在硬盘中的大小,读取到内存当中是按像素来计算的。可以通过缓存、压缩的方法来加载一张图片。

使用优化过的数据集合

Android API当中提供了一些优化过后的数据集合工具类,如SparseArray,SparseBooleanArray,以及LongSparseArray等,使用这些API可以让我们的程序更加高效。传统Java API中提供的HashMap工具类会相对比较低效,因为它需要为每一个键值对都提供一个对象入口,而SparseArray就避免掉了基本数据类型转换成对象数据类型的时间。

知晓内存的开支情况

我们还应当清楚我们所使用语言的内存开支和消耗情况,并且在整个软件的设计和开发当中都应该将这些信息考虑在内。可能有一些看起来无关痛痒的写法,结果却会导致很大一部分的内存开支,例如:
使用枚举通常会比使用静态常量要消耗两倍以上的内存,在Android开发当中我们应当尽可能地不使用枚举。
任何一个Java类,包括内部类、匿名类,都要占用大概500字节的内存空间。
任何一个类的实例要消耗12-16字节的内存开支,因此频繁创建实例也是会一定程序上影响内存的。
在使用HashMap时,即使你只设置了一个基本数据类型的键,比如说int,但是也会按照对象的大小来分配内存,大概是32字节,而不是4字节。因此最好的办法就是像上面所说的一样,使用优化过的数据集合。

谨慎使用抽象编程

在Android上使用抽象会带来额外的内存开支,因为抽象的编程方法需要编写额外的代码,虽然这些代码根本执行不到,但是却也要映射到内存当中,不仅占用了更多的内存,在执行效率方面也会有所降低。所以要谨慎的使用,而不是肆意的去使用它。

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

@ContentView(R.layout.main)
class RoboWay extends RoboActivity { 
 @InjectView(R.id.name)             TextView name; 
 @InjectView(R.id.thumbnail)        ImageView thumbnail; 
 @InjectResource(R.drawable.icon)   Drawable icon; 
 @InjectResource(R.string.app_name) String myName; 
 @Inject                            LocationManager loc; 

 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  name.setText( "Hello, " + myName ); 
 } 
}
这些框架为了要搜寻代码中的注解,通常都需要经历较长的初始化过程,并且还可能将一些你用不到的对象也一并加载到内存当中。这些用不到的对象会一直占用着内存空间,可能要过很久之后才会得到释放

使用ProGuard简化代码

ProGuard相信大家都不会陌生,很多人都会使用这个工具来混淆代码,但是除了混淆之外,它还具有压缩和优化代码的功能。ProGuard会对我们的代码进行检索,删除一些无用的代码,并且会对类、字段、方法等进行重命名,重命名之后的类、字段和方法名都会比原来简短很多,这样的话也就对内存的占用变得更少了。

使用多个进程

这个技巧其实并不是非常建议使用,但它确实是一种可以帮助我们节省和管理内存的高级技巧。如果你要使用它的话一定要谨慎使用,因为绝大多数的应用程序都不应该在多个进程当中运行的,一旦使用不当,它甚至会增加额外的内存而不是帮我们节省内存。这个技巧比较适用于那些需要在后台去完成一项独立的任务,和前台的功能是可以完全区分开的场景。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 性能 管理 内存