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

来源:互联网 发布:李羊羊seo 编辑:程序博客网 时间:2024/05/11 21:18
关于如何优化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); 
 

        } 


原创粉丝点击