Android screencap的处理流程
以下分析基于Android Q的代码
先大体整理screencap的处理流程
1.获取DisplayID
std::optional<PhysicalDisplayId> displayId = SurfaceComposerClient::getInternalDisplayId();
2. 调用ScreenshotClient::capture截取屏幕图像,数据保存在一个GraphicBuffer中
ui::Dataspace outDataspace;
sp<GraphicBuffer> outBuffer;
status_t result = ScreenshotClient::capture(*displayId, &outDataspace, &outBuffer);
3. BInder IPC 呼叫到 SurfaceFlinger::captureScreen
根据DisplayId获取到DisplayDevice信息,width/height/orientation/renderArea
4. 继续呼叫 SurfaceFlinger::captureScreenCommon
createGraphicBuffer
5. 继续调用 SurfaceFlinger::captureScreenImplLocked
找到belongsToDisplay 并判断(layer->isVisible() && layer->isSecure()的情况
6. 继续走到 SurfaceFlinger::renderScreenImplLocked
遍历belongsToDisplay的所有layer ==>layer->prepareClientLayer
7. 使用getRenderEngine().drawLayers 绘制合成到一个GraphicBuffer中
GLESRenderEngine::drawLayers中使用GLES完成图像绘制
大体如上过程screencap中就得到了最后保存屏幕截图的GraphicBuffer,然后利用Skia中的方法经encode保存在PNG图片
Android原生recent app机制的重点就是去获取screenshots of each task,具体是去调用 :
WindowManagerService::getTaskSnapshot
TaskSnapshot实际是在TaskSnapshotController中获取的
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
大体如下流程:
1. TaskSnapshotController::createTaskSnapshot
2. SurfaceControl::captureLayers
经JNI
3. ScreenshotClient::captureChildLayers
经binder
4. SurfaceFlinger::captureLayers
5. SurfaceFlinger::captureScreenCommon
6. SurfaceFlinger::captureScreenImplLocked
7. SurfaceFlinger::renderScreenImplLocked
8. GLESRenderEngine::drawLayers
处理过程和screencap截取屏幕是类似的,区别在于
screencap:呼叫ScreenshotClient::capture,传递displayId给SurfaceFlinger,会把和这个display相关的layer合成绘制到一张图片
TaskSnapshot: 呼叫ScreenshotClient::captureChildLayers,传递和task相关的layerHandle给SurfaceFlinger,会把和这个layerHandle相关的layers / child layers合成绘制到一张图片
差不多简单理解:
screencap:截取屏幕显示的内容
TaskSnapshot:截取一个apk界面显示的内容
但从SurfaceFlinger处理来说基本一致,最终都是通过GPU合成 画到一张图片,数据存到GraphicBuffer中返回给caller。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?