[ Android实战 ] android query: BufferQueue has been abandoned 问题解决

  • 背景
  • 日志分析
  • 参考资料
  • 解决方案
  • 源码分析
  • 总结

尊重原创,转载请注明出处!

背景

最近在我们的 Camera 应用上发现一个问题,Camera 应用有一个设置页面,进入设置页面后连续按 back 键退回到预览页面,再退出应用回到桌面,概率性出现应用停止运行的崩溃问题。
经过一天的定位,终于找到了问题的所在并修复了此问题,好久没写实战博客了,因此专门写一篇记录一下。

日志分析

抓了一份崩溃时候的日志,其中关键崩溃日志如下:

--------- beginning of crash
12-07 16:11:03.975  7790  7807 E AndroidRuntime: FATAL EXCEPTION: CameraHandler
12-07 16:11:03.975  7790  7807 E AndroidRuntime: Process: com.xxx.xxx, PID: 7790
12-07 16:11:03.975  7790  7807 E AndroidRuntime: java.lang.reflect.UndeclaredThrowableException
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at $Proxy0.openCamera(Unknown Source)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.presenter.CapturePresenter$5.doInBackground(CapturePresenter.java:162)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.presenter.CapturePresenter$5.doInBackground(CapturePresenter.java:1)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.base.BaseHandler$3.run(BaseHandler.java:40)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at android.os.Handler.handleCallback(Handler.java:751)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:95)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:154)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at android.os.HandlerThread.run(HandlerThread.java:61)
12-07 16:11:03.975  7790  7807 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.common.LogProxy$LogInvocationHandler.invoke(LogProxy.java:48)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at java.lang.reflect.Proxy.invoke(Proxy.java:813)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    ... 8 more
12-07 16:11:03.975  7790  7807 E AndroidRuntime: Caused by: java.lang.RuntimeException: startPreview failed
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at android.hardware.Camera.startPreview(Native Method)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.camera.CameraController$6.execute(CameraController.java:117)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.camera.CameraController.apply(CameraController.java:294)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.platform.xxx.XXXCamera$BackCamera.openCamera(XXXCamera.java:132)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    at com.xxx.xxx.platform.xxx.XXXCamera.openCamera(XXXCamera.java:24)
12-07 16:11:03.975  7790  7807 E AndroidRuntime:    ... 11 more

这不简单吗?直接在调用 startPreview 的地方 catch RuntimeException,问题解决,到此结束!

开个玩笑~

捕获异常只是规避问题的手段,用 catch 异常解决问题简单粗暴,但是同时这种方法也会掩盖真正的问题,后续再发现异常时,会更难定位。

不是不能用 catch 捕获异常,但是这种解决问题的方式不应该被滥用!

崩溃的发生,一定是因为应用或系统中存在其他的问题,才导致 startPreview 的时候异常,而这个问题,才是我们真正要定位并修复的。

继续分析日志,从崩溃信息往前看,果然看到了一些异常的地方:

12-07 16:11:03.918   557  8117 D QCamera2HWI: int qcamera::QCamera2HardwareInterface::startPreview(): E
......
12-07 16:11:03.927   557  8117 D QCameraHWI_Mem: void qcamera::QCameraMemory::traceLogAllocStart(size_t, int, const char*) : alloc E count=7 size=0
12-07 16:11:03.927   557  8117 D QCameraHWI_Mem:  virtual int qcamera::QCameraGrallocMemory::allocate(uint8_t, size_t) : E
12-07 16:11:03.927  7790  7802 E BufferQueueProducer: [SurfaceTexture-0-7790-1] query: BufferQueue has been abandoned
12-07 16:11:03.927   557  8117 E QCameraHWI_Mem: get_min_undequeued_buffer_count  failed: No such device (19)
12-07 16:11:03.927   557  8117 D QCameraHWI_Mem:  virtual int qcamera::QCameraGrallocMemory::allocate(uint8_t, size_t) : X
12-07 16:11:03.927   557  8117 D QCameraHWI_Mem:  void qcamera::QCameraMemory::traceLogAllocEnd(size_t) : X
12-07 16:11:03.928   557  8117 E QCameraStream: int32_t qcamera::QCameraStream::getBufs(cam_frame_len_offset_t*, uint8_t*, uint8_t**, mm_camera_buf_def_t**, mm_camera_map_unmap_ops_tbl_t*): Failed to allocate stream buffers
......
12-07 16:11:03.959   557  5488 D QCamera2HWI: [KPI Perf] static int qcamera::QCamera2HardwareInterface::start_preview(camera_device*): X
--------- beginning of crash

