概览

当 SurfaceView 不可见时,会执行 SurfaceView 的释放,它会销毁 Surface 与 SurfaceControl。 下一次可见时,再创建新的 Surface 与 SurfaceControl。

基于 Android 12

SurfaceView 与 Layer 关系

先看一下 SurfaceView 与 SurfaceFlinger 中对应 layer 的关系图。

SurfaceView 对象有成员 mBlastSurfaceControl,SurfaceControl Java 对象对应一个 SurfaceControl native 对象。SurfaceControl native 对象有成员 mHandle,它是一个 BpBinder。

mHandle 是在创建 layer 时,从 SurfaceFlinger 通过 binder 传递过来的,对应 BBinder 是 Layer::Handle。Layer::Handle 继承了 LayerCleaner,它的析构函数里会调用 SurfaceFlinger::onHandleDestroyed() 销毁 layer。

SurfaceFlinger 不持有 Layer::Handler 对象,而是利用 Binder | 对象的生命周期。当所有 client 端的 SurfaceControl 销毁,同时 BpBinder mHandle 也销毁时,根据 Binder 生命周期 Layer::Handle 也会销毁。

Untitled

释放条件

当窗口可见性变化时,会调用 SurfaceView.updateSurface(),在该方法中,如果不可见,会调用 SurfaceView.tryReleaseSurfaces() 执行 SurfaceView 的释放。

protected void onWindowVisibilityChanged(int visibility) {
    super.onWindowVisibilityChanged(visibility);
    mWindowVisibility = visibility == VISIBLE;
    updateRequestedVisibility();
    updateSurface();
}

protected void updateSurface() {
    ...
    if (mSurfaceCreated && (surfaceChanged || (!mVisible && visibleChanged))) {
        mSurfaceCreated = false;
        notifySurfaceDestroyed();
    }
    ...
    if (mSurfaceControl != null && !mSurfaceCreated) {
        tryReleaseSurfaces();
    }
    ...
}

释放

private void tryReleaseSurfaces() {
    synchronized (mSurfaceControlLock) {
        mSurface.destroy();
        if (mBlastBufferQueue != null) {
            mBlastBufferQueue.destroy();
            mBlastBufferQueue = null;
        }

        ViewRootImpl viewRoot = getViewRootImpl();
        Transaction transaction = new Transaction();
        releaseSurfaces(transaction);
        if (viewRoot != null) {
            viewRoot.applyTransactionOnDraw(transaction);
        } else {
            transaction.apply();
        }
    }
}