您的位置:首页 > 移动开发 > Android开发

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

2015-10-02 05:52 746 查看
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();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: