【图文】关于Android内存和性能优化的使用教程
1.1。为什么你要小心使用Android资源
Android设备比标准的台式机或笔记本电脑的动力不足。 为此你必须小心的使用。
尤其是在Android设备在Android 5你想避免触发的 java虚拟机的垃圾收集器。 结果Android运行约200毫秒。 这可以显著延迟。
1.2。避免不必要的对象分配
避免创建不必要的对象,特别是在有些地方。 重用的对象,如果可能的话。 创建不必要的对象触发垃圾收集更频繁。
例如,避免在循环中创建对象ondraw()您的自定义视图的方法。
1.3。使用高效的数据结构
Android提供了几种实现方法*分散阵列分类考虑下面的代码。
Map<Integer, String> map = new HashMap<Integer, String>();
不必要的使用此代码的结果整数创建的对象。
Android提供了更为有效的值映射到其他对象的数据结构。 如果可能使用这些对象,他们避免创建对象实例使用HashMap。 创建对象可以是昂贵的和应该避免的次数减少垃圾收集器需要。
表sparsearrays给出例子。
表1。高效的内存结构
内存结构    描述
sparsearray <和>
整数对象,避免整数对象的创建。
sparsebooleanarray
整数to booleans地图。
sparseintarray
整数
为了改善上述的例子,可以用以下的数据结构。
SparseArray<String> map = new SparseArray<String>(); map.put(1, "Hello");
2。处理位图
位图可以分配大量内存如果在全尺寸的装。这是 推荐加载位图所需的大小。 假设你有一个应用程序,图像显示一个DP 100x100, 你要加载的图像完全。
一个常用的方法是首先测量无负载通过 旗传递到位图使用BitmapFactory。
// instruct BitmapFactory to only the bounds and type of the image BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); // get width and height int imageHeight = options.outHeight; int imageWidth = options.outWidth; // type of the image String imageType = options.outMimeType;
然后你可以负荷的缩小版的图像。Android 由功率两缩放图像真的是好的。你可以使用下面的方法 的 (从Android的官方文档)来计算的2的基础上 尺度因子。
public static Bitmap decodeBitmapWithGiveSizeFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
        final int halfHeight = height / 2;
        final int halfWidth = width / 2;
        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}此方法可用于指定图像的视图下面的例子演示了 。
viewWidth = imageView.getWidth();
viewHeight = imageView.getHeight();
imageView.
imageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, viewWidth, viewHeight));三.使用高速缓存
3.1。使用高速缓存
高速缓存允许重用这是昂贵的创建对象。如果你加载对象到内存,你可以认为这是一个 缓存的对象。 举例来说,如果你下载的图像从 的 互联网 到 显示 在 列表 你 应该将它们保存在内存中,避免 你下载他们 几个 。
在某些时候你需要利用你的一些对象,否则你耗尽内存。一个好的方法去做 这是回收未使用时间最长的应用程序中的对象。
Android平台提供的LruCache类,如API 12(或在support-v4图书馆)。这个LruCache类提供了一个 least最近使用的高速缓存(Cache) 缓存实现。 LRU缓存 的使用记录。它有一个给定的尺寸,如果这 大小 超标,它消除 的 项目 具有 不 被访问时长。这种行为是 描绘在 以下 图形。

LRU cache in general
下面的代码示例演示了一种可能的实现LruCache缓存的图片类。
public class ImageCache extends LruCache<String, Bitmap> {
 
  public ImageCache( int maxSize ) {
    super( maxSize );
  }
 
  @Override
  protected int sizeOf( String key, Bitmap value ) {
    return value.getByteCount();
  }
 
  @Override
  protected void entryRemoved( boolean evicted, String key, Bitmap oldValue, Bitmap newValue ) {
    oldValue.recycle();
  }
 
}确定缓存的大小,这是很好的做法的基础上确定总的可用内存设备上的大小。 确定可用的内存,你可以memoryclass这表明, 如下。
int memClass = ( ( ActivityManager) activity.getSystemService( Context.ACTIVITY_SERVICE ) ).getMemoryClass(); int cacheSize = 1024 * 1024 * memClass / 8; LruCache cache = new LruCache<String, Bitmap>( cacheSize );
3.2。清理你的缓存
作为API 14你可以重写ontrimmemory()在Android组件的方法。 这种方法被称为Android系统要求你清理你的记忆的情况下,Android系统需要的资源前景。