BufferQueue has been abandoned,嗯,就是这个地方了……

Camera 在生成预览时需要从 BufferQueue 中取出 buffer 进行填充,当 BufferQueue 被释放后,无法分配到 Buffer 填充预览数据,就会导致预览失败。

参考资料

第一反应,百度一下,这该死的本能!

然后,还真让我找到了相关的博客和 stackoverflow 的问题:

BufferQueue has been abandoned解决方案

SurfaceTexture has been abandoned

这两篇文章中都是同样的问题,因为 surfaceTexture 是在方法中的临时变量,所以会导致方法调用结束后创建的 SurfaceTexture 对象不被持有,从而在 GC 时被当做垃圾回收掉。

因此文章中推荐的做法是将 surfaceTexture 变为类的成员变量,这样就能一直持有 SurfaceTexture 的引用,从而避免被回收而导致 BufferQueue has been abandoned 的报错。

但是这跟我遇到的情况还不一样,我们应用中的 TextureView 是在布局文件中声明,onCreate 时解析 XML 创建的,TextureView 包含成员变量 mSurface(类型为 SurfaceTexture),因此本来就一直持有 SurfaceTexture 的引用。

所以,伸手党不好当啊,博客中的解决方案不能直接使用,还是得继续分析。

解决方案

但是,文章中的思路还是可以参考的:SurfaceTexture 的回收会导致 BufferQueue 被释放,从而导致预览失败。

重新阅读了一下应用源码,发现 Camera 的流程是通过 Handler 操作的,由于是异步操作,时序就没法保证了。

联想到复现问题的步骤,退出设置界面回到预览界面的时候会重新打开预览,而从预览界面退回到桌面的时候,又会走 Activity 的销毁流程。当这两个操作结合到一起的时候,确实可能存在 TextureView 已经移除,但 startPreview 还在执行的情况,而这就会导致问题的发生!

应用的框架和逻辑被同事写得太复杂了= =。我的想法是尽可能小地改动,不影响其他的逻辑,自然而然地就想到了加锁。

因为应用是基于 MVP 模式开发的,Activity 在 onDestroy 中会调用 detach 解绑 view,在 Presenter 类中,绑定/解绑 view,以及操作 Camera 的地方加上锁,确保这些操作同步就行了。

@Override
public void attach(ICaptureView view) {synchronized (mPreviewLock) {this.mView = view;}
}@Override
public void detach() {synchronized (mPreviewLock) {this.mView = null;}
}@Override
public void openCamera(final int cameraId, final boolean flashOn) {mCameraHandler.post(new BaseHandler.OnCallback<ICamera>() {@Overridepublic void doInBackground(ICamera camera) {synchronized (mPreviewLock) {camera.openCamera(request);}}});
}

作为对比,修改之前,手动测个几次十几次就能出现一次崩溃现象;修改之后,手动复测了一百多次,未复现问题~

源码分析

问题解决了,还是得花点时间研究下这块的流程。知其然知其所以然,搞清楚这块的逻辑,知道为啥会报错,无论对后续的开发还是问题定位都会有很大的帮助!

日志中的 BufferQueue has been abandoned,是在 BufferQueueProducer 中打印的,很容易找到报错的地方:

/frameworks/native/libs/gui/BufferQueueProducer.cppint BufferQueueProducer::query(int what, int *outValue) {......if (mCore->mIsAbandoned) {BQ_LOGE("query: BufferQueue has been abandoned");return NO_INIT;}......
}

这里判断了 mIsAbandoned,当 mIsAbandoned 为 true 时,会报错。因此,我们需要查看 mIsAbandoned 到底是在什么时候被置为 true 的。源码中搜索一下,定位到 BufferQueueConsumer:

/frameworks/native/libs/gui/BufferQueueConsumer.cppstatus_t BufferQueueConsumer::disconnect() {......mCore->mIsAbandoned = true;......return NO_ERROR;
}

