android UI 最佳化系列之 建立RGB565的緩衝

來源:互聯網
上載者:User

轉自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);

        }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.