Apidemo学习 PurgeableBitmap

/**
 * PurgeableBitmap demonstrates the effects of setting Bitmaps as being
 * purgeable.
 *
 * In the NonPurgeable case, an encoded bitstream is decoded to a different
 * Bitmap over and over again up to 200 times until out-of-memory occurs.
 * In contrast, the Purgeable case shows that the system can complete decoding
 * the encoded bitstream 200 times without hitting the out-of-memory case.
 * 
 * BitmapFactory.Option 由一个属性public boolean inPurgeable

    如果inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间在系统内存不足时可以被回收, 
    在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel),系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组。
    为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据。
   本例显示了inPurgeable设为True和False的两种情况,不停的创建一个bitmap
   mOptions 为BitmapFactory.Option类型,mOptions.isPurgable可以为true和false。 在isPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收,
   这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象,不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同,200个bitmap足以使大部分的设备重新OutOfMemory错误。

当isPurgable设为true时,系统中内存不足时,可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误。

本例有两个例子NonPurgeable 和 Purgeable,其定义的代码是同样的类PurgeableBitmap和PurgeableBitmapView,
 但它们在Android的Launcher都有自己的启动图标。这是因为在AndroidManifest.xml中使用了activity-alias定义。

activity-alias定义可以为同一个Activty指定别名,指定不同的IntentFilter或其它配置,从而使得同一个Activity可以有不同的属性,
图标等。 activity-alias 和activity支持的属性基本一致,在功能上和Activity基本一致。

 */
public class 
PurgeableBitmap 
extends GraphicsActivity { private PurgeableBitmapView mView; private final RefreshHandler mRedrawHandler = new RefreshHandler(); class RefreshHandler extends Handler { @Override public void handleMessage(Message msg) { int index = mView.update(this); if (index > 0) { showAlertDialog(getDialogMessage(true, index)); } else if (index < 0){ mView.invalidate(); showAlertDialog(getDialogMessage(false, -index)); } else { mView.invalidate(); } } public void sleep(long delayMillis) { this.removeMessages(0); sendMessageDelayed(obtainMessage(0), delayMillis); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mView = new PurgeableBitmapView(this, detectIfPurgeableRequest()); mRedrawHandler.sleep(0); setContentView(mView); } private boolean detectIfPurgeableRequest() { PackageManager pm = getPackageManager(); CharSequence labelSeq = null; try { ActivityInfo info = pm.getActivityInfo(this.getComponentName(), PackageManager.GET_META_DATA); labelSeq = info.loadLabel(pm); } catch (NameNotFoundException e) { e.printStackTrace(); return false; } String[] components = labelSeq.toString().split("/"); if (components[components.length - 1].equals("Purgeable")) { return true; } else { return false; } } private String getDialogMessage(boolean isOutOfMemory, int index) { StringBuilder sb = new StringBuilder(); if (isOutOfMemory) { sb.append("Out of memery occurs when the "); sb.append(index); sb.append("th Bitmap is decoded."); } else { sb.append("Complete decoding ") .append(index) .append(" bitmaps without running out of memory."); } return sb.toString(); } private void showAlertDialog(String message) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(message) .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }); AlertDialog alert = builder.create(); alert.show(); }}



/**
 * PurgeableBitmapView works with PurgeableBitmap to demonstrate the effects of setting
 * Bitmaps as being purgeable.
 *
 * PurgeableBitmapView decodes an encoded bitstream to a Bitmap each time update()
 * is invoked(), and its onDraw() draws the Bitmap and a number to screen.
 * The number is used to indicate the number of Bitmaps that has been decoded.
 */
public class PurgeableBitmapView extends View {
    private final byte[] bitstream;

    private Bitmap mBitmap;
    private final int mArraySize = 200;
    private final Bitmap[] mBitmapArray = new Bitmap [mArraySize];
    private final Options mOptions = new Options();
    private static final int WIDTH = 150;
    private static final int HEIGHT = 450;
    private static final int STRIDE = 320;   // must be >= WIDTH
    private int mDecodingCount = 0;
    private final Paint mPaint = new Paint();
    private final int textSize = 32;
    private static int delay = 100;

    public PurgeableBitmapView(Context context, boolean isPurgeable) {
        super(context);
        setFocusable(true);
        mOptions.inPurgeable = isPurgeable;

        int[] colors = createColors();
        Bitmap src = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
                Bitmap.Config.ARGB_8888);
        bitstream = generateBitstream(src, Bitmap.CompressFormat.JPEG, 80);

        mPaint.setTextSize(textSize);
        mPaint.setColor(Color.GRAY);
    }

    private int[] createColors() {//颜色变化
        int[] colors = new int[STRIDE * HEIGHT];
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                int r = x * 255 / (WIDTH - 1);
                int g = y * 255 / (HEIGHT - 1);
                int b = 255 - Math.min(r, g);
                int a = Math.max(r, g);
                colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b;
            }
        }
        return colors;
    }

    public int update(PurgeableBitmap.RefreshHandler handler) {
        try {
            mBitmapArray[mDecodingCount] = BitmapFactory.decodeByteArray(
                bitstream, 0, bitstream.length, mOptions);
            mBitmap = mBitmapArray[mDecodingCount];
            mDecodingCount++;
            if (mDecodingCount < mArraySize) {
                handler.sleep(delay);
                return 0;
            } else {
                return -mDecodingCount;
            }

        } catch (OutOfMemoryError error) {
            for (int i = 0; i < mDecodingCount; i++) {
                mBitmapArray[i].recycle();
            }
            return mDecodingCount + 1;
        }
    }

    @Override protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(mBitmap, 0, 0, null);
        canvas.drawText(String.valueOf(mDecodingCount), WIDTH / 2 - 20,
            HEIGHT / 2, mPaint);
    }

    private byte[] generateBitstream(Bitmap src, Bitmap.CompressFormat format,
            int quality) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        src.compress(format, quality, os);
        return os.toByteArray();
    }

}


阅读更多
个人分类: ApiDemo学习
想对作者说点什么? 我来说一句

android apidemo

2011年08月23日 5.09MB 下载

android ApiDemo

2011年05月17日 96KB 下载

Android API Demo

2014年05月12日 8.61MB 下载

Android ApiDemo

2010年08月16日 4.83MB 下载

Android官方ApiDemo

2017年11月23日 4.89MB 下载

APIdemo源码

2013年10月28日 8.36MB 下载

没有更多推荐了,返回首页

不良信息举报

Apidemo学习 PurgeableBitmap

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