情況如: /kf/201203/123446.html
模擬器上面getDrawingCache可以返回值,而在真機上面返回null
當我們需要獲取某個View的DrawingCache時回去調用getDrawingCache方法,有同學說可以使用getDrawable;但這兩個是不一樣的,根本上的不一樣暫時還沒去研究,至少getDrawable獲取的是原圖(至少大小是跟原圖一樣大),而getDrawingCache返回的Image是ImageView控件顯示的一個截屏
那麼當getDrawingCache返回null時我們怎麼解決https://www.aiwalls.com/kf/201203/123437.html ,這篇blog說添加如下代碼:
// this is the important code 🙂
// Without it the view will have a dimension of 0,0 and the bitmap will be null
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
後面我發現,如果是你的DrawingCache超過最大Cache,這招管用,如果不是,這招不管用。
現在網上很多遇到的getDrawingCache返回為null都是DrawingCache大小超過Cache大小導致的,但我這裡不是這個問題導致。
我看瞭下View源碼,getDrawingCache是這樣實現的:
public Bitmap getDrawingCache() {
return getDrawingCache(false);
}
我們接著看getDrawingCache(false):
public Bitmap getDrawingCache(boolean autoScale) {
if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
return null;
}
if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
buildDrawingCache(autoScale);
}
return autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) :
(mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
}
如果getDrawingCache返回null,大體兩種可能
1) (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING 這個值為true
2) (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED 為false,buildDrawingCache沒執行
3) buildDrawingCache執行失敗
我們怎麼去粗略的估計是那種原因導致的呢
後面我發現View的willNotCacheDrawing這個方法,代碼如下
public boolean willNotCacheDrawing() {
return (mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING;
}
他返回的就是剛才的第一種情況的那個boolean值,我們可以直接debug查看是否為true,如果該值為true,可以強行轉成false,View.setWillNotCacheDrawing( Boolean.FALSE ).
第二種情況可以看View的 isDrawingCacheEnabled 方法
public boolean isDrawingCacheEnabled() {
return (mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED;
}
如果這個方法為false,那就是之前忘記調用setDrawingCacheEnabled(Boolean.TRUE)方法瞭。
至於第三種,zartzwj『https://www.aiwalls.com/kf/201203/123435.html 』同學有分析,
在buildDrawingCache(boolean)方法中有這樣一段代碼
if (width <= 0 || height <= 0 ||
// Projected bitmap size in bytes
(width * height * (opaque && !translucentWindow ? 2 : 4) >
ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
destroyDrawingCache();
return;
}
很多同學遇到的可能都是這種, (width * height * (opaque && !translucentWindow ? 2 : 4) 大於 ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize()導致buildDrawingCache失敗。
怎麼判斷是否這裡導致的呢,如果你在前面沒有對View的layout自行設置,是程序默認,並且調用的是view.getDrawingCache()或者是view.getDrawingCache(false);
view.getHidth的值就是這兒的width值
view.getHeight的值就是這兒的height
將這兩個值乘以4如果還沒大於ViewConfiguration.get(Context).getScaledMaximumDrawingCacheSize(),那麼就不可能是是DrawingCache大於最大Cache所導致的,
如果乘以4大於瞭,也不一定就是,因為(width * height * (opaque && !translucentWindow ? 2 : 4)有這個變數。
我遇到的是第一種情況,willNotCacheDrawing我沒有調用,使用的默認值,但為什麼在模擬器上面為false,而在真機上就是true瞭呢?現在還不是很清楚
剛接觸android不久,對API不是很熟,各位大牛輕拍
摘自 tonyley3