Różnica między SurfaceView a View?

211

Kiedy jest to konieczne lub lepiej użyć SurfaceViewzamiast View?

Viktor
źródło

Odpowiedzi:

210

Widoki są rysowane w tym samym wątku GUI, który jest również używany do wszystkich interakcji użytkownika.

Więc jeśli musisz szybko zaktualizować GUI lub jeśli renderowanie zajmuje zbyt dużo czasu i wpływa na wrażenia użytkownika, użyj SurfaceView.

Niko Gamulin
źródło
2
Sprawdź odpowiedź Pierra, która zawiera więcej szczegółów.
Helin Wang
4
Oficjalna szczegółowa odpowiedź: developer.android.com/guide/topics/graphics/2d-graphics.html
Helin Wang
To już nie jest takie proste. Sprawdź odpowiedź pierra; zawiera link do szczegółowej dokumentacji architektury ( source.android.com/devices/graphics/architecture.html ) i wyjaśnia, dlaczego przyspieszenie sprzętowe renderowania na kanwie może uczynić niestandardowe widoki lepszym wyborem.
fadden
1
Kiedy używać FrameLayout do układania widoków zamiast SurfaceView?
IgorGanapolsky
103

Kilka rzeczy, które zauważyłem:

  • SurfaceViews zawierają ładny mechanizm renderowania, który pozwala wątkom aktualizować zawartość powierzchni bez użycia programu obsługi (dobre dla animacji).
  • Widoki powierzchni nie mogą być przezroczyste, mogą pojawiać się tylko za innymi elementami w hierarchii widoku.
  • Przekonałem się, że animacje są znacznie szybsze niż renderowanie w widoku.

Aby uzyskać więcej informacji (i świetny przykład użycia), zapoznaj się z projektem LunarLander w sekcji przykładów SDK.

Ralphleon
źródło
36
Do Twojej wiadomości ... SurfaceView może być teraz przezroczysty: stackoverflow.com/questions/5391089/...
Steve
@Ralphleon: Co masz na myśli mówiąc, że widoki powierzchni nie mogą być przezroczyste? Czy inne widoki mogą nakładać się na widok powierzchni? Na przykład, czy mogę tymczasowo wyświetlić ListView w widoku Surface?
Ashwin,
78

zaktualizowano 05/09/2014

DOBRZE. Mamy teraz oficjalny dokument. Mówił wszystko, co wspomniałem, w lepszy sposób.


Przeczytaj więcej tutaj .

Tak, główna różnica polega na tym, że SurfaceView można aktualizować w wątku tła. Jest jednak coś, co może Cię obchodzić.

  • SurfaceView ma dedykowany bufor powierzchni, podczas gdy cały widok ma jeden bufor powierzchni przydzielony przez ViewRoot. Innymi słowy, SurfaceView kosztuje więcej zasobów.

  • SurfaceView nie może być przyspieszany sprzętowo (od JB4.2), podczas gdy 95% operacji w normalnym widoku jest przyspieszane sprzętowo przy użyciu OpenGL ES.

  • Należy wykonać więcej pracy, aby utworzyć niestandardową powierzchnię. Musisz nasłuchiwać zdarzenia SurfaceCreated / Destroy, utworzyć wątek renderujący, a co ważniejsze, zsynchronizować wątek renderujący i wątek główny. Aby jednak dostosować widok, wystarczy tylko przesłonić onDrawmetodę.

  • Czas aktualizacji jest inny. Normalny mechanizm aktualizacji widoku jest ograniczony lub kontrolowany przez framework: Wywołujesz view.invalidatew wątku interfejsu użytkownika lub view.postInvalidw innym wątku, aby wskazać frameworkowi, że widok powinien zostać zaktualizowany. Jednak widok nie zostanie natychmiast zaktualizowany, ale poczekaj, aż nadejdzie następne zdarzenie VSYNC. Łatwe podejście do zrozumienia VSYNC polega na uznaniu, że jest to zegar, który uruchamia się co 16 ms dla ekranu 60 klatek na sekundę. W Androidzie wszystkie normalne aktualizacje widoku (i wyświetlane w rzeczywistości, ale dzisiaj nie będę o tym mówić) są zsynchronizowane z VSYNC, aby uzyskać lepszą płynność. Teraz wracając do SurfaceView, możesz wyrenderować go w dowolnym momencie. Jednak nie mogę powiedzieć, czy jest to zaletą, ponieważ wyświetlacz jest również synchronizowany z VSYNC, jak wspomniano wcześniej.
