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
PurgeableBitmapView
MainActivity
如果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(); } }
相关文章推荐
- Android进程和线程
- Android官方教程中文版
- 自定义对话框
- Android 简单计算器的实现
- Ubuntu12.04 64bit 下载android4.3源代码
- Android环境搭建中遇到的小问题
- 如何将android studio设置复位,将设置恢复到初始化
- Android文件关联之Mime Type
- AIDL跨进程通信在Android的应用
- 使用命令行安装安卓应用
- activity view 截图
- Android之平时遇见的异常和错误总结(不断更新)
- ANDROID 序列化Parcelable /Serializalble
- android jni 引用第三方 so
- 安卓assets目录下sharesdk.xml修改无效的问题
- Android Studio
- Android 搭建(Servlet)服务器端 实现用户登录
- Android控件:ScrollView的使用,滑动到底部的监听
- android studio在模拟器上的中文乱码问题解决方法
- android按钮事件触发拨号器