【图文】关于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系统需要的资源前景。