Подтвердить что ты не робот

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

TL; DR: Поскольку getDrawingCache(), похоже, вызывает полное перерисовку View, когда аппаратное ускорение включено, есть ли альтернативный способ получения 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. Тем не менее, я надеюсь, что, возможно, мне не хватает какого-либо решения.

Спасибо заранее!

4b9b3361

Ответ 1

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