Эффективные «скриншоты» просмотра?

TL; DR: Поскольку getDrawingCache() похоже, вызывает полную перерисовку представления, когда включено ускорение аппаратного обеспечения, есть ли альтернативный способ получения Bitmap (или что-то в этом направлении), который позволяет избежать этого, возможно, путем чтения данных, заполненных (Аппаратное, программное), когда в последний раз был View ?


Некоторые предпосылки:

Android имеет возможность отображать экран с Android 3.0, например, на подключенном HDMI-дисплее. Это можно использовать для презентаций, но это означает, что аудитория видит то же, что и ведущий, что не всегда идеально.

Android 4.2 добавлена Presentation , позволяющая приложениям помещать произвольные вещи на «второй экран» (например, дисплей с подключением HDMI). В этом случае время от времени было бы полезно, чтобы второй экран отображал часть того, что находится на дисплее основного планшета. Если вы считаете, что презентационное программное обеспечение, такое как Microsoft PowerPoint, LibreOffice Impress и т. П., В типичных настройках с двумя экранами, аудитория видит текущий слайд презентации, а ведущий видит текущий слайд и записи таймера и динамиков и …

Для неинтерактивного контента, например PNG, представляющего слайд, это просто вопрос отображения одного и того же изображения на обоих экранах (наряду с другими вещами на основном экране).

Однако для интерактивного контента, такого как WebView , иногда бывает сложно сделать такое зеркалирование. Например, у нас нет хорошего способа узнать, когда содержимое WebView может измениться, так как это может быть сделано на основе всего, что есть в самом WebView (например, для завершения вызовов AJAX), а не в том, что мы делаем отдельно. И даже если бы мы знали, когда изменилось содержимое WebView , у нас нет хорошего способа заставить другой WebView отображать тот же контент.

Поэтому я решил, что попытаюсь настроить MirroringFrameLayout , который будет использовать getDrawingCache() для извлечения Bitmap содержимого контейнера и доставить его кому-то, кто может отображать его на экране (например, ImageView показанный в Presentation ).

Однако при включенном аппаратном ускорении setDrawingCacheEnabled(true) несколько не работает :

Включение кэша чертежа аналогично настройке уровня, когда аппаратное ускорение отключено. Когда аппаратное ускорение включено, включение кеша чертежа не влияет на рендеринг, поскольку в системе используется другой механизм ускорения, который игнорирует флаг.

Вызов getDrawingCache() в этих случаях заставляет полностью draw() в View на Canvas , поддерживающем растровое изображение, а не на самом деле использовать кеш. Так как draw() может быть дорогостоящим, часто делать draw() (например, инициируется через postOnAnimation() ) приводит к jank.

Следовательно, я пытаюсь определить, есть ли какой-нибудь другой «кэш чертежа», помимо getDrawingCache() , который мы можем использовать с включенным аппаратным ускорением, который можно использовать для настройки этого зеркалирования, и это более эффективно. Из того, что я вижу, такого кеша нет, так как уровни эффективно записываются только с точки зрения приложений SDK. Однако я надеюсь, что, возможно, мне не хватает какого-либо решения.

Заранее спасибо!

Вы можете использовать setLayerType(View.LAYER_TYPE_SOFTWARE, null) но он будет иметь побочный эффект, чтобы сделать просмотр медленнее, чтобы перерисовывать каждый раз, когда он обновляется. Было бы гораздо эффективнее создать пользовательскую ViewGroup которая рисует ваш вид на двух холстах (по одному для каждого экрана). Вы также можете просто использовать ViewTreeObserver и при каждом ViewTreeObserver обратного просмотра ваше изображение будет отображаться на втором экране. Я действительно рекомендую вам не пытаться злоупотреблять типом / типом чертежа для такого прецедента.