当 SurfaceView 不可见时,会执行 SurfaceView 的释放,它会销毁 Surface 与 SurfaceControl。 下一次可见时,再创建新的 Surface 与 SurfaceControl。
基于 Android 12
先看一下 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 也会销毁。
当窗口可见性变化时,会调用 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();
}
}
}