这里还有一个知识点,BufferQueueProducer 和 BufferQueueConsumer 是在 BufferQueue 中成对创建的,使用的是同一个 BufferQueueCore,因此在 BufferQueueConsumer 将 mCore->mIsAbandoned 置为 true 时,也会对 BufferQueueProducer 中的逻辑造成影响:

/frameworks/native/libs/gui/BufferQueue.cppvoid BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,sp<IGraphicBufferConsumer>* outConsumer,const sp<IGraphicBufferAlloc>& allocator) {sp<BufferQueueCore> core(new BufferQueueCore(allocator));sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));*outProducer = producer;*outConsumer = consumer;
}

再继续往下看,涉及代码太多了,就不放了,简单画了个调用流程图,可以参考一下:

#mermaid-svg-MSqdtVKdk6kMkkAO .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .label text{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .node rect,#mermaid-svg-MSqdtVKdk6kMkkAO .node circle,#mermaid-svg-MSqdtVKdk6kMkkAO .node ellipse,#mermaid-svg-MSqdtVKdk6kMkkAO .node polygon,#mermaid-svg-MSqdtVKdk6kMkkAO .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-MSqdtVKdk6kMkkAO .node .label{text-align:center;fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .node.clickable{cursor:pointer}#mermaid-svg-MSqdtVKdk6kMkkAO .arrowheadPath{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-MSqdtVKdk6kMkkAO .flowchart-link{stroke:#333;fill:none}#mermaid-svg-MSqdtVKdk6kMkkAO .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-MSqdtVKdk6kMkkAO .edgeLabel rect{opacity:0.9}#mermaid-svg-MSqdtVKdk6kMkkAO .edgeLabel span{color:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-MSqdtVKdk6kMkkAO .cluster text{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-MSqdtVKdk6kMkkAO .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-MSqdtVKdk6kMkkAO text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-MSqdtVKdk6kMkkAO .actor-line{stroke:grey}#mermaid-svg-MSqdtVKdk6kMkkAO .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-MSqdtVKdk6kMkkAO #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .sequenceNumber{fill:#fff}#mermaid-svg-MSqdtVKdk6kMkkAO #sequencenumber{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO #crosshead path{fill:#333;stroke:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .messageText{fill:#333;stroke:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-MSqdtVKdk6kMkkAO .labelText,#mermaid-svg-MSqdtVKdk6kMkkAO .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-MSqdtVKdk6kMkkAO .loopText,#mermaid-svg-MSqdtVKdk6kMkkAO .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-MSqdtVKdk6kMkkAO .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-MSqdtVKdk6kMkkAO .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-MSqdtVKdk6kMkkAO .noteText,#mermaid-svg-MSqdtVKdk6kMkkAO .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-MSqdtVKdk6kMkkAO .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-MSqdtVKdk6kMkkAO .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-MSqdtVKdk6kMkkAO .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-MSqdtVKdk6kMkkAO .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .section{stroke:none;opacity:0.2}#mermaid-svg-MSqdtVKdk6kMkkAO .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-MSqdtVKdk6kMkkAO .section2{fill:#fff400}#mermaid-svg-MSqdtVKdk6kMkkAO .section1,#mermaid-svg-MSqdtVKdk6kMkkAO .section3{fill:#fff;opacity:0.2}#mermaid-svg-MSqdtVKdk6kMkkAO .sectionTitle0{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .sectionTitle1{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .sectionTitle2{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .sectionTitle3{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-MSqdtVKdk6kMkkAO .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .grid path{stroke-width:0}#mermaid-svg-MSqdtVKdk6kMkkAO .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-MSqdtVKdk6kMkkAO .task{stroke-width:2}#mermaid-svg-MSqdtVKdk6kMkkAO .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .taskText:not([font-size]){font-size:11px}#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-MSqdtVKdk6kMkkAO .task.clickable{cursor:pointer}#mermaid-svg-MSqdtVKdk6kMkkAO .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-MSqdtVKdk6kMkkAO .taskText0,#mermaid-svg-MSqdtVKdk6kMkkAO .taskText1,#mermaid-svg-MSqdtVKdk6kMkkAO .taskText2,#mermaid-svg-MSqdtVKdk6kMkkAO .taskText3{fill:#fff}#mermaid-svg-MSqdtVKdk6kMkkAO .task0,#mermaid-svg-MSqdtVKdk6kMkkAO .task1,#mermaid-svg-MSqdtVKdk6kMkkAO .task2,#mermaid-svg-MSqdtVKdk6kMkkAO .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutside0,#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutside2{fill:#000}#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutside1,#mermaid-svg-MSqdtVKdk6kMkkAO .taskTextOutside3{fill:#000}#mermaid-svg-MSqdtVKdk6kMkkAO .active0,#mermaid-svg-MSqdtVKdk6kMkkAO .active1,#mermaid-svg-MSqdtVKdk6kMkkAO .active2,#mermaid-svg-MSqdtVKdk6kMkkAO .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-MSqdtVKdk6kMkkAO .activeText0,#mermaid-svg-MSqdtVKdk6kMkkAO .activeText1,#mermaid-svg-MSqdtVKdk6kMkkAO .activeText2,#mermaid-svg-MSqdtVKdk6kMkkAO .activeText3{fill:#000 !important}#mermaid-svg-MSqdtVKdk6kMkkAO .done0,#mermaid-svg-MSqdtVKdk6kMkkAO .done1,#mermaid-svg-MSqdtVKdk6kMkkAO .done2,#mermaid-svg-MSqdtVKdk6kMkkAO .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-MSqdtVKdk6kMkkAO .doneText0,#mermaid-svg-MSqdtVKdk6kMkkAO .doneText1,#mermaid-svg-MSqdtVKdk6kMkkAO .doneText2,#mermaid-svg-MSqdtVKdk6kMkkAO .doneText3{fill:#000 !important}#mermaid-svg-MSqdtVKdk6kMkkAO .crit0,#mermaid-svg-MSqdtVKdk6kMkkAO .crit1,#mermaid-svg-MSqdtVKdk6kMkkAO .crit2,#mermaid-svg-MSqdtVKdk6kMkkAO .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-MSqdtVKdk6kMkkAO .activeCrit0,#mermaid-svg-MSqdtVKdk6kMkkAO .activeCrit1,#mermaid-svg-MSqdtVKdk6kMkkAO .activeCrit2,#mermaid-svg-MSqdtVKdk6kMkkAO .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-MSqdtVKdk6kMkkAO .doneCrit0,#mermaid-svg-MSqdtVKdk6kMkkAO .doneCrit1,#mermaid-svg-MSqdtVKdk6kMkkAO .doneCrit2,#mermaid-svg-MSqdtVKdk6kMkkAO .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-MSqdtVKdk6kMkkAO .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-MSqdtVKdk6kMkkAO .milestoneText{font-style:italic}#mermaid-svg-MSqdtVKdk6kMkkAO .doneCritText0,#mermaid-svg-MSqdtVKdk6kMkkAO .doneCritText1,#mermaid-svg-MSqdtVKdk6kMkkAO .doneCritText2,#mermaid-svg-MSqdtVKdk6kMkkAO .doneCritText3{fill:#000 !important}#mermaid-svg-MSqdtVKdk6kMkkAO .activeCritText0,#mermaid-svg-MSqdtVKdk6kMkkAO .activeCritText1,#mermaid-svg-MSqdtVKdk6kMkkAO .activeCritText2,#mermaid-svg-MSqdtVKdk6kMkkAO .activeCritText3{fill:#000 !important}#mermaid-svg-MSqdtVKdk6kMkkAO .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-MSqdtVKdk6kMkkAO g.classGroup text .title{font-weight:bolder}#mermaid-svg-MSqdtVKdk6kMkkAO g.clickable{cursor:pointer}#mermaid-svg-MSqdtVKdk6kMkkAO g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-MSqdtVKdk6kMkkAO g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-MSqdtVKdk6kMkkAO .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-MSqdtVKdk6kMkkAO .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-MSqdtVKdk6kMkkAO .dashed-line{stroke-dasharray:3}#mermaid-svg-MSqdtVKdk6kMkkAO #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO .commit-id,#mermaid-svg-MSqdtVKdk6kMkkAO .commit-msg,#mermaid-svg-MSqdtVKdk6kMkkAO .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-MSqdtVKdk6kMkkAO g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-MSqdtVKdk6kMkkAO g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-MSqdtVKdk6kMkkAO g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-MSqdtVKdk6kMkkAO .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-MSqdtVKdk6kMkkAO .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-MSqdtVKdk6kMkkAO .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-MSqdtVKdk6kMkkAO .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-MSqdtVKdk6kMkkAO .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-MSqdtVKdk6kMkkAO .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-MSqdtVKdk6kMkkAO .edgeLabel text{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-MSqdtVKdk6kMkkAO .node circle.state-start{fill:black;stroke:black}#mermaid-svg-MSqdtVKdk6kMkkAO .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-MSqdtVKdk6kMkkAO #statediagram-barbEnd{fill:#9370db}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-state .divider{stroke:#9370db}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-MSqdtVKdk6kMkkAO .note-edge{stroke-dasharray:5}#mermaid-svg-MSqdtVKdk6kMkkAO .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-MSqdtVKdk6kMkkAO .error-icon{fill:#522}#mermaid-svg-MSqdtVKdk6kMkkAO .error-text{fill:#522;stroke:#522}#mermaid-svg-MSqdtVKdk6kMkkAO .edge-thickness-normal{stroke-width:2px}#mermaid-svg-MSqdtVKdk6kMkkAO .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-MSqdtVKdk6kMkkAO .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-MSqdtVKdk6kMkkAO .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-MSqdtVKdk6kMkkAO .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-MSqdtVKdk6kMkkAO .marker{fill:#333}#mermaid-svg-MSqdtVKdk6kMkkAO .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-MSqdtVKdk6kMkkAO {color: rgba(0, 0, 0, 0.75);font: ;}SurfaceFlingerLayerGLConsumerConsumerBaseIGraphicBufferConsumerBufferQueueConsumeronRemovedabandonabandonabandonLockedabandonLockedconsumerDisconnectdisconnectSurfaceFlingerLayerGLConsumerConsumerBaseIGraphicBufferConsumerBufferQueueConsumer

