Android Api Demos登顶之路(八十五)Graphics-->PurgeableBitmap

BitmapFactory.Option 由一个属性public boolean inPurgeable
如果inPurgeable 设为True表示使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间
在系统内存不足时可以被回收,设为false时不能被回收。本例演示了此参数设为true和false时的不同
示例。
activity.main

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/layout" >

    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button 
            android:onClick="nonPurgeable"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="NonPurgeable"/>

        <Button 
            android:onClick="purgeable"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Purgeable"/>
    </LinearLayout>

</LinearLayout>

PurgeableBitmapView

public class PurgeableBitmapView extends View {
    // 将位图压缩成二进制流
    private byte[] bitStream;
    private Bitmap mBitmap;
    private int mArraySize = 200;
    private Bitmap[] mBitmapArray = new Bitmap[mArraySize];
    private Options mOptions = new Options();

    private static final int WIDTH = 150;
    private static final int HEIGHT = 360;
    private static final int STRIDE = 320;

    // 正在解析的位图的序号
    private int mDecodingCount = 0;
    private Paint mPaint = new Paint();
    private int textSize = 32;
    private 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);
        mBitmap=src;
        // 将位图压缩为JPEG格式的流
        bitStream = generateBitStream(src, Bitmap.CompressFormat.JPEG, 80);

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

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

    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;
    }

    @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);
    }

    // 刷新位图上显示的内容
    public int update(MainActivity.RefreshHandler handler) {
        try {
            // 从二进制数据流中解析位图
            mBitmapArray[mDecodingCount] = BitmapFactory.decodeByteArray(bitStream,
                    0, bitStream.length, mOptions);
            mBitmap=mBitmapArray[mDecodingCount];
            mDecodingCount++;
            if(mDecodingCount<mArraySize){
                //如果解析成功,且还没有解析完所有位图,则延迟100毫秒,重新发送消息后返回零
                handler.sleep(delay);
                return 0;
            }else{
                return -mDecodingCount;
            }
        } catch (OutOfMemoryError e) {
            //出现内存错误异常后,回收所有的位图
            for(int i=0;i<mDecodingCount-1;i++){
                mBitmapArray[i].recycle();
            }
            return mDecodingCount+1;
        }
    }

}

MainActivity

public class MainActivity extends Activity {
    private PurgeableBitmapView mView;
    private RefreshHandler mRefreshHandler = new RefreshHandler();

    class RefreshHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            int index = mView.update(this);
            if (index > 0) {
                showAlterDialog(getDialogMessage(true, index));
            }else if(index<0){
                //绘制出最后一个位图的序号(200)
                mView.invalidate();
                showAlterDialog(getDialogMessage(false, -index));
            }else{
                //当index为0时表示位图正常被解析,则需要重新初始化视图界面,刷新界面上显示的内容
                mView.invalidate();
            }
        }

        public void sleep(long delayMillis) {
            this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), delayMillis);
        }
    }

    private LinearLayout layout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layout=(LinearLayout) findViewById(R.id.layout);
        //mRefreshHandler.sleep(0);
    }

    public void nonPurgeable(View v){
        if(mView!=null){
            layout.removeView(mView);
        }
        mView=new PurgeableBitmapView(this, false);
        layout.addView(mView);
        mRefreshHandler.sleep(0);
    }

    public void purgeable(View v){
        if(mView!=null){
            layout.removeView(mView);
        }
        mView=new PurgeableBitmapView(this, true);
        layout.addView(mView);
        mRefreshHandler.sleep(0);
    }
    public void showAlterDialog(String message) {
        AlertDialog.Builder builder=new Builder(this);
        builder.setMessage(message)
               .setCancelable(false)
               .setPositiveButton("Yes", new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                }
            });
        builder.show();
    }

    public 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();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值