Понимание концепций Canvas и Surface - PullRequest
110 голосов
/ 02 января 2011

Я изо всех сил пытаюсь понять процесс рисования до SurfaceView и, следовательно, всей системы Surface / Canvas / Bitmap, которая используется в Android.

Я прочиталвсе статьи и страницы документации API, которые я смог найти на сайте разработчиков Android, несколько учебных пособий по графике Android, исходный код LunarLander и этот вопрос .

Скажите, какиеиз этих утверждений верны, чего нет, и почему.

  1. Canvas имеет свой собственный Bitmap, связанный с ним.У Surface есть свой собственный Canvas.
  2. Все View окна имеют одинаковый Surface и, таким образом, имеют одинаковые Canvas.
  3. SurfaceView является подклассом View, который, в отличие от других подклассов View и самого View, имеет свой собственный Surface для рисования.

Существует также еще один вопрос:

  • Зачем нужен класс Surface, если уже есть Canvas для высокоуровневых операций с растровым изображением.Приведите пример ситуации, когда Canvas не подходит для выполнения работы, которую может выполнять Surface.

Ответы [ 3 ]

216 голосов
/ 02 января 2011

Вот несколько определений:

  • Поверхность - это объект, содержащий пиксели, которые наложены на экран.Каждое окно, которое вы видите на экране (диалоговое окно, ваша полноэкранная активность, строка состояния), имеет свою собственную поверхность, к которой оно обращается, и Surface Flinger отображает их на конечном экране в правильном Z-порядке.Поверхность, как правило, имеет более одного буфера (обычно два) для рендеринга с двойной буферизацией: приложение может рисовать свое следующее состояние пользовательского интерфейса, в то время как бегунок поверхности создает экран, используя последний буфер, без необходимости ждать завершения приложениярисование.

  • Окно в основном похоже на окно на рабочем столе.Он имеет единственную поверхность, в которой отображается содержимое окна.Приложение взаимодействует с диспетчером окон для создания окон;Диспетчер окон создает поверхность для каждого окна и передает ее приложению для рисования.Приложение может рисовать все что угодно в Surface;для диспетчера окон это просто непрозрачный прямоугольник.

  • Вид - это интерактивный элемент пользовательского интерфейса внутри окна.К окну прикреплена единая иерархия представления, которая обеспечивает все поведение окна.Всякий раз, когда окно необходимо перерисовать (например, из-за того, что представление само себя аннулировало), это делается на поверхности окна.Поверхность заблокирована, что возвращает холст, который можно использовать для рисования в нем.Обход рисования выполняется по иерархии, передавая холст для каждого представления, чтобы нарисовать свою часть пользовательского интерфейса.После этого Поверхность разблокируется и публикуется, так что только что нарисованный буфер переключается на передний план, чтобы затем скомпоновать его с экраном с помощью Surface Flinger.Представление, которое также создает свою собственную выделенную поверхность для непосредственного рисования приложения (за пределами обычной иерархии представления, которая в противном случае должна совместно использовать одну поверхность для окна).Это работает проще, чем вы можете ожидать - все, что делает SurfaceView, - это просит оконный менеджер создать новое окно, сообщая ему Z-порядок того окна непосредственно позади или перед окном SurfaceView и располагая его так, чтобы оно соответствовалогде SurfaceView появляется в содержащем окне.Если поверхность размещается за главным окном (в Z-порядке), SurfaceView также заполняет свою часть главного окна прозрачностью, чтобы ее можно было видеть.

  • Растровое изображениепросто интерфейс для некоторых данных пикселей.Пиксели могут быть выделены самим растровым изображением, когда вы его непосредственно создаете, или оно может указывать на пиксели, которые ему не принадлежат, например, что происходит внутри с подключением Canvas к Surface для рисования.(Растровое изображение создается и указывает на текущий буфер рисования Surface.)

Также имейте в виду, что, как это и подразумевается, SurfaceView является довольно тяжелым объектом.Если у вас есть несколько SurfaceViews в конкретном интерфейсе, остановитесь и подумайте, действительно ли это нужно.Если у вас больше двух, у вас почти наверняка слишком много.

45 голосов
/ 21 июля 2016

A conceptual overview of Window, Surface, Canvas, and Bitmap

Вот очень простой и простой концептуальный обзор того, как происходит взаимодействие между окном, поверхностью, холстом и растровым изображением.
Иногда визуальное представлениеочень помогает в понимании запутанных концепций.
Я надеюсь, что этот рисунок может кому-то помочь.

18 голосов
/ 02 января 2011

Растровое изображение - это просто оболочка для коллекции пикселей. Думайте об этом как о массиве пикселей с некоторыми другими удобными функциями.

Canvas - это просто класс, содержащий все методы рисования. Он похож на класс Graphics в AWT / Swing, если вы знакомы с этим. Вся логика о том, как нарисовать круг, или прямоугольник, и т. Д. Содержится внутри Canvas. Холст рисует на растровом изображении или в открытом контейнере GL, но нет никаких причин, по которым в будущем он может быть расширен для рисования на другие типы растров.

SurfaceView - это представление, которое содержит поверхность. Поверхность похожа на растровое изображение (у нее есть хранилище пикселей). Я не знаю, как это реализовано, но я представляю, что это своего рода обертка для растровых изображений с дополнительными методами для вещей, которые непосредственно связаны с отображением на экране (по этой причине поверхность является слишком общей). Вы можете получить Canvas из вашей Surface, который действительно связывает Canvas с базовым растровым изображением.

Ваши вопросы.

1.Canvas имеет свой собственный растровый файл, прикрепленный к нему. К поверхности прикреплен собственный холст.

Да, холст работает с растровым изображением (или открытой панелью GL). Поверхность дает вам Canvas, который работает с тем, что Surface использует для своего пиксельного хранилища в стиле Bitmap.

2.Все окна имеют одну и ту же поверхность и, следовательно, один и тот же холст.

Нет. Вы можете иметь столько поверхностей, сколько захотите.

3.SurfaceView является подклассом View, который, в отличие от других подклассов View и самого View, имеет собственную поверхность для рисования.

Да. Так же, как ListView является подклассом View, который имеет свою собственную структуру данных List. Каждый подкласс View делает что-то свое.

...