即 Activity 销毁时,系统会先通过 surfaceflinger 移除相应的 layer,并释放相应的 BufferQueue。

再简单画下上面资料中的流程图,即 BufferQueueConsumer 的所有强引用都被释放后,也是走相同的流程,释放相应的 BufferQueue。

#mermaid-svg-At3UZw0pFjgtNQUE .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-At3UZw0pFjgtNQUE .label text{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .node rect,#mermaid-svg-At3UZw0pFjgtNQUE .node circle,#mermaid-svg-At3UZw0pFjgtNQUE .node ellipse,#mermaid-svg-At3UZw0pFjgtNQUE .node polygon,#mermaid-svg-At3UZw0pFjgtNQUE .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-At3UZw0pFjgtNQUE .node .label{text-align:center;fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .node.clickable{cursor:pointer}#mermaid-svg-At3UZw0pFjgtNQUE .arrowheadPath{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-At3UZw0pFjgtNQUE .flowchart-link{stroke:#333;fill:none}#mermaid-svg-At3UZw0pFjgtNQUE .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-At3UZw0pFjgtNQUE .edgeLabel rect{opacity:0.9}#mermaid-svg-At3UZw0pFjgtNQUE .edgeLabel span{color:#333}#mermaid-svg-At3UZw0pFjgtNQUE .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-At3UZw0pFjgtNQUE .cluster text{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-At3UZw0pFjgtNQUE .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-At3UZw0pFjgtNQUE text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-At3UZw0pFjgtNQUE .actor-line{stroke:grey}#mermaid-svg-At3UZw0pFjgtNQUE .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-At3UZw0pFjgtNQUE .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-At3UZw0pFjgtNQUE #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-At3UZw0pFjgtNQUE .sequenceNumber{fill:#fff}#mermaid-svg-At3UZw0pFjgtNQUE #sequencenumber{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE #crosshead path{fill:#333;stroke:#333}#mermaid-svg-At3UZw0pFjgtNQUE .messageText{fill:#333;stroke:#333}#mermaid-svg-At3UZw0pFjgtNQUE .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-At3UZw0pFjgtNQUE .labelText,#mermaid-svg-At3UZw0pFjgtNQUE .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-At3UZw0pFjgtNQUE .loopText,#mermaid-svg-At3UZw0pFjgtNQUE .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-At3UZw0pFjgtNQUE .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-At3UZw0pFjgtNQUE .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-At3UZw0pFjgtNQUE .noteText,#mermaid-svg-At3UZw0pFjgtNQUE .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-At3UZw0pFjgtNQUE .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-At3UZw0pFjgtNQUE .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-At3UZw0pFjgtNQUE .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-At3UZw0pFjgtNQUE .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .section{stroke:none;opacity:0.2}#mermaid-svg-At3UZw0pFjgtNQUE .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-At3UZw0pFjgtNQUE .section2{fill:#fff400}#mermaid-svg-At3UZw0pFjgtNQUE .section1,#mermaid-svg-At3UZw0pFjgtNQUE .section3{fill:#fff;opacity:0.2}#mermaid-svg-At3UZw0pFjgtNQUE .sectionTitle0{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .sectionTitle1{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .sectionTitle2{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .sectionTitle3{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-At3UZw0pFjgtNQUE .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .grid path{stroke-width:0}#mermaid-svg-At3UZw0pFjgtNQUE .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-At3UZw0pFjgtNQUE .task{stroke-width:2}#mermaid-svg-At3UZw0pFjgtNQUE .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .taskText:not([font-size]){font-size:11px}#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-At3UZw0pFjgtNQUE .task.clickable{cursor:pointer}#mermaid-svg-At3UZw0pFjgtNQUE .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-At3UZw0pFjgtNQUE .taskText0,#mermaid-svg-At3UZw0pFjgtNQUE .taskText1,#mermaid-svg-At3UZw0pFjgtNQUE .taskText2,#mermaid-svg-At3UZw0pFjgtNQUE .taskText3{fill:#fff}#mermaid-svg-At3UZw0pFjgtNQUE .task0,#mermaid-svg-At3UZw0pFjgtNQUE .task1,#mermaid-svg-At3UZw0pFjgtNQUE .task2,#mermaid-svg-At3UZw0pFjgtNQUE .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutside0,#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutside2{fill:#000}#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutside1,#mermaid-svg-At3UZw0pFjgtNQUE .taskTextOutside3{fill:#000}#mermaid-svg-At3UZw0pFjgtNQUE .active0,#mermaid-svg-At3UZw0pFjgtNQUE .active1,#mermaid-svg-At3UZw0pFjgtNQUE .active2,#mermaid-svg-At3UZw0pFjgtNQUE .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-At3UZw0pFjgtNQUE .activeText0,#mermaid-svg-At3UZw0pFjgtNQUE .activeText1,#mermaid-svg-At3UZw0pFjgtNQUE .activeText2,#mermaid-svg-At3UZw0pFjgtNQUE .activeText3{fill:#000 !important}#mermaid-svg-At3UZw0pFjgtNQUE .done0,#mermaid-svg-At3UZw0pFjgtNQUE .done1,#mermaid-svg-At3UZw0pFjgtNQUE .done2,#mermaid-svg-At3UZw0pFjgtNQUE .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-At3UZw0pFjgtNQUE .doneText0,#mermaid-svg-At3UZw0pFjgtNQUE .doneText1,#mermaid-svg-At3UZw0pFjgtNQUE .doneText2,#mermaid-svg-At3UZw0pFjgtNQUE .doneText3{fill:#000 !important}#mermaid-svg-At3UZw0pFjgtNQUE .crit0,#mermaid-svg-At3UZw0pFjgtNQUE .crit1,#mermaid-svg-At3UZw0pFjgtNQUE .crit2,#mermaid-svg-At3UZw0pFjgtNQUE .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-At3UZw0pFjgtNQUE .activeCrit0,#mermaid-svg-At3UZw0pFjgtNQUE .activeCrit1,#mermaid-svg-At3UZw0pFjgtNQUE .activeCrit2,#mermaid-svg-At3UZw0pFjgtNQUE .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-At3UZw0pFjgtNQUE .doneCrit0,#mermaid-svg-At3UZw0pFjgtNQUE .doneCrit1,#mermaid-svg-At3UZw0pFjgtNQUE .doneCrit2,#mermaid-svg-At3UZw0pFjgtNQUE .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-At3UZw0pFjgtNQUE .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-At3UZw0pFjgtNQUE .milestoneText{font-style:italic}#mermaid-svg-At3UZw0pFjgtNQUE .doneCritText0,#mermaid-svg-At3UZw0pFjgtNQUE .doneCritText1,#mermaid-svg-At3UZw0pFjgtNQUE .doneCritText2,#mermaid-svg-At3UZw0pFjgtNQUE .doneCritText3{fill:#000 !important}#mermaid-svg-At3UZw0pFjgtNQUE .activeCritText0,#mermaid-svg-At3UZw0pFjgtNQUE .activeCritText1,#mermaid-svg-At3UZw0pFjgtNQUE .activeCritText2,#mermaid-svg-At3UZw0pFjgtNQUE .activeCritText3{fill:#000 !important}#mermaid-svg-At3UZw0pFjgtNQUE .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-At3UZw0pFjgtNQUE g.classGroup text .title{font-weight:bolder}#mermaid-svg-At3UZw0pFjgtNQUE g.clickable{cursor:pointer}#mermaid-svg-At3UZw0pFjgtNQUE g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-At3UZw0pFjgtNQUE g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-At3UZw0pFjgtNQUE .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-At3UZw0pFjgtNQUE .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-At3UZw0pFjgtNQUE .dashed-line{stroke-dasharray:3}#mermaid-svg-At3UZw0pFjgtNQUE #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE .commit-id,#mermaid-svg-At3UZw0pFjgtNQUE .commit-msg,#mermaid-svg-At3UZw0pFjgtNQUE .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-At3UZw0pFjgtNQUE g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-At3UZw0pFjgtNQUE g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-At3UZw0pFjgtNQUE g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-At3UZw0pFjgtNQUE .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-At3UZw0pFjgtNQUE .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-At3UZw0pFjgtNQUE .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-At3UZw0pFjgtNQUE .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-At3UZw0pFjgtNQUE .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-At3UZw0pFjgtNQUE .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-At3UZw0pFjgtNQUE .edgeLabel text{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-At3UZw0pFjgtNQUE .node circle.state-start{fill:black;stroke:black}#mermaid-svg-At3UZw0pFjgtNQUE .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-At3UZw0pFjgtNQUE #statediagram-barbEnd{fill:#9370db}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-state .divider{stroke:#9370db}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-At3UZw0pFjgtNQUE .note-edge{stroke-dasharray:5}#mermaid-svg-At3UZw0pFjgtNQUE .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-At3UZw0pFjgtNQUE .error-icon{fill:#522}#mermaid-svg-At3UZw0pFjgtNQUE .error-text{fill:#522;stroke:#522}#mermaid-svg-At3UZw0pFjgtNQUE .edge-thickness-normal{stroke-width:2px}#mermaid-svg-At3UZw0pFjgtNQUE .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-At3UZw0pFjgtNQUE .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-At3UZw0pFjgtNQUE .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-At3UZw0pFjgtNQUE .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-At3UZw0pFjgtNQUE .marker{fill:#333}#mermaid-svg-At3UZw0pFjgtNQUE .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-At3UZw0pFjgtNQUE {color: rgba(0, 0, 0, 0.75);font: ;}RefBaseConsumerBaseGLConsumerIGraphicBufferConsumerBufferQueueConsumeronLastStrongRefabandonabandonLockedabandonLockedconsumerDisconnectdisconnectRefBaseConsumerBaseGLConsumerIGraphicBufferConsumerBufferQueueConsumer

