7k小说网,韩讯,许晋享
正例:
class BitmapWorkerTask extends AsyncTask { ... // 在后台进行图片解码 @Override protected Bitmap doInBackground(Integer... params) { final Bitmap bitmap = BitmapFactory.decodeFile("some path"); return bitmap; } ... }
反例:
Button btnLoadImage = (Button) findViewById(R.id.btn); btnLoadImage.setOnClickListener(new OnClickListener() { public void onClick(View v) { Bitmap bitmap = BitmapFactory.decodeFile("some path"); } });
正例:
例如使用系统 LruCache 缓存
private LruCache mMemoryCache; @Override protected void onCreate(Bundle savedInstanceState) { ... // 获取可用内存的最大值,使用内存超出这个值将抛出 OutOfMemory 异常。LruCache 通过构造函数传入缓存值,以 KB 为单位。 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // 把最大可用内存的 1/8 作为缓存空间 final int cacheSize = maxMemory / 8; mMemoryCache = new LruCache(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount() / 1024; } }; ... } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { mMemoryCache.put(key, bitmap); } } public Bitmap getBitmapFromMemCache(String key) { return mMemoryCache.get(key); } public void loadBitmap(int resId, ImageView imageView) { final String imageKey = String.valueOf(resId); final Bitmap bitmap = getBitmapFromMemCache(imageKey); if (bitmap != null) { mImageView.setImageBitmap(bitmap); } else { mImageView.setImageResource(R.drawable.image_placeholder); BitmapWorkerTask task = new BitmapWorkerTask(mImageView); task.execute(resId); } } class BitmapWorkerTask extends AsyncTask { ... // 在后台进行图片解码 @Override protected Bitmap doInBackground(Integer... params) { final Bitmap bitmap = decodeSampledBitmapFromResource(getResources(), params[0], 100, 100); addBitmapToMemoryCache(String.valueOf(params[0]), bitmap); return bitmap; } ... }
反例:
没有存储,每次都需要解码,或者有缓存但是没有合适的淘汰机制,导致缓存效果很差,依然经常需要重新解码。
正例:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // 首先通过 inJustDecodeBounds=true 获得图片的尺寸 final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // 然后根据图片分辨率以及我们实际需要展示的大小,计算压缩率 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 设置压缩率,并解码 options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); }
反例:
不经压缩显示原图。
正例:
Bitmap bitmap = null; loadBitmapAsync(new OnResult(result) { bitmap = result; }); // ...使用该 bitmap... // 使用结束,在 2.3.3 及以下需要调用 recycle()函数,在 2.3.3 以上 GC 会自动管理,除非你明确不需要再用。 if (Build.VERSION.SDK_INT <= 10) { bitmap.recycle(); } bitmap = null;
反例:
使用完成图片,始终不释放资源。
正例:
public class MyActivity extends Activity { ImageView mImageView; Animation mAnimation; Button mBtn; /** * 首次创建 activity 时调用 */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mImageView = (ImageView) findViewById(R.id.ImageView01); mAnimation = AnimationUtils.loadAnimation(this, R.anim.anim); mBtn = (Button) findViewById(R.id.Button01); mBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mImageView.startAnimation(mAnimation); } }); } public void onPause() { //页面退出,及时清理动画资源 mImageView.clearAnimation(); } }
反例:
页面退出时,不关闭该页面相应的动画。
正例:
package com.niles.ndkdemo; public class MyActivity extends Activity { private ImageView mImageView; private Animation mAnimation; /** * 首次创建 activity 时调用 */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mImageView = (ImageView) findViewById(R.id.ImageView01); mAnimation = AnimationUtils.loadAnimation(this, R.anim.anim); mAnimation.setAnimationListener(new AnimationListener() { @Override public void onAnimationEnd(Animation arg0) { //判断一下资源是否被释放了 if (mImageView != null) { mImageView.clearAnimation(); } } }); mImageView.startAnimation(mAnimation); } }
反例:
动画结束回调中,直接使用资源不加判断,导致异常。
正例:
public static Bitmap decodeSampledBitmapFromFile(String filename, int reqWidth, int reqHeight, ImageCache cache) { final BitmapFactory.Options options = new BitmapFactory.Options(); ... BitmapFactory.decodeFile(filename, options); ... // 如果在 Honeycomb 或更新版本系统中运行,尝试使用 inBitmap if (Utils.hasHoneycomb()) { addInBitmapOptions(options, cache); } ... return BitmapFactory.decodeFile(filename, options); } private static void addInBitmapOptions(BitmapFactory.Options options, ImageCache cache) { // inBitmap 只处理可变的位图,所以强制返回可变的位图 options.inMutable = true; if (cache != null) { Bitmap inBitmap = cache.getBitmapFromReusableSet(options); if (inBitmap != null) { options.inBitmap = inBitmap; } } }
说明:
android.graphics.Bitmap.Config 类中关于图片颜色的存储方式定义:
ALPHA_8 代码 8 位 Alpha 位图; ARGB_4444 代表 16 位 ARGB 位图; ARGB_8888 代表 32 位 ARGB 位图; RGB_565 代表 8 位 RGB 位图。位图位数越高,存储的颜色信息越多,图片也就越逼真。大多数场景使用的是 ARGB_8888 和 RGB_565,RGB_565 能够在保证图片质量的情况下大大减少内存的开销,是解决 OOM 的一种方法。
但是一定要注意 RGB_565 是没有透明度的,如果图片本身需要保留透明度,那么就不能使用 GRB_565。
正例:
Config config = drawableSave.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888 : Config.RGB_565; Bitmap bitmap = Bitmap.createBitmap(w, h, config);
反例:
Bitmap newb = Bitmap.createBitmap(width, height, Config.ARGB_8888);
11、【推荐】尽量减少 Bitmap(BitmapDrawable)的使用,尽量使用纯色(ColorDrawable)、渐变色(GradientDrawable)、StateSelector(StateListDrawable)等与 Shape 结合的形式构建绘图。
正例:
View v = findViewById(R.id.xxxViewID); final FadeUpAnimation anim = new FadeUpAnimation(v); anim.setInterpolator(new AccelerateInterpolator()); anim.setDuration(1000); anim.setFillAfter(true); new Handler().postDelayed(new Runnable() { public void run() { if (v != null) { v.clearAnimation(); } } }, anim.getDuration()); v.startAnimation(anim);
正例:
View v = findViewById(R.id.xxxViewID); final FadeUpAnimation anim = new FadeUpAnimation(v); anim.setInterpolator(new AccelerateInterpolator()); anim.setDuration(1000); anim.setFillAfter(true); anim.setAnimationListener(new AnimationListener() { @Override public void onAnimationEnd(Animation arg0) { //判断一下资源是否被释放了 if (v != null) { v.clearAnimation(); } } }); v.startAnimat
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android Manifest中meta-data扩展元素数据的配置与获取方式
Android实现获取meta-data和build.gradle的值
Android获取清单文件中的meta-data,解决碰到数值为null的问题
解决webview 第二次调用loadUrl页面不刷新的问题
解决Android WebView拦截url,视频播放加载失败的问题
Android webview加载https链接错误或无响应的解决
网友评论