android Surface概述

  Surface的主要作用是存储View树的绘制数据,主要由屏幕组合器管理(screen compositor),每个Window都有一个Surface。

 android中Surface分为两种:

   一、Java层surface

   二、Native层Surface

    Java层产生Surface的主要有两个地方:ViewRoot和SurfaceView。

   Native层主要由NativeWindow产生。

 Surface是如何和View树搭上关系的呢?

 不过相信大家对View中的draw()方法一定很熟悉!

   boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {

      }
   protected void onDraw(Canvas canvas) {
     }

 draw里面的Canvas都是由Framework传递来的参数,那么Canvas就是View树和Surface的连接点。

 View树的测绘(measure)、布局(layout)和绘制(draw)都是由ViewRoot发起和管理的,View树绘制起点由ViewRoot的drawSoftware开始的!

 drawSoftware的方法体大致如下:

 private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
            boolean scalingRequired, Rect dirty) {

        // Draw with software renderer.
        final Canvas canvas;
 
         canvas = mSurface.lockCanvas(dirty);//获取Canvas

        try {
            if (!canvas.isOpaque() || yoff != 0 || xoff != 0) {
                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
            }

            dirty.setEmpty();
            mIsAnimating = false;
            attachInfo.mDrawingTime = SystemClock.uptimeMillis();
            mView.mPrivateFlags |= View.PFLAG_DRAWN;

            if (DEBUG_DRAW) {
                Context cxt = mView.getContext();
            }
            try {
                canvas.translate(-xoff, -yoff);
                if (mTranslator != null) {
                    mTranslator.translateCanvas(canvas);
                }
                canvas.setScreenDensity(scalingRequired ? mNoncompatDensity : 0);
                attachInfo.mSetIgnoreDirtyState = false;
                mView.draw(canvas);//绘制view树
                drawAccessibilityFocusedDrawableIfNeeded(canvas);
            } finally {
                if (!attachInfo.mSetIgnoreDirtyState) {
                    // Only clear the flag if it was not set during the mView.draw() call
                    attachInfo.mIgnoreDirtyState = false;
                }
            }
        } finally {
            try {
                surface.unlockCanvasAndPost(canvas);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Could not unlock surface", e);
                mLayoutRequested = true;    // ask wm for a new surface next time.
                //noinspection ReturnInsideFinallyBlock
                return false;
            }
        }
        return true;
    }


posted @ 2016-10-26 17:42  清澈见底  阅读(838)  评论(0编辑  收藏  举报