TL; DR:由于getDrawingCache()
似乎在启用硬件加速时触发了View
的完全重绘,是否有另一种方法可以获得Bitmap
(或者其他内容)避免这种情况,可能是在最后一次绘制View
时读取填充到(硬件,软件)层的数据?
一些背景知识:
Android已经能够自Android 3.0以来镜像屏幕,例如连接到HDMI显示器。这可以用于演示,但这意味着观众看到与演示者相同的东西,这并不总是理想的。
Android 4.2添加了Presentation
,允许应用在“第二屏幕”上放置任意内容(例如,HDMI附加显示)。在这种情况下,有时第二个屏幕显示主平板电脑显示屏上的内容 part 会很有用。如果您想到Microsoft PowerPoint,LibreOffice Impress等演示软件,在典型的双屏幕设置中,观众会看到当前的演示幻灯片,而演示者会看到当前的幻灯片以及计时器和演讲者注释...... / p>
对于非交互式内容,例如代表幻灯片的PNG,这只是在两个屏幕上显示相同图像的问题(以及主屏幕上的其他内容)。
但是,对于交互式内容,例如WebView
,有时很难进行此类镜像。例如,我们没有好的方法可以知道WebView
的内容何时可能会发生变化,因为它可能基于纯粹在WebView
内部的内容(例如,完成AJAX调用)而不是我们分开做的事情。而且,即使我们 知道WebView
的内容何时发生了变化,我们也没有办法让其他WebView
呈现相同的内容。
所以我想我会尝试设置一个MirroringFrameLayout
,使用getDrawingCache()
来检索容器内容的Bitmap
并将其传递给可以在其上呈现的人 - 屏幕(例如,ImageView
中显示的Presentation
。
但是,启用硬件加速后,setDrawingCacheEnabled(true)
is somewhat of a no-op:
启用绘图缓存类似于关闭硬件加速时设置图层。打开硬件加速时,启用绘图缓存对渲染没有影响,因为系统使用不同的加速机制忽略该标志。
在这些情况下调用getDrawingCache()
会强制draw()
View
到位图支持的Canvas
,而不是实际使用缓存。由于draw()
可能会很昂贵,因此频繁执行draw()
(例如,通过postOnAnimation()
触发)会导致jank。
因此,我试图确定是否还有其他“绘图缓存”,超出getDrawingCache()
,我们可以在启用硬件加速时使用,可用于设置此镜像,这是更多高效。从我所看到的,没有这样的缓存,因为从SDK应用程序的角度来看,层是有效的只写。但是,我希望也许我错过了一些解决方案。
提前致谢!
答案 0 :(得分:13)
您可以使用setLayerType(View.LAYER_TYPE_SOFTWARE, null)
,但它会产生副作用,即每次更新时都会使View重绘速度较慢。创建一个在两个画布上绘制视图的自定义ViewGroup
会更高效(每个屏幕一个)。您也可以简单地使用ViewTreeObserver
并在每个绘制回调上强制您的视图渲染在第二个屏幕上。我真的建议你不要试图滥用这种用例的绘图缓存/图层类型。