pierrotlefou
źródło
2
Po twojej odpowiedzi mam wrażenie, że lepiej jest użyć klasy pochodnej View niż SurfaceView. A może coś nie tak? Byłoby to sprzeczne z większością samouczków związanych z tworzeniem gier 2D.
Storm
2
@ Zwolnij coś, co należy wziąć pod uwagę, że SurfaceView z założenia nie powinien blokować wątku interfejsu użytkownika, w którym widok można modyfikować tylko za pomocą wątku interfejsu użytkownika. W większości gier SurfaceViews wykona dobre renderowanie, które zablokuje wątek interfejsu użytkownika za pomocą prostego widoku. To jest podstawowa korzyść, z mojego zrozumienia, SurfaceView.
zgc7009
Co rozumiesz przez tworzenie wątku renderującego . Musimy to utworzyć ręcznie za każdym razem?
IgorGanapolsky
44

Główną różnicą jest to, że SurfaceViewmożna na niej wyciągnąć teady tła, ale Viewsnie można. SurfaceViewsużyj więcej zasobów, więc nie chcesz ich używać, chyba że musisz.

jcoder
źródło
„Jednak zużywają więcej zasobów, więc nie chcesz ich używać, chyba że musisz”. - Kto używa więcej zasobów? Widoki czy SurfaceViews?
Dror
6
Przegląd surfowania wykorzystuje więcej zasobów niż widoków
Ritesh Gune,
1
@RiteshGune ile?
Alex Sifuentes
Kiedy my musimy ?
IgorGanapolsky
12

A SurfaceViewto niestandardowy widok w Androidzie, którego można używać do rysowania w nim.

Główną różnicą między a Viewi a SurfaceViewjest to, że rysowany jest widok UI Thread, który jest używany do wszystkich interakcji użytkownika.

Jeśli chcesz zaktualizować interfejs użytkownika wystarczająco szybko i wyświetlić w nim dużą ilość informacji, SurfaceView jest lepszym wyborem.

Ale istnieje kilka technicznych aspektów SurfaceView:

1. Nie są przyspieszane sprzętowo.

2. Zwykłe widoki są renderowane podczas wywoływania metody invalidatelub postInvalidate(), ale to nie znaczy, że widok zostanie natychmiast zaktualizowany (A VSYNCzostanie wysłana, a system operacyjny decyduje, kiedy jest ona aktualizowana. Na SurfaceViewmogą być natychmiast aktualizowane.

3. SurfaceView ma przydzielony surface buffer, więc jest bardziej kosztowny

Setu Kumar Basak
źródło
Dlaczego ważne jest przyspieszenie sprzętowe ?
IgorGanapolsky
8

Jedną z głównych różnic między podglądem powierzchni a widokiem jest to, że aby odświeżyć ekran dla normalnego widoku, musimy wywołać metodę unieważnienia z tego samego wątku, w którym widok jest zdefiniowany. Ale nawet jeśli wywołamy unieważnienie, odświeżanie nie nastąpi natychmiast. Występuje dopiero po kolejnym nadejściu sygnału VSYNC. Sygnał VSYNC jest sygnałem generowanym przez jądro, które zdarza się co 16,6 ms lub jest to również znane jako 60 ramek na sekundę. Jeśli więc chcemy mieć większą kontrolę nad odświeżaniem ekranu (na przykład w przypadku bardzo szybko poruszającej się animacji), nie powinniśmy używać normalnej klasy widoku.

Z drugiej strony, w przypadku podglądu powierzchni, możemy odświeżyć ekran tak szybko, jak chcemy i możemy to zrobić z wątku w tle. Odświeżenie widoku powierzchni naprawdę nie zależy od VSYNC, a jest to bardzo przydatne, jeśli chcemy wykonać szybką animację. Mam kilka filmów szkoleniowych i przykładową aplikację, która ładnie wyjaśnia wszystkie te rzeczy. Obejrzyj następujące filmy szkoleniowe.

https://youtu.be/kRqsoApOr9U

https://youtu.be/Ji84HJ85FIQ

https://youtu.be/U8igPoyrUf8

somenath mukhopadhyay
źródło
0

Dlaczego warto korzystać z SurfaceView, a nie z klasycznej klasy View ...

Jednym z głównych powodów jest to, że SurfaceView może szybko renderować ekran.

Krótko mówiąc, SV jest bardziej zdolny do zarządzania czasem i renderowania animacji.

Aby lepiej zrozumieć, czym jest SurfaceView, musimy porównać go z klasą View.

Jaka jest różnica ... sprawdź to proste wyjaśnienie w filmie

https://m.youtube.com/watch?feature=youtu.be&v=eltlqsHSG30

Cóż, z Widokiem mamy jeden poważny problem ... czas renderowania animacji.

Zwykle funkcja onDraw () jest wywoływana z systemu wykonawczego Android.

Tak więc, gdy system wykonawczy Android wywołuje funkcję onDraw (), wówczas aplikacja nie może kontrolować

czas wyświetlania, a to jest ważne dla animacji. Mamy luki czasowe

między aplikacją (naszą grą) a systemem wykonawczym Android.

SV może wywołać onDraw () przez dedykowany wątek.

Zatem: aplikacja kontroluje czas. Możemy więc wyświetlić następny obraz bitmapowy animacji.

Takis Doris
źródło