当前位置: 代码迷 >> Android >> android UI 优化系列之 创设RGB565的缓存
  详细解决方案

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

热度:43   发布时间:2016-05-01 16:32:26.0
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格式,看看源码先:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
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了,可以用下列方法验证一下:

123456
final Bitmap cache = mContent.getDrawingCache();            if (cache != null) {             Config cfg = cache.getConfig();             Log.d(TAG, "----------------------- cache.getConfig() = " + cfg);?        }

  相关解决方案