我是C++程序员,下面java代码里的
private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
这一句看不懂,在这里声明一个 mSurfaceHolder ,然后调用SurfaceHolder的构造函数来初始化,可是 “{” 后面跟着的代码算什么,C++可没有这种用法

public class SurfaceView extends View {
    static private final String TAG = "SurfaceView";
    static private final boolean DEBUG = false;
    static private final boolean localLOGV = DEBUG ? true : Config.LOGV;    final ArrayList<SurfaceHolder.Callback> mCallbacks
            = new ArrayList<SurfaceHolder.Callback>();    final int[] mLocation = new int[2];
    
    final ReentrantLock mSurfaceLock = new ReentrantLock();
    final Surface mSurface = new Surface();
    boolean mDrawingStopped = true;    final WindowManager.LayoutParams mLayout
            = new WindowManager.LayoutParams();
    IWindowSession mSession;
    MyWindow mWindow;
    final Rect mVisibleInsets = new Rect();
    final Rect mWinFrame = new Rect();
    final Rect mContentInsets = new Rect();    static final int KEEP_SCREEN_ON_MSG = 1;
    static final int GET_NEW_SURFACE_MSG = 2;
    
    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
    
    boolean mIsCreating = false;    final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case KEEP_SCREEN_ON_MSG: {
                    setKeepScreenOn(msg.arg1 != 0);
                } break;
                case GET_NEW_SURFACE_MSG: {
                    handleGetNewSurface();
                } break;
            }
        }
    };
    
    boolean mRequestedVisible = false;
    boolean mWindowVisibility = false;
    boolean mViewVisibility = false;
    int mRequestedWidth = -1;
    int mRequestedHeight = -1;
    int mRequestedFormat = PixelFormat.OPAQUE;
    int mRequestedType = -1;    boolean mHaveFrame = false;
    boolean mDestroyReportNeeded = false;
    boolean mNewSurfaceNeeded = false;
    long mLastLockTime = 0;
    
    boolean mVisible = false;
    int mLeft = -1;
    int mTop = -1;
    int mWidth = -1;
    int mHeight = -1;
    int mFormat = -1;
    int mType = -1;
    final Rect mSurfaceFrame = new Rect();
    private Translator mTranslator;
    
    public SurfaceView(Context context) {
        super(context);
        setWillNotDraw(true);
    }
    
    public SurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setWillNotDraw(true);
    }    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setWillNotDraw(true);
    }
    
    /**
     * Return the SurfaceHolder providing access and control over this
     * SurfaceView's underlying surface.
     * 
     * @return SurfaceHolder The holder of the surface.
     */
    public SurfaceHolder getHolder() {
        return mSurfaceHolder;
    }    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mParent.requestTransparentRegion(this);
        mSession = getWindowSession();
        mLayout.token = getWindowToken();
        mLayout.setTitle("SurfaceView");
        mViewVisibility = getVisibility() == VISIBLE;
    }    @Override
    protected void onWindowVisibilityChanged(int visibility) {
        super.onWindowVisibilityChanged(visibility);
        mWindowVisibility = visibility == VISIBLE;
        mRequestedVisible = mWindowVisibility && mViewVisibility;
        updateWindow(false);
    }    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        mViewVisibility = visibility == VISIBLE;
        mRequestedVisible = mWindowVisibility && mViewVisibility;
        updateWindow(false);
    }
    
    @Override
    protected void onDetachedFromWindow() {
        mRequestedVisible = false;
        updateWindow(false);
        mHaveFrame = false;
        if (mWindow != null) {
            try {
                mSession.remove(mWindow);
            } catch (RemoteException ex) {
            }
            mWindow = null;
        }
        mSession = null;
        mLayout.token = null;        super.onDetachedFromWindow();
    }    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getDefaultSize(mRequestedWidth, widthMeasureSpec);
        int height = getDefaultSize(mRequestedHeight, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }
    
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        updateWindow(false);
    }    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        updateWindow(false);
    }    @Override
    public boolean gatherTransparentRegion(Region region) {
        if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
            return super.gatherTransparentRegion(region);
        }
        
        boolean opaque = true;
        if ((mPrivateFlags & SKIP_DRAW) == 0) {
            // this view draws, remove it from the transparent region
            opaque = super.gatherTransparentRegion(region);
        } else if (region != null) {
            int w = getWidth();
            int h = getHeight();
            if (w>0 && h>0) {
                getLocationInWindow(mLocation);
                // otherwise, punch a hole in the whole hierarchy
                int l = mLocation[0];
                int t = mLocation[1];
                region.op(l, t, l+w, t+h, Region.Op.UNION);
            }
        }
        if (PixelFormat.formatHasAlpha(mRequestedFormat)) {
            opaque = false;
        }
        return opaque;
    }    @Override
    public void draw(Canvas canvas) {
        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
            // draw() is not called when SKIP_DRAW is set
            if ((mPrivateFlags & SKIP_DRAW) == 0) {
                // punch a whole in the view-hierarchy below us
                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
            }
        }
        super.draw(canvas);
    }    @Override
    protected void dispatchDraw(Canvas canvas) {
        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
            // if SKIP_DRAW is cleared, draw() has already punched a hole
            if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
                // punch a whole in the view-hierarchy below us
                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
            }
        }
        // reposition ourselves where the surface is 
        mHaveFrame = true;
        updateWindow(false);
        super.dispatchDraw(canvas);
    }    /**
     * Control whether the surface view's surface is placed on top of another
     * regular surface view in the window (but still behind the window itself).
     * This is typically used to place overlays on top of an underlying media
     * surface view.
     * 
     * <p>Note that this must be set before the surface view's containing
     * window is attached to the window manager.
     * 
     * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
     */
    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
        mWindowType = isMediaOverlay
                ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
    }
    
    /**
     * Control whether the surface view's surface is placed on top of its
     * window.  Normally it is placed behind the window, to allow it to
     * (for the most part) appear to composite with the views in the
     * hierarchy.  By setting this, you cause it to be placed above the
     * window.  This means that none of the contents of the window this
     * SurfaceView is in will be visible on top of its surface.
     * 
     * <p>Note that this must be set before the surface view's containing
     * window is attached to the window manager.
     * 
     * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}.
     */
    public void setZOrderOnTop(boolean onTop) {
        mWindowType = onTop ? WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
    }
    
    /**
     * Hack to allow special layering of windows.  The type is one of the
     * types in WindowManager.LayoutParams.  This is a hack so:
     * @hide
     */
    public void setWindowType(int type) {
        mWindowType = type;
    }    

