android内存优化总结
在写app的时候,越是到后面越是要考虑到app实际效率和体验的问题。往往在写个人的项目时,这方面考虑的比较少,因为用户少,而且有些问题可能不是很复杂。但是在做公司的项目时就必须考虑周到。比如内存优化,recyclerview优化,界面优化等。避免出现oom、anr等错误。
为什么需要内存优化 现在的手机配置都不一样,在开发app的时候应该考虑到大多数手机的实际情况,所以一般app占用内存不要超过50m。否则会出现app相当卡顿的样子。也可能出现app的ANR错误。这是一个优秀app开发必然要考虑的问题。
内存优化的方式
图片: 在很多内存崩溃的情况中最多的原因就是图片过多过大。那么针对图片进行一些优化是必要的。
(1)、使用option进行压缩。
public static Bitmap createImageThumbnail(String filePath){
Bitmap bitmap = null;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, opts);
opts.inSampleSize = computeSampleSize(opts, -1, 128*128);
opts.inJustDecodeBounds = false;
try {
bitmap = BitmapFactory.decodeFile(filePath, opts);
}catch (Exception e) {
// TODO: handle exception
}
return bitmap;
}
public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {
int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);
int roundedSize;
if (initialSize <= 8) {
roundedSize = 1;
while (roundedSize < initialSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initialSize + 7) / 8 * 8;
}
return roundedSize;
}
private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) {
double w = options.outWidth;
double h = options.outHeight;
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 :(int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
// return the larger one when there is no overlapping zone.
return lowerBound;
}
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}
(2)、使用LRUcache
LRU指的是回收最近不是经常使用的资源。LRUcache使用的是key、value的形式,对于图片。实现:
1、获取图片所需的缓存空间。(重写sizeof方法)
private LruCache<String, Bitmap> mMemoryCache;
private LruCacheUtils() {
if (mMemoryCache == null)
mMemoryCache = new LruCache<String, Bitmap>(
MAXMEMONRY / 8) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// 重写此方法来衡量每张图片的大小,默认返回图片数量。
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}
@Override
protected void entryRemoved(boolean evicted, String key,
Bitmap oldValue, Bitmap newValue) {
Log.v("tag", "hard cache is full , push to soft cache");
}
};
}
2、实现图片操作
public void clearCache() {
if (mMemoryCache != null) {
if (mMemoryCache.size() > 0) {
Log.d("CacheUtils",
"mMemoryCache.size() " + mMemoryCache.size());
mMemoryCache.evictAll();
Log.d("CacheUtils", "mMemoryCache.size()" + mMemoryCache.size());
}
mMemoryCache = null;
}
}
public synchronized void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (mMemoryCache.get(key) == null) {
if (key != null && bitmap != null)
mMemoryCache.put(key, bitmap);
} else
Log.w(TAG, "the res is aready exits");
}
public synchronized Bitmap getBitmapFromMemCache(String key) {
Bitmap bm = mMemoryCache.get(key);
if (key != null) {
return bm;
}
return null;
}
/**
* 移除缓存
*
* @param key
*/
public synchronized void removeImageCache(String key) {
if (key != null) {
if (mMemoryCache != null) {
Bitmap bm = mMemoryCache.remove(key);
if (bm != null)
bm.recycle();
}
}
}
(3)、软引用(已经不推崇使用,因为gc主要处理对象就是软引用和弱引用,现在就用LRUcache)
(4)、选择RGB_565 (一个像素两个byte) 代替 ALPHA_8(1)、ARGB_444(2)、ARGB_8888(4)
(5)、使用完图片要及时recycle
二、变量 1、尽量使用final static代替static
2、能直接访问的字段就不要使用get、set了。
3、全局变量尽量少一些。
4、能放在外面的东西尽量不要放在for循环当中。
以上就是一些基础的吧,希望对大家有所帮助。