현재 다루는 코드에서는 화면 상으로 Android device 와 연결된 특정 기기의 화면을 실시간으로 투사해야 한다.
이런 경우 SurfaceView 를 활용한다.
일단 공식문서에서 어떻게 설명하고 있는지를 봐보자
Provides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen
The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.
음... 뇌가 아파오는 설명이다.
한국 블로그들을 구글링한 결과 다음과 같은 설명들을 얻었다.
- SurfaceView는 view를 상속
- 기존의 view 는 모두 화면 관련 처리를 ui 스레드에서 처리 가능
- 하지만 일부 동영상 등 무거운 작업의 경우 ANR이 생길 수도 있음
- 따라서 이런 때 SurfaceView를 사용. 별도의 백그라운드에서 동작하여 빠른 뷰 업데이트가 가능하다고 한다.
어떻게 이런 방식이 가능하냐면
기존 처럼 그리는 것을 시스템에 맡기지 않고, 스레드를 통해 강제로 원하는 시점에 바로 그리는 것이라고 한다.
그려지는 원리는 다음과 같다. SurfaceView 자신 만큼의 부분을 Window에서 뚫어서
최종적으로는 Window에 올려진 View 위에서 SurfaceView와 View가 같이 보이는 방식이다 (Blended).
SurfaceView를 사용할 경우 다음 4가지의 메서드를 오버라이드 해야 한다.
1. public void onDraw (Canvas canvas)
2. public void surfaceChanged() : 뷰 변경시 호출
3. public void surfaceCreated() : 뷰 생성시 호출
4. public void surfaceDestroyed() : 뷰 종료시 호출
private final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
};
이런식으로 오버라이드 해서 적절한 처리를 해주면 된다.
-------------------
참고한 사이트
https://developer.android.com/reference/android/view/SurfaceView
https://happysuzy.tistory.com/180