转自http://www.bangchui.org/read.php?tid=8458

关于如何优化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);

}

更多相关文章

  1. Android(安卓)matrix 控制图片的旋转、缩放、移动
  2. Android中dispatchDraw分析
  3. 锁屏界面
  4. Android异步加载图像小结 (含线程池,缓存方法)
  5. android OpenGL ES2.0编程初学
  6. Android(安卓)主流图片库Picasso Glide Fresco对比分析
  7. android和j2me之清屏(clearScreen)
  8. [置顶] android 图标的绘制
  9. android和j2me之清屏(clearScreen)

随机推荐

  1. Android下常见的内存泄露 经典
  2. Android两种虚拟机区别和联系
  3. Android 沉浸式状态栏实现
  4. android常见漏洞
  5. 客户端(android,ios)与服务器通信
  6. [置顶] Android(安卓)Touch事件的分发过
  7. android 如何调用系统拨打电话的功能
  8. Java乔晓松-android中的手势识别的详解
  9. Android ContentResolver 内容解析者(解
  10. android的 UI 布局总结