Я изо всех сил пытаюсь понять процесс рисования SurfaceView
и, следовательно, всю систему Surface
/ Canvas
/ Bitmap
, которая используется в Android.
Я прочитал все статьи и страницы документации API, которые мне удалось найти на сайте разработчиков Android, несколько руководств по графике для Android, исходный код LunarLander и этот вопрос .
Скажите, пожалуйста, какие из этих утверждений верны, а какие нет и почему.
Canvas
Bitmap
к нему прикреплено собственное . к нему прикрепленоSurface
собственноеCanvas
.- Все
View
окна используют одноSurface
и то же и, следовательно, используют одно и то жеCanvas
. SurfaceView
является подклассомView
, который, в отличие от другихView
подклассов иView
самого себя, имеет свой собственныйSurface
.
Есть еще один дополнительный вопрос:
- Зачем нужен
Surface
класс, если он уже естьCanvas
для высокоуровневых операций с битовой картой. Приведите пример ситуации, когдаCanvas
не подходит для выполнения работы, которуюSurface
можно выполнять.
android
android-canvas
surfaceview
fyodorananiev
источник
источник
Ответы:
Вот несколько определений:
Поверхность - это объект, содержащий пиксели, которые накладываются на экран. Каждое окно, которое вы видите на экране (диалоговое окно, ваше полноэкранное действие, строка состояния), имеет свою собственную поверхность, на которую оно обращается, и Surface Flinger отображает их на окончательном дисплее в их правильном Z-порядке. Поверхность обычно имеет более одного буфера (обычно два) для рендеринга с двойной буферизацией: приложение может рисовать свое следующее состояние пользовательского интерфейса, в то время как отражатель поверхности составляет экран, используя последний буфер, без необходимости дожидаться завершения работы приложения. Рисунок.
Окно в основном похоже на окно на рабочем столе. Он имеет единственную поверхность, на которой отображается содержимое окна. Приложение взаимодействует с диспетчером окон для создания окон; Диспетчер окон создает поверхность для каждого окна и передает ее приложению для рисования. Приложение может рисовать на поверхности все, что угодно; для оконного менеджера это просто непрозрачный прямоугольник.
Представление - это интерактивный элемент пользовательского интерфейса внутри окна. Окно имеет прикрепленную к нему единую иерархию представлений, которая обеспечивает все поведение окна. Всякий раз, когда окно необходимо перерисовать (например, из-за того, что представление стало недействительным), это делается на поверхности окна. Поверхность заблокирована, что возвращает Canvas, который можно использовать для рисования на ней. Обход отрисовки выполняется вниз по иерархии, передавая Canvas вниз для каждого представления, чтобы отрисовать его часть пользовательского интерфейса. После этого Surface разблокируется и публикуется, так что только что нарисованный буфер перемещается на передний план, чтобы затем его компоновали на экран с помощью Surface Flinger.
SurfaceView - это специальная реализация View, которая также создает свою собственную выделенную поверхность для непосредственного рисования приложением (за пределами обычной иерархии представлений, которая в противном случае должна совместно использовать одну поверхность для окна). Это работает проще, чем вы можете ожидать - все, что делает SurfaceView, - это просит диспетчер окон создать новое окно, сообщая ему Z-порядок, что окно сразу за или перед окном SurfaceView, и позиционирует его для соответствия где SurfaceView отображается в содержащем окне. Если поверхность размещается за главным окном (в Z-порядке), SurfaceView также заполняет свою часть главного окна прозрачностью, чтобы поверхность была видна.
Растровое изображение - это просто интерфейс для некоторых данных пикселей. Пиксели могут быть выделены самим растровым изображением, когда вы его напрямую создаете, или он может указывать на пиксели, которыми он не владеет, например, что внутри происходит при подключении холста к поверхности для рисования. (Растровое изображение создается и указывает на текущий буфер рисования поверхности.)
Также имейте в виду, что из этого следует, что SurfaceView - довольно тяжелый объект. Если у вас есть несколько SurfaceView в конкретном пользовательском интерфейсе, остановитесь и подумайте, действительно ли это необходимо. Если у вас их больше двух, у вас почти наверняка их слишком много.
источник
#hackbod's
ответу, онSurfaceView
также может быть отрисован из вторичного потока, что невозможно дляView
объектовВот очень простой и простой концептуальный обзор того, как происходит взаимодействие между Window, Surface, Canvas и Bitmap.
Иногда визуальное представление очень помогает в понимании искаженных концепций.
Надеюсь, этот рисунок может кому-то помочь.
источник
Bitmap - это просто оболочка для набора пикселей. Думайте об этом как о массиве пикселей с некоторыми другими удобными функциями.
Canvas - это просто класс, содержащий все методы рисования. Он похож на класс Graphics в AWT / Swing, если вы с ним знакомы. Вся логика того, как рисовать круг, прямоугольник и т. Д., Содержится внутри Canvas. Холст отрисовывается на растровом изображении или открытом контейнере GL, но нет причин, по которым в будущем его можно было бы расширить для рисования на других типах растров.
SurfaceView - это представление, содержащее поверхность. Поверхность похожа на растровое изображение (в ней есть хранилище пикселей). Я не знаю, как это реализовано, но я бы предположил, что это своего рода оболочка Bitmap с дополнительными методами для вещей, которые напрямую связаны с отображением экрана (это причина поверхности, Bitmap слишком общий). Вы можете получить Canvas со своей поверхности, которая действительно связывает Canvas с нижележащим растровым изображением.
Ваши вопросы.
Да, холст работает с растровым изображением (или открытой панелью GL). Surface предоставляет вам холст, который работает на любой поверхности, которая используется для своего хранилища пикселей в стиле Bitmap.
Нет. Вы можете иметь столько видов поверхностей, сколько захотите.
Да. Так же, как ListView является подклассом View, который имеет собственную структуру данных List. Каждый подкласс View делает что-то свое.
источник
Bitmap
аSurface
это просто разные виды хранилища пикселей иCanvas
можно ли обернуть любой из них?