总结

都看到这了,还不给我点个赞吗???

Camera 在预览过程中,必须持有 Surface 的强引用,因此需要注意:

1、不能将 SurfaceTexture 作为临时变量,这样在方法执行结束后,由于没有持有对 Surface 的强引用,系统可能会释放 BufferQueue,导致预览出错。

2、需要注意 Activity 和 Camera 操作的时序问题,如果在预览过程中退出应用,必须在 Surface 移除前先停止预览,否则也会导致预览出错。

[ Android实战 ] android query: BufferQueue has been abandoned 问题解决相关推荐

  1. bomb android实战,android 仿qq app源码下载(bmob)

    [实例简介] [实例截图] [核心代码] package com.bmob.im.demo.ui; import android.os.Bundle; import android.support.v ...

  2. 【Android】Android SurfaceFlinger之BufferQueue

    在Android中,BufferQueue是Surface实现本地窗口的关键,驻留在SurfaceFlinger进程中进行服务,下面从BufferQueue的结构开始分析. 1.BufferQueue ...

  3. Android实战:CoolWeather酷欧天气(加强版数据接口)代码详解(上)

    -----------------------------------该文章代码已停更,可参考浩比天气(更新于2019/6/25)----------------------------------- ...

  4. Android实战——jsoup实现网络爬虫,糗事百科项目的起步

    Android实战--jsoup实现网络爬虫,爬糗事百科主界面 本篇文章包括以下内容: 前言 jsoup的简介 jsoup的配置 jsoup的使用 结语 前言 对于Android初学者想要做项目时,最 ...

  5. Android实战技巧之十一:Android Studio和Gradle

    2019独角兽企业重金招聘Python工程师标准>>> 经过两个多月的AS体验,我认为是时候将Android的开发环境迁移到AS上了.目前最新版本是1.0.2(大年30当天升级到1. ...

  6. 【Android实战】记录自学自己定义GifView过程,能同一时候支持gif和其它图片!【有用篇】...

    之前写了一篇博客.<[Android实战]记录自学自己定义GifView过程,具体解释属性那些事! [学习篇]> 关于自己定义GifView的,具体解说了学习过程及遇到的一些类的解释,然后 ...

  7. android listview 列加id,Android实战开发之ListView同一个item显示2列的实现方法

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Android实战开发中,ListView控件用途十分广泛,各种自定义控件多种多样.当项目要求实现一个2列的商品列表形式的界面,我们首先肯定想到用List ...

  8. 苹果电脑基本设置+Linux 命令+Android 实战集锦

    本文微信公众号「AndroidTraveler」首发. 背景 大多数应届毕业生在大学期间使用的比较多的是 windows 电脑,因此初入职场如果拿到一台苹果电脑,可能一时间不能够很快的上手.基于此,这 ...

  9. Android实战:手把手实现“捧腹网”APP(三)-----UI实现,逻辑实现

    APP页面实现 根据原型图,我们可以看出,UI分为两部分,底部Tab导航+上方列表显示. 所以此处,我们通过 FragmentTabHost+Fragment,来实现底部的导航页面,通过Recycle ...

最新文章

  1. js layui 模板属性 添加_layui.laytpl--模板引擎文档
  2. Web API With AJAX: Handle Session in Web API
  3. Delegate成员变量和Event的区别
  4. redis中KEYS替代命令
  5. 《Programming WPF》学习(二)Application及其设置
  6. Vmware centos无法连接网络
  7. 2017-09-16
  8. AWT_Swing_初始化(Java)
  9. Java匹马行天下之学编程的起点——编程常识知多少
  10. python就业有哪些方向_Python就业有哪些方向?最全信息在这里!
  11. 详解CATransformLayer
  12. html微博换头像,手机新浪微博头像怎么设置 手机新浪微博更换头像教程
  13. 使用node加密excel文件
  14. Kubernetes:应用部署、应用了解、应用公布、应用伸缩,-image=ikubernetes/myapp:v1
  15. c语言二级编程实例,二级C语言编程_-实例.doc
  16. linux安全之服务安全
  17. 计算机ps课如何把玫瑰花绿色,ps变色教程 利用PhotoShop将红玫瑰变成蓝色玫瑰
  18. sync.WaitGroup的用法
  19. 一、计算机组成与体系——软考软件设计师
  20. 百度云音视频直播服务(LSS)的使用流程

热门文章

  1. C语言输出100-1000之内所有的水仙花数字
  2. 用帕斯卡定理证明圆和切线有关的问题
  3. arcgis api js调用天地图
  4. 文件操作(全类型通用)
  5. html中如何引用其外部字体,css引入外部字体
  6. 福利!!!Python爬取好看的妹子图!!!
  7. 精品网址导航主题整站源码 wordpress模板 自适应手机端
  8. 【BZOJ4552】【TJOI2016HEOI2016】排序(线段树、二分)
  9. ArcGIS Earth 1.11版本发布啦!
  10. usb_register_dev