解决方案 »

  1.   

    new 了一个匿名类..  里面属于内部类. 你搜一下 匿名类,内部类,太多内容了.
      

  2.   

     private void updateWindow(boolean force) {
            if (!mHaveFrame) {
                return;
            }
            ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
            if (viewRoot != null) {
                mTranslator = viewRoot.mTranslator;
            }        Resources res = getContext().getResources();
            if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) {
                mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator);
            }
            
            int myWidth = mRequestedWidth;
            if (myWidth <= 0) myWidth = getWidth();
            int myHeight = mRequestedHeight;
            if (myHeight <= 0) myHeight = getHeight();        getLocationInWindow(mLocation);
            final boolean creating = mWindow == null;
            final boolean formatChanged = mFormat != mRequestedFormat;
            final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
            final boolean visibleChanged = mVisible != mRequestedVisible
                    || mNewSurfaceNeeded;
            final boolean typeChanged = mType != mRequestedType;
            if (force || creating || formatChanged || sizeChanged || visibleChanged
                || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]) {            if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
                        + " format=" + formatChanged + " size=" + sizeChanged
                        + " visible=" + visibleChanged
                        + " left=" + (mLeft != mLocation[0])
                        + " top=" + (mTop != mLocation[1]));            try {
                    final boolean visible = mVisible = mRequestedVisible;
                    mLeft = mLocation[0];
                    mTop = mLocation[1];
                    mWidth = myWidth;
                    mHeight = myHeight;
                    mFormat = mRequestedFormat;
                    mType = mRequestedType;                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
                    
                    // Places the window relative
                    mLayout.x = mLeft;
                    mLayout.y = mTop;
                    mLayout.width = getWidth();
                    mLayout.height = getHeight();
                    if (mTranslator != null) {
                        mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
                    }
                    
                    mLayout.format = mRequestedFormat;
                    mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                                  | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                                  | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                                  | WindowManager.LayoutParams.FLAG_SCALED
                                  | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                                  | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                                  ;
                    if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
                        mLayout.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
                    }                mLayout.memoryType = mRequestedType;                if (mWindow == null) {
                        mWindow = new MyWindow(this);
                        mLayout.type = mWindowType;
                        mLayout.gravity = Gravity.LEFT|Gravity.TOP;
                        mSession.add(mWindow, mLayout,
                                mVisible ? VISIBLE : GONE, mContentInsets);
                    }
                    
                    if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
                        reportSurfaceDestroyed();
                    }
                    
                    mNewSurfaceNeeded = false;
                    
                    mSurfaceLock.lock();
                    mDrawingStopped = !visible;                final int relayoutResult = mSession.relayout(
                        mWindow, mLayout, mWidth, mHeight,
                            visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
                            mVisibleInsets, mSurface);                if (localLOGV) Log.i(TAG, "New surface: " + mSurface
                            + ", vis=" + visible + ", frame=" + mWinFrame);
                    
                    mSurfaceFrame.left = 0;
                    mSurfaceFrame.top = 0;
                    if (mTranslator == null) {
                        mSurfaceFrame.right = mWinFrame.width();
                        mSurfaceFrame.bottom = mWinFrame.height();
                    } else {
                        float appInvertedScale = mTranslator.applicationInvertedScale;
                        mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
                        mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
                    }
                    mSurfaceLock.unlock();                try {
                        if (visible) {
                            mDestroyReportNeeded = true;                        SurfaceHolder.Callback callbacks[];
                            synchronized (mCallbacks) {
                                callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
                                mCallbacks.toArray(callbacks);
                            }                        if (visibleChanged) {
                                mIsCreating = true;
                                for (SurfaceHolder.Callback c : callbacks) {
                                    c.surfaceCreated(mSurfaceHolder);
                                }
                            }
                            if (creating || formatChanged || sizeChanged
                                    || visibleChanged) {
                                for (SurfaceHolder.Callback c : callbacks) {
                                    c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
                                }
                            }
                        }
                    } finally {
                        mIsCreating = false;
                        if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
                            mSession.finishDrawing(mWindow);
                        }
                    }
                } catch (RemoteException ex) {
                }
                if (localLOGV) Log.v(
                    TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
                    " w=" + mLayout.width + " h=" + mLayout.height +
                    ", frame=" + mSurfaceFrame);
            }
        }    private void reportSurfaceDestroyed() {
            if (mDestroyReportNeeded) {
                mDestroyReportNeeded = false;
                SurfaceHolder.Callback callbacks[];
                synchronized (mCallbacks) {
                    callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
                    mCallbacks.toArray(callbacks);
                }            
                for (SurfaceHolder.Callback c : callbacks) {
                    c.surfaceDestroyed(mSurfaceHolder);
                }
            }
            super.onDetachedFromWindow();
        }    void handleGetNewSurface() {
            mNewSurfaceNeeded = true;
            updateWindow(false);
        }  
      

  3.   

    private static class MyWindow extends BaseIWindow {
            private final WeakReference<SurfaceView> mSurfaceView;        public MyWindow(SurfaceView surfaceView) {
                mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
            }        public void resized(int w, int h, Rect coveredInsets,
                    Rect visibleInsets, boolean reportDraw) {
                SurfaceView surfaceView = mSurfaceView.get();
                if (surfaceView != null) {
                    if (localLOGV) Log.v(
                            "SurfaceView", surfaceView + " got resized: w=" +
                                    w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
                    synchronized (this) {
                        if (mCurWidth != w || mCurHeight != h) {
                            mCurWidth = w;
                            mCurHeight = h;
                        }
                        if (reportDraw) {
                            try {
                                surfaceView.mSession.finishDrawing(surfaceView.mWindow);
                            } catch (RemoteException e) {
                            }
                        }
                    }
                }
            }        public void dispatchKey(KeyEvent event) {
                SurfaceView surfaceView = mSurfaceView.get();
                if (surfaceView != null) {
                    //Log.w("SurfaceView", "Unexpected key event in surface: " + event);
                    if (surfaceView.mSession != null && surfaceView.mSurface != null) {
                        try {
                            surfaceView.mSession.finishKey(surfaceView.mWindow);
                        } catch (RemoteException ex) {
                        }
                    }
                }
            }        public void dispatchPointer(MotionEvent event, long eventTime,
                    boolean callWhenDone) {
                Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
                //if (mSession != null && mSurface != null) {
                //    try {
                //        //mSession.finishKey(mWindow);
                //    } catch (RemoteException ex) {
                //    }
                //}
            }        public void dispatchTrackball(MotionEvent event, long eventTime,
                    boolean callWhenDone) {
                Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
                //if (mSession != null && mSurface != null) {
                //    try {
                //        //mSession.finishKey(mWindow);
                //    } catch (RemoteException ex) {
                //    }
                //}
            }        public void dispatchAppVisibility(boolean visible) {
                // The point of SurfaceView is to let the app control the surface.
            }        public void dispatchGetNewSurface() {
                SurfaceView surfaceView = mSurfaceView.get();
                if (surfaceView != null) {
                    Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
                    surfaceView.mHandler.sendMessage(msg);
                }
            }        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
                Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
            }        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
            }        int mCurWidth = -1;
            int mCurHeight = -1;
        }    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
            
            private static final String LOG_TAG = "SurfaceHolder";
            private int mSaveCount;
            
            public boolean isCreating() {
                return mIsCreating;
            }        public void addCallback(Callback callback) {
                synchronized (mCallbacks) {
                    // This is a linear search, but in practice we'll 
                    // have only a couple callbacks, so it doesn't matter.
                    if (mCallbacks.contains(callback) == false) {      
                        mCallbacks.add(callback);
                    }
                }
            }        public void removeCallback(Callback callback) {
                synchronized (mCallbacks) {
                    mCallbacks.remove(callback);
                }
            }
            
            public void setFixedSize(int width, int height) {
                if (mRequestedWidth != width || mRequestedHeight != height) {
                    mRequestedWidth = width;
                    mRequestedHeight = height;
                    requestLayout();
                }
            }        public void setSizeFromLayout() {
                if (mRequestedWidth != -1 || mRequestedHeight != -1) {
                    mRequestedWidth = mRequestedHeight = -1;
                    requestLayout();
                }
            }        public void setFormat(int format) {
                mRequestedFormat = format;
                if (mWindow != null) {
                    updateWindow(false);
                }
            }        public void setType(int type) {
                switch (type) {
                case SURFACE_TYPE_HARDWARE:
                case SURFACE_TYPE_GPU:
                    // these are deprecated, treat as "NORMAL"
                    type = SURFACE_TYPE_NORMAL;
                    break;
                }
                switch (type) {
                case SURFACE_TYPE_NORMAL:
                case SURFACE_TYPE_PUSH_BUFFERS:
                    mRequestedType = type;
                    if (mWindow != null) {
                        updateWindow(false);
                    }
                    break;
                }
            }        public void setKeepScreenOn(boolean screenOn) {
                Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
                msg.arg1 = screenOn ? 1 : 0;
                mHandler.sendMessage(msg);
            }
            
            public Canvas lockCanvas() {
                return internalLockCanvas(null);
            }        public Canvas lockCanvas(Rect dirty) {
                return internalLockCanvas(dirty);
            }        private final Canvas internalLockCanvas(Rect dirty) {
                if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
                    throw new BadSurfaceTypeException(
                            "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
                }
                mSurfaceLock.lock();            if (localLOGV) Log.i(TAG, "Locking canvas... stopped="
                        + mDrawingStopped + ", win=" + mWindow);            Canvas c = null;
                if (!mDrawingStopped && mWindow != null) {
                    Rect frame = dirty != null ? dirty : mSurfaceFrame;
                    try {
                        c = mSurface.lockCanvas(frame);
                    } catch (Exception e) {
                        Log.e(LOG_TAG, "Exception locking surface", e);
                    }
                }            if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
                if (c != null) {
                    mLastLockTime = SystemClock.uptimeMillis();
                    return c;
                }
                
                // If the Surface is not ready to be drawn, then return null,
                // but throttle calls to this function so it isn't called more
                // than every 100ms.
                long now = SystemClock.uptimeMillis();
                long nextTime = mLastLockTime + 100;
                if (nextTime > now) {
                    try {
                        Thread.sleep(nextTime-now);
                    } catch (InterruptedException e) {
                    }
                    now = SystemClock.uptimeMillis();
                }
                mLastLockTime = now;
                mSurfaceLock.unlock();
                
                return null;
            }        public void unlockCanvasAndPost(Canvas canvas) {
                mSurface.unlockCanvasAndPost(canvas);
                mSurfaceLock.unlock();
            }        public Surface getSurface() {
                return mSurface;
            }        public Rect getSurfaceFrame() {
                return mSurfaceFrame;
            }
        };
    }
      

  4.   


    还有一个 文件声明 Interface 
    public interface SurfaceHolder {可是这里没有写 implemnets SurfaceHolder ,这个实现和interface有关系吗?
      

  5.   

    SurfaceHolder这个类应该是抽象类或者接口,private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {代码块}代码块里头是实现,就比如说有点像C++类中的虚函数吧?你要实现它才可以使用,这里就换成了类,相当于"虚类",不能直接实例化,要实现其“虚函数”。简单来说的话其实这是匿名内部类的一个用法,楼主详细可以谷歌或者百度一下,表达得不是很好,请见谅了。
      

  6.   

    匿名内部类。。
    虽然没有implements
    但是实现和interface有关系。
      

  7.   

    THINKING IN JAVA
    里面有详细介绍匿名内部类的用法.
      

  8.   

      匿名内部类中没有构造方法,但是可以调用父类中的构造方法,是通过new关键字在创建匿名对象的时候自动调用
      

  9.   

    interface 是指所声明的是接口类型,implemnets SurfaceHolder 是某一个类去实现声明的SurfaceHolder 接口里的方法!
      

  10.   

    因为你那个类是个接口,那样new ,相当于实现了这个抽象类,只是没给这个新类命名. 但是必须实现所有抽象方法. 
      

  11.   

    找一本java入门的好书,这些问题就没有了,C++和java虽然都是面向对象,但是语法上还是有很大差别的
      

  12.   

    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
    }
    这是创建一个类的实例并且实现··当然··实现内部可以不放代码·那就是空实现··明白?之所以加{}`我想是程序员的疏忽或者是因为SurfaceHolder 本身不仅仅是一个类·还是一个接口··我记得老马在教程里说过这个·
      

  13.   

    private void updateWindow(boolean force) {
      if (!mHaveFrame) {
      return;
      }
      ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
      if (viewRoot != null) {
      mTranslator = viewRoot.mTranslator;
      }  Resources res = getContext().getResources();
      if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) {
      mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator);
      }
        
      int myWidth = mRequestedWidth;
      if (myWidth <= 0) myWidth = getWidth();
      int myHeight = mRequestedHeight;
      if (myHeight <= 0) myHeight = getHeight();  getLocationInWindow(mLocation);
      final boolean creating = mWindow == null;
      final boolean formatChanged = mFormat != mRequestedFormat;
      final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
      final boolean visibleChanged = mVisible != mRequestedVisible
      || mNewSurfaceNeeded;
      final boolean typeChanged = mType != mRequestedType;
      if (force || creating || formatChanged || sizeChanged || visibleChanged
      || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]) {  if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
      + " format=" + formatChanged + " size=" + sizeChanged
      + " visible=" + visibleChanged
      + " left=" + (mLeft != mLocation[0])
      + " top=" + (mTop != mLocation[1]));  try {
      final boolean visible = mVisible = mRequestedVisible;
      mLeft = mLocation[0];
      mTop = mLocation[1];
      mWidth = myWidth;
      mHeight = myHeight;
      mFormat = mRequestedFormat;
      mType = mRequestedType;  // Scaling/Translate window's layout here because mLayout is not used elsewhere.
        
      // Places the window relative
      mLayout.x = mLeft;
      mLayout.y = mTop;
      mLayout.width = getWidth();
      mLayout.height = getHeight();
      if (mTranslator != null) {
      mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
      }
        
      mLayout.format = mRequestedFormat;
      mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
      | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
      | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
      | WindowManager.LayoutParams.FLAG_SCALED
      | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
      | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
      ;
      if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
      mLayout.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
      }  mLayout.memoryType = mRequestedType;  if (mWindow == null) {
      mWindow = new MyWindow(this);
      mLayout.type = mWindowType;
      mLayout.gravity = Gravity.LEFT|Gravity.TOP;
      mSession.add(mWindow, mLayout,
      mVisible ? VISIBLE : GONE, mContentInsets);
      }
        
      if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
      reportSurfaceDestroyed();
      }
        
      mNewSurfaceNeeded = false;
        
      mSurfaceLock.lock();
      mDrawingStopped = !visible;  final int relayoutResult = mSession.relayout(
      mWindow, mLayout, mWidth, mHeight,
      visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
      mVisibleInsets, mSurface);  if (localLOGV) Log.i(TAG, "New surface: " + mSurface
      + ", vis=" + visible + ", frame=" + mWinFrame);
        
      mSurfaceFrame.left = 0;
      mSurfaceFrame.top = 0;
      if (mTranslator == null) {
      mSurfaceFrame.right = mWinFrame.width();
      mSurfaceFrame.bottom = mWinFrame.height();
      } else {
      float appInvertedScale = mTranslator.applicationInvertedScale;
      mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
      mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
      }
      mSurfaceLock.unlock();  try {
      if (visible) {
      mDestroyReportNeeded = true;  SurfaceHolder.Callback callbacks[];
      synchronized (mCallbacks) {
      callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
      mCallbacks.toArray(callbacks);
      }  if (visibleChanged) {
      mIsCreating = true;
      for (SurfaceHolder.Callback c : callbacks) {
      c.surfaceCreated(mSurfaceHolder);
      }
      }
      if (creating || formatChanged || sizeChanged
      || visibleChanged) {
      for (SurfaceHolder.Callback c : callbacks) {
      c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
      }
      }
      }
      } finally {
      mIsCreating = false;
      if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
      mSession.finishDrawing(mWindow);
      }
      }
      } catch (RemoteException ex) {
      }
      if (localLOGV) Log.v(
      TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
      " w=" + mLayout.width + " h=" + mLayout.height +
      ", frame=" + mSurfaceFrame);
      }
      }  private void reportSurfaceDestroyed() {
      if (mDestroyReportNeeded) {
      mDestroyReportNeeded = false;
      SurfaceHolder.Callback callbacks[];
      synchronized (mCallbacks) {
      callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
      mCallbacks.toArray(callbacks);
      }   
      for (SurfaceHolder.Callback c : callbacks) {
      c.surfaceDestroyed(mSurfaceHolder);
      }
      }
      super.onDetachedFromWindow();
      }  void handleGetNewSurface() {
      mNewSurfaceNeeded = true;
      updateWindow(false);
      }  
      

  14.   

    private static class MyWindow extends BaseIWindow {
      private final WeakReference<SurfaceView> mSurfaceView;  public MyWindow(SurfaceView surfaceView) {
      mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
      }  public void resized(int w, int h, Rect coveredInsets,
      Rect visibleInsets, boolean reportDraw) {
      SurfaceView surfaceView = mSurfaceView.get();
      if (surfaceView != null) {
      if (localLOGV) Log.v(
      "SurfaceView", surfaceView + " got resized: w=" +
      w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
      synchronized (this) {
      if (mCurWidth != w || mCurHeight != h) {
      mCurWidth = w;
      mCurHeight = h;
      }
      if (reportDraw) {
      try {
      surfaceView.mSession.finishDrawing(surfaceView.mWindow);
      } catch (RemoteException e) {
      }
      }
      }
      }
      }  public void dispatchKey(KeyEvent event) {
      SurfaceView surfaceView = mSurfaceView.get();
      if (surfaceView != null) {
      //Log.w("SurfaceView", "Unexpected key event in surface: " + event);
      if (surfaceView.mSession != null && surfaceView.mSurface != null) {
      try {
      surfaceView.mSession.finishKey(surfaceView.mWindow);
      } catch (RemoteException ex) {
      }
      }
      }
      }  public void dispatchPointer(MotionEvent event, long eventTime,
      boolean callWhenDone) {
      Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
      //if (mSession != null && mSurface != null) {
      // try {
      // //mSession.finishKey(mWindow);
      // } catch (RemoteException ex) {
      // }
      //}
      }  public void dispatchTrackball(MotionEvent event, long eventTime,
      boolean callWhenDone) {
      Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
      //if (mSession != null && mSurface != null) {
      // try {
      // //mSession.finishKey(mWindow);
      // } catch (RemoteException ex) {
      // }
      //}
      }  public void dispatchAppVisibility(boolean visible) {
      // The point of SurfaceView is to let the app control the surface.
      }  public void dispatchGetNewSurface() {
      SurfaceView surfaceView = mSurfaceView.get();
      if (surfaceView != null) {
      Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
      surfaceView.mHandler.sendMessage(msg);
      }
      }  public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
      Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
      }  public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
      }  int mCurWidth = -1;
      int mCurHeight = -1;
      }  private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
        
      private static final String LOG_TAG = "SurfaceHolder";
      private int mSaveCount;
        
      public boolean isCreating() {
      return mIsCreating;
      }  public void addCallback(Callback callback) {
      synchronized (mCallbacks) {
      // This is a linear search, but in practice we'll  
      // have only a couple callbacks, so it doesn't matter.
      if (mCallbacks.contains(callback) == false) {   
      mCallbacks.add(callback);
      }
      }
      }  public void removeCallback(Callback callback) {
      synchronized (mCallbacks) {
      mCallbacks.remove(callback);
      }
      }
        
      public void setFixedSize(int width, int height) {
      if (mRequestedWidth != width || mRequestedHeight != height) {
      mRequestedWidth = width;
      mRequestedHeight = height;
      requestLayout();
      }
      }  public void setSizeFromLayout() {
      if (mRequestedWidth != -1 || mRequestedHeight != -1) {
      mRequestedWidth = mRequestedHeight = -1;
      requestLayout();
      }
      }  public void setFormat(int format) {
      mRequestedFormat = format;
      if (mWindow != null) {
      updateWindow(false);
      }
      }  public void setType(int type) {
      switch (type) {
      case SURFACE_TYPE_HARDWARE:
      case SURFACE_TYPE_GPU:
      // these are deprecated, treat as "NORMAL"
      type = SURFACE_TYPE_NORMAL;
      break;
      }
      switch (type) {
      case SURFACE_TYPE_NORMAL:
      case SURFACE_TYPE_PUSH_BUFFERS:
      mRequestedType = type;
      if (mWindow != null) {
      updateWindow(false);
      }
      break;
      }
      }  public void setKeepScreenOn(boolean screenOn) {
      Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
      msg.arg1 = screenOn ? 1 : 0;
      mHandler.sendMessage(msg);
      }
        
      public Canvas lockCanvas() {
      return internalLockCanvas(null);
      }  public Canvas lockCanvas(Rect dirty) {
      return internalLockCanvas(dirty);
      }  private final Canvas internalLockCanvas(Rect dirty) {
      if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
      throw new BadSurfaceTypeException(
      "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
      }
      mSurfaceLock.lock();  if (localLOGV) Log.i(TAG, "Locking canvas... stopped="
      + mDrawingStopped + ", win=" + mWindow);  Canvas c = null;
      if (!mDrawingStopped && mWindow != null) {
      Rect frame = dirty != null ? dirty : mSurfaceFrame;
      try {
      c = mSurface.lockCanvas(frame);
      } catch (Exception e) {
      Log.e(LOG_TAG, "Exception locking surface", e);
      }
      }  if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
      if (c != null) {
      mLastLockTime = SystemClock.uptimeMillis();
      return c;
      }
        
      // If the Surface is not ready to be drawn, then return null,
      // but throttle calls to this function so it isn't called more
      // than every 100ms.
      long now = SystemClock.uptimeMillis();
      long nextTime = mLastLockTime + 100;
      if (nextTime > now) {
      try {
      Thread.sleep(nextTime-now);
      } catch (InterruptedException e) {
      }
      now = SystemClock.uptimeMillis();
      }
      mLastLockTime = now;
      mSurfaceLock.unlock();
        
      return null;
      }  public void unlockCanvasAndPost(Canvas canvas) {
      mSurface.unlockCanvasAndPost(canvas);
      mSurfaceLock.unlock();
      }  public Surface getSurface() {
      return mSurface;
      }  public Rect getSurfaceFrame() {
      return mSurfaceFrame;
      }
      };
    }
      

  15.   

    private SurfaceHolder mSurfaceHolder = new SurfaceHolder(){}是个匿名内部类
      

  16.   

    内部类的用法,不一定是抽象类和接口,普通的类也可以的,但是final的类是不行的,就相当与你创建了一个新的类,继承或者实现了类/接口,同时创建了一个对象,因为没有名字,所以只用一次,称为匿名内部类,通常用于监听器,做事件处理用途,其实就是一个行为的注入,JAVA里面变相的闭包实现,虽然麻烦了点,但总体来说还是遵循了OO思想
      

  17.   

    class Hello implements SurfaceHolder是表示Hello这个类实现了SurfaceHolder 这个接口
    而public interface SurfaceHolder{}是声明一个接口
      

  18.   

    建议楼主看一下关于JAVA方面的书。不然会很混乱的。JAVA核心技术
      

  19.   

    匿名类,内部类等
    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {};
    通常在大括号内要实现接口的方法,一般这种写法用在回调函数中,
    swing就有很多匿名内部类的写法。
    建议楼主稍微看下J2SE相关内容。还有Java不是C++,C++也不是Java.
    不要混为一谈