截图框架代码原理 android 11
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了截图框架代码原理 android 11相关的知识,希望对你有一定的参考价值。
参考技术A 通过SurfaceControl.screenshot来获取一个bitmap对象,原理就是创造一个graphicBuffer ,屏幕上面各个layer经过surfaceFlinger处理后,填充它,然后返回一个bitmap对象/ frameworks / base / core / java / android / view / SurfaceControl.java
1、获取displayToken这IBinder类型的对象,
2、调整方向,一般调用时候传入的是rotaion是0,如果传入1或者3会重置横竖屏方向。
3、捕获屏幕上所有的surface,返回一个填充内容的GraphicBuffer
4、把创建好的GraphicBuffer对象传入硬件支持的位图使用图形缓冲区,返回bitmap对象
getPhysicalDisplayIds()返回一个long型的数组,physicalDisplayIds[0]就是主显示设备,数组的其他位置可能会是投屏等其他设备。
1、通过一系列的调用会走到SurfaceComposerClient.cpp的 ComposerService::getComposerService()这里
获取ComposerService对象,Composervice是一个单例模式,ComposerSerivce继承Singleton,且类型是ComposerService ,singleton 中的TYPE就ComposerService。
2、其回返回一个 ComposerService 对象,若ComposerService已经创建,说明已经链接上了,则直接返回,若没有创建,则创建并执行connectLocked方法。
3、在connectLocked过程中,首先可以看到通过SurfaceFlinger名称查找服务,死循环,在ServiceMananger中通过名称不停的查找获取对应的服务。
getService是一个模板函数,通过参数name去查找获取对应的服务,并将服务的IBinder转化为接口对象输出
3.1 创建死亡监听,且绑定
3.2 返回ComposerService单例中的ISurfaceComposer对象。我们知道SurfaceFlinger继承BnSurfaceFlinger继承BnInterface<ISurfaceComposer>。也就是说返回了SurfaceFlinger对象,
我们就可以知道getPhysicalDisplayToken就是执行的SurfaceFlinger中的方法。/ frameworks / native / services / surfaceflinger / SurfaceFlinger.cpp
在SurfaceFlinger.h / frameworks / native / services / surfaceflinger / SurfaceFlinger.h
mPhysicalDisplayTokens是一个map类型,DisplayId对应某个屏幕,sp<IBinder>就是屏幕对应的SurfaceFlinger的IBinder对象。通过mPhysicalDisplayTokends.find(displayId)找到IBinder。
这样SurfaceControl.getInternalDisplayToken()过程就完成,很明显返回的IBinder类型DisplayToken就是SurfaceFlinger服务端。
这个方法的目的是 捕获屏幕上所有的surface,返回一个填充这些surface内容的GraphicBuffer
1、Display就是surfaceFlinger的代理,后面最重要的截图过程就是在其内部进行的。
2、捕获屏幕中的bitmap,一般传入new Rect,也就是不进行裁剪
3、接下来就是宽,高,方向,userIdentityTransform是false。
nativeScreenshot通过JNI调用到了android_view_SurfaceControl.cpp中,在这个方法里面可以设置setpripority,截图应用的优先级,优先处理截图操作。
可以看到了一个关键点sp<GraphicBuffer> buffer,surfaces就是要填充给这个buffer。ScreenshotClient.capture会调用到SurfaceComposerClient.cpp中的capture
1、ISurfaceComposer对象赋值,上面也介绍过此过程
2、调用ISurfaceComposer的captureScreen方法,方法内容较多,
其中关键句是 Status_t result= remote()->transact(BnSurfaceCompser::_CAPTURE_SCREEN,data,&reply);
会调用到服务端onTransact中
找到CAPTURE_SCREEN
因为服务端为SurfaceFlinger所以会执行到SurfaceFlinger中的captureScreen方法
流程图如下
1、DisplayDevice类型 display对象通过getDisplayDeviceLocked(displayToken)进行赋值,
2、构造一个DisplayRenderArea类型对象renderArea
3、bind函数中执行traverseLayersInDisplay方法,this是sf,display,std::placeholders:_1是一个占位符。结果重命名为traverselayers方法。
这个方法主要内容是通过getFactory().createGraphicBuffer创建一个GraphicBuffer
在SurfaceFlingerDefaultFactory.cpp中可以看到new 了一个 GraphicBuffer对象,requestorName就是screenshot。
继续往下走captureScreenCommon方法
1、获取被调用者的UID,也就是我们系统应用App的UID,只有系统应用才能调用截图接口,
2、forSystem的值当然就是true了,代表是系统应用
3、schedule函数把和应用打交道的某个binder线程执行的任务调用到了主线程进行执行,从systrace中能很明显的看到,如下,在一个vsync周期内sf合成完后会进行屏幕的截图工作
在captureScreenImplLocked方法中可以获取到各个layer,所以就可以在这块进行layer的处理,比如哪些内容不需要截取等。
接下来renderScreenImplLocked方法
这方法内容较多,关键语句是
GLESRenderEngine继承RenderEngine
getRenderEngine().drawLayers是调用的 GLESRenderEngine的drawLayers方法,这个方法主要工作是
1、通过GPU合成为特定的显示呈现图层
2、这个方法会被每一个需要通过GPU渲染的显示内容调用
3、display,绘制图层前显示范围的设置
4、Layers,绘制到显示器上的图层,z轴次序
5、Buffer,将layer内容填充到buffer中
6、userFrameBufferCache缓冲区可用就为true,没有实现缓冲区则这个值没有用
7、bufferFence ,fence标记,看是否准备好了,准备好了就可以draw
填充好buffer,这个时候buffer就有了该有的屏幕上layer内容。
回到SurfaceControl.java中
FinalScreenshotGraphicBuffer buffer =screenshotToBuffer(displayToken,sourceCrop,width,height,userIdentityTransform,rotation);
Buffer现在有值了,已经填充好了,接下来就是把Buffer转化成Bitmap
调用Bitmap.wrapHardwareBuffer(buffer.getGraphicBuffer(),buffer.getColorSpace());可以得到我们需要的bitmap,截图过程到此完成。
如何在 Android Studio 的屏幕截图中添加更多框架,如 Nexus 6P、5X 等
【中文标题】如何在 Android Studio 的屏幕截图中添加更多框架,如 Nexus 6P、5X 等【英文标题】:How To Add more Frame Like Nexus 6P,5X etc in Screenshots in Android studio 【发布时间】:2016-04-04 03:05:08 【问题描述】:我是Android工作室的真正爱人...
Android 监视器中有一个很棒的插件是 SCHREEN CAPTURE 如下图。
捕捉模拟器屏幕非常棒。
我的问题
在屏幕截图中,有一个选项 Frame screenshot 我可以为我的屏幕截图选择设备。
但是只有4个设备列表
联结 联结一号 通用电话 通用平板电脑如何添加更多设备框架。
有什么办法吗?
等待您的建议。
已编辑
注意:我不想要预览选项卡中的 xml 屏幕截图,因为它不是运行时屏幕。
【问题讨论】:
试试这个***.com/a/59826578/9699634 【参考方案1】:仅适用于 MacOS,当您的模拟器运行时,点击Command + Shift + 5
并单击模拟器窗口。这将获取框架和屏幕的屏幕截图。您可能需要使用图像编辑器删除屏幕截图中也包含的工具栏窗口。
【讨论】:
【参考方案2】:你好,我发现了一个
android asset studio Link
请看下图:-
要获取所有列出的用于帧捕获的设备,请查看下图如果您想要的设备在您可以找到的列出:-
也可以看看https://developer.android.com/distribute/marketing-tools/device-art-generator
【讨论】:
不是这样的。我正在尝试在屏幕截图中添加框架,而不是在 xml 文件中,感谢您的建议 那个链接现在失效了!【参考方案3】:这可能会迟到,但我认为 android studio 不允许自定义框架。
您可以使用这个link在线更换框架,在这里您可以找到不同类型的不同风格的设备。
【讨论】:
付费服务。免费下载分辨率:231x530px + 水印。没用。【参考方案4】:适用于 mac:(在 windows 或 linux 上也应该类似)
在 Android Studio 安装位置/内容中找到 device-art-resources 文件夹。
路径: /Applications/Android Studio.app/Contents/plugins/android/lib/device-art-resources
编辑: 使用您需要的任何自定义框架创建您的文件夹。 根据需要编辑 device-art.xml
我刚刚编辑了通用电话文本以确保它有效..
【讨论】:
你找不到什么。?你在什么操作系统上? ubuntu ? 哦,它处于隐藏模式 这甚至没有明确回答问题!你通过重命名实现了什么?如果可能,请回答如何在设备截图编辑窗口中添加 N6P 图像。【参考方案5】:我对此并不完全确定,但我猜 Android Studio 会根据屏幕截图的大小显示设备列表,而对我来说它显示的是 Nexus 5X for my Nexus 5 connected。
无论如何,请更新您的 SDK 和 Android Studio,以获取至少适用于 Nexus 5X 的框架。不过我会尝试找到 Nexus 6P。
【讨论】:
@VishalPatel 那肯定是根据截图的大小,也就是连接设备的大小。 @VishalPatel 如果屏幕截图的大小合适,我们可以。例如,您无法将 1080p 屏幕截图放入更高分辨率的设备框架中,例如 Nexus 6P 我理解兄弟,但假设我想要的框架没有我的截图的真正分辨率呢?我就是这么说的 @VishalPatel 我了解您的问题。我会努力为它找点东西【参考方案6】:取决于设备分辨率。
如果您尝试在具有 768x1280 分辨率的模拟器上截屏,它将显示具有该分辨率的设备(例如,nexus 4、nexus s 等 ),如果您正在运行具有 1080x1920 分辨率的模拟器,它将显示具有该分辨率的设备(例如,nexus 5、nexus 5x 等。) p>
【讨论】:
我的 sdk 完全更新了,我的设备分辨率是 1080x1920 我认为 nexes 4 和 nexus s 有 768*1280 分辨率。 我的模拟器是nexus5 你是对的,但我的问题是有什么方法可以添加任何分辨率的框架??【参考方案7】:尝试先更新您的 SDK(构建工具、平台工具、最新 API 23),然后从“帮助”菜单更新您的 Android Studio 版本。它现在应该出现了。
【讨论】:
看起来您使用的是 Ubuntu。如果您的 SDK 路径正确,您可以检查首选项吗? Android Studio 带有自己的 SDK,因此如果您单独安装 SDK,它可能会查看自己捆绑的 SDK,而不是您下载的 SDK。 另外,如果这不起作用,请尝试从更新对话框下载测试版,进入更新设置,然后选择 Canary 或 Beta 更新通道。如果这也不起作用,那么您可能正在考虑下载新的 Android Studio 包(全新安装)【参考方案8】:Hi 转到您的 XML ex:sample_activity.xml(您要为其截屏的文件)->在那里选择->左上角的设计,您将获得所有设备。
当您右键单击保存屏幕时,将根据您将选择的设备显示相关设备。 在此处输入图像描述
【讨论】:
但这是布局快照,不是真正的屏幕截图。 是的,这只是布局快照,因为我们有更多可选的虚拟设备。以上是关于截图框架代码原理 android 11的主要内容,如果未能解决你的问题,请参考以下文章
11.1 Android显示系统框架_framebuffer原理及改进
Android注解使用之通过annotationProcessor注解生成代码实现自己的ButterKnife框架
Android 插件化“ 插桩式 “ 插件化框架 ( 运行应用 | 代码整理 )
如何在 Android Studio 的屏幕截图中添加更多框架,如 Nexus 6P、5X 等