Android中view转换为bitmap为null解决方案

来源:互联网 发布:618淘宝也买酒 编辑:程序博客网 时间:2024/04/30 05:11

前言

我们经常会用到将一个View转换为Bitmap的情景,比如截屏保存到本地,比如一些动态的实时View为便于观察和记录数据、需要临时生成静态的Bitmap等等。
我们一般都会这样写:

public static Bitmap convertViewToBitmap(View view){       view.buildDrawingCache();    Bitmap bitmap = view.getDrawingCache();    return bitmap; }

一般情况这种是没有问题的,但是view过大的话,就会buildDrawingCache()失败,当然我们getDrawingCache()得到的bitmap就为null了!

原因

那么为什么会出现这种情况呢?我们可以从源码中看到:
buildDrawingCache(boolean autoScale)
—->buildDrawingCacheImpl(boolean autoScale)

final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);final long drawingCacheSize =ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {    if (width > 0 && height > 0) {        Log.w(VIEW_LOG_TAG, getClass().getSimpleName() + " not displayed because it is"                        + " too large to fit into a software layer (or drawing cache), needs "                        + projectedBitmapSize + " bytes, only "                        + drawingCacheSize + " available");    }    destroyDrawingCache();    mCachingFailed = true;    return;}

widthheight是所要cache的view绘制的宽度和高度,所以(width * height * (opaque && !use32BitCache ? 2 : 4)
计算的是当前所需要的cache大小。
ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize()得到的是系统所提供的最大的DrawingCache的值
当所需要的`drawingCache >系统所提供的最大DrawingCache值时,生成Bitmap就会出现问题,此时获取的Bitmap就为null。

解决方案

我在stackoverflow上面找到一个类似的回答:
Android View.getDrawingCache returns null, only null
所以,我们应该这样写:

public static Bitmap convertViewToBitmap(View view){    view.setDrawingCacheEnabled(true);    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());    view.buildDrawingCache();    Bitmap bitmap = view.getDrawingCache();    view.setDrawingCacheEnabled(false);      return bitmap;    }

替代方案

从源码中可以看到buildDrawingCache过程貌似就是利用获得View的Canvas然后画到bitmap上,直接返回对应的bitmap,这样一来,就是我们用getDrawingCache获得的bitmap;跟我们直接将View画到bitmap区别不是很大,所以我们可以自己直接画:

public static Bitmap convertViewToBitmap(View view) {      Bitmap bitmap= Bitmap.createBitmap(view.getWidth(), view.getHeight(), HDConstantSet.BITMAP_QUALITY);      Canvas canvas = new Canvas(bitmap);      view.draw(canvas);      return bitmap;  }

另外可能要这样的问题:就是在滑动的view中这样操作的话会产生问题,具体的可以参照这篇博客:
View的getDrawingCache为空,解决办法

参考文章:
Android中View转换为Bitmap及getDrawingCache=null的解决方法

1 0
原创粉丝点击