android softreference bitmap 为空,Android中view转换为bitmap为null解决方案

本文探讨了在将大型View转换为Bitmap时遇到的问题,分析了内存限制导致的buildDrawingCache失败。提供了两种解决方案:一是调整View尺寸并重建缓存,二是直接在Bitmap上绘制View。同时提到了在滑动视图中的注意事项。
摘要由CSDN通过智能技术生成

前言

我们经常会用到将一个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;

}

width和height是所要cache的view绘制的宽度和高度,所以(width * height * (opaque && !translucentWindow ? 2 : 4)

计算的是当前所需要的cache大小。

ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize()得到的是系统所提供的最大的DrawingCache的值。

当所需要的`drawingCache >系统所提供的最大DrawingCache值时,生成Bitmap就会出现问题,此时获取的Bitmap就为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为空,解决办法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值