android UI 优化系列之 创建RGB565的缓存

关于如何优化activity的启动速度, view 的绘制速度, 可参考这个sdk里的文档。 android-sdk-windows-1.5_r1/docs/resources/articles/window-bg-speed.html。  
看完后你就知道 android:windowBackground 太重要了,影响到绘制效率。  
这里要说的是另外一点, 不是这个windowBackground 。  
android 为了提高滚动等各方面的绘制速度,可以为每一个view建立一个缓存,使用 View.buildDrawingCache为自己的view 建立相应的缓存,  
这个所谓的缓存,实际上就是一个Bitmap对象。只是 这个 bitmap 对象可以有多种格式而已,如  
     Bitmap.Config.ARGB_8888;  
     Bitmap.Config.ARGB_4444;  
     Bitmap.Config.ARGB_8888;  
     Bitmap.Config.ARGB_8888;  
     Bitmap.Config.RGB_565;  
   默认的格式是Bitmap.Config.ARGB_8888.,但大多数嵌入式设备使用的显示格式都是Bitmap.Config.RGB_565. 对于后者, 并没有  
alpha 值,所以绘制的时候不需要计算alpha合成,速递当让快些。其次,RGB_565可以直接使用优化了的memcopy函数,效率相对高出许多。  
 
 
  所以, 在用buildDrawingCache建立缓存时, 可以使用RGB_565格式。但是如何制定这个格式呢 ?buildDrawingCache有两个版本,      buildDrawingCache(boolean)  和  buildDrawingCache()。并没有任何参数可以设置rgb格式,看看源码先:  
 
public void buildDrawingCache(boolean autoScale) {  
        if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ?  
                (mDrawingCache == null || mDrawingCache.get() == null) :  
                (mUnscaledDrawingCache == null || mUnscaledDrawingCache.get() == null))) {  
            if (ViewDebug.TRACE_HIERARCHY) {  
                ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);  
            }  
            if (Config.DEBUG && ViewDebug.profileDrawing) {  
                EventLog.writeEvent(60002, hashCode());  
            }  
            int width = mRight - mLeft;  
            int height = mBottom - mTop;  
            final AttachInfo attachInfo = mAttachInfo;  
            final boolean scalingRequired = attachInfo != null && attachInfo.mScalingRequired;  
            if (autoScale && scalingRequired) {  
                width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);  
                height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);  
            }  
            final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;  
              final boolean opaque = drawingCacheBackgroundColor != 0 ||  
                (mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE);  
            if (width <= 0 || height <= 0 ||  
                    (width * height * (opaque ? 2 : 4) > // Projected bitmap size in bytes  
                            ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {  
                destroyDrawingCache();  
                return;  
            }  
            boolean clear = true;  
            Bitmap bitmap = autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) :  
                    (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());  
            if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {  
                Bitmap.Config quality;  
                 if (!opaque) {  
                    switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {  
                        case DRAWING_CACHE_QUALITY_AUTO:  
                            quality = Bitmap.Config.ARGB_8888;  
                            break;  
                        case DRAWING_CACHE_QUALITY_LOW:  
                            quality = Bitmap.Config.ARGB_4444;  
                            break;  
                        case DRAWING_CACHE_QUALITY_HIGH:  
                            quality = Bitmap.Config.ARGB_8888;  
                            break;  
                        default:  
                            quality = Bitmap.Config.ARGB_8888;  
                            break;  
                    }  
                } else {  
                    quality = Bitmap.Config.RGB_565;  
                }  
                // Try to cleanup memory  
                if (bitmap != null) bitmap.recycle();  
                try {  
                    bitmap = Bitmap.createBitmap(width, height, quality);  
                    bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);  
                    if (autoScale) {  
                        mDrawingCache = new SoftReference<Bitmap>(bitmap);  
                    } else {  
                        mUnscaledDrawingCache = new SoftReference<Bitmap>(bitmap);  
                    }  
                } catch (OutOfMemoryError e) {  
                    // If there is not enough memory to create the bitmap cache, just  
                    // ignore the issue as bitmap caches are not required to draw the  
                    // view hierarchy  
                    if (autoScale) {  
                        mDrawingCache = null;  
                    } else {  
                        mUnscaledDrawingCache = null;  
                    }  
                    return;  
                }  
                clear = drawingCacheBackgroundColor != 0;  
            }  
            Canvas canvas;  
            if (attachInfo != null) {  
                canvas = attachInfo.mCanvas;  
                if (canvas == null) {  
                    canvas = new Canvas();  
                }  
                canvas.setBitmap(bitmap);  
                // Temporarily clobber the cached Canvas in case one of our children  
                // is also using a drawing cache. Without this, the children would  
                // steal the canvas by attaching their own bitmap to it and bad, bad  
                // thing would happen (invisible views, corrupted drawings, etc.)  
                attachInfo.mCanvas = null;  
            } else {  
                // This case should hopefully never or seldom happen  
                canvas = new Canvas(bitmap);  
            }  
            if (clear) {  
                bitmap.eraseColor(drawingCacheBackgroundColor);  
            }  
            computeScroll();  
            final int restoreCount = canvas.save();  
            if (autoScale && scalingRequired) {  
                final float scale = attachInfo.mApplicationScale;  
                canvas.scale(scale, scale);  
            }  
            canvas.translate(-mScrollX, -mScrollY);  
            mPrivateFlags |= DRAWN;  
            // Fast path for layouts with no backgrounds  
            if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {  
                if (ViewDebug.TRACE_HIERARCHY) {  
                    ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);  
                }  
                mPrivateFlags &= ~DIRTY_MASK;  
                dispatchDraw(canvas);  
            } else {  
                draw(canvas);  
            }  
            canvas.restoreToCount(restoreCount);  
            if (attachInfo != null) {  
                // Restore the cached Canvas for our siblings  
                attachInfo.mCanvas = canvas;  
            }  
            mPrivateFlags |= DRAWING_CACHE_VALID;  
        }  
    }  
 
看完后明白了,至少跟两个因素有关  drawingCacheBackgroundColor 和 mBGDrawable.  
用setDrawingCacheBackgroundColor(0xffff0000)设置为 非默认颜色后,建立的缓存就是rgb565了,可以用下列方法验证一下:  
 
final Bitmap cache = mContent.getDrawingCache();  
            if (cache != null) {  
             Config cfg = cache.getConfig();  
             Log.d(TAG, "----------------------- cache.getConfig() = " + cfg);  
 

        } 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值