Android 에서 SurfaceView 와 일반 view 의 차이 및 사용
14608 단어 AndroidSurfaceView일반 보기
Surface View 의 첫 인상 은 view 입 니 다.View 를 계승 하기 때문에 두 개의 직접 하위 클래스 인 GLSurface View,VideoView 가 있 습 니 다.그러나 SDK 문서 인 Surface View 와 일반적인 view 에 따라 차이 가 크다.
가장 현저 한 차이 점 은 일반 view 와 그의 숙주 창 이 하나의 그림 표면(Surface)을 공유 하 는 것 이다.Surface View 도 View 의 트 리 구조 에 있 지만 자신 만 의 그림 표면 이 있 고 Surface 내부 에 Canvas 가 있어 이 Canvas 를 이용 하여 그 릴 수 있다.
Surface View 는 보기 구조 차원 에 직접 그림 표면(Surface)을 삽입 합 니 다.이 Surface 의 형식,크기 를 제어 할 수 있 습 니 다.Surface View 는 화면 에 Surface 를 올 바 르 게 배치 하 는 것 을 책임 집 니 다.쉽게 말 하면 Surface View 는 자신의 Surface 를 가지 고 숙주 창 과 분리 된다.
창 에 있 는 view 가 하나의 window 를 공유 하고 window 는 하나의 Surface 에 대응 하 는 것 을 알 기 때문에 창의 view 는 하나의 Surface 를 공유 하고 Surface View 는 자신의 Surface 를 가지 고 있 습 니 다.Surface View 는 응용 창 뒤에 있 는 새 창 을 만 듭 니 다.Surface View 는 Window 에 구멍 을 파 는 것 과 같 습 니 다.바로 이 구멍 에 표 시 됩 니 다.다른 View 는 Window 에 표시 되 기 때문에 View 는 Surface View 에 표시 할 수도 있 고 일부 층 을 Surface View 에 추가 할 수도 있 습 니 다.
Surface View 의 창 을 새로 고 칠 때 프로그램의 창 을 다시 그 릴 필요 가 없습니다.안 드 로 이 드 일반 창의 보기 그리 기 체 제 는 한 층 한 층 입 니 다.모든 하위 요소 나 부분 적 인 새로 고침 은 전체 보기 구 조 를 다시 그 릴 수 있 습 니 다.
일반적인 view 에 대해 안 드 로 이 드 의 창 인 터 페 이 스 는 여러 View 로 구 성 된 View Hierachy 의 트 리 구 조 를 포함 하고 있 으 며,맨 윗 층 의 DecorView 만 WMS 에 보 입 니 다.이 DecorView 는 WMS 에 해당 하 는 WindowState 가 있 습 니 다.이때 앱 이 Surface 생 성 을 요청 할 때 Surface Flinger 내부 에 해당 하 는 Layer 를 만 듭 니 다.Surface View 에 대해 서 는 Surface 를 가지 고 있 습 니 다.이 Surface 는 WMS 에 해당 하 는 Window State 가 있 고 Surface Flinger 에 해당 하 는 layer 가 있 습 니 다.Surface View 는 앱 에서 볼 때 View hierachy 구조 에 있 지만 WMS 와 Surface Flinger 에 서 는 숙주 창 과 분 리 됩 니 다.따라서 Surface View 의 Surface 렌 더 링 은 단독 스 레 드 에 넣 을 수 있 고 메 인 스 레 드 가 이벤트 에 대한 응답 에 영향 을 주지 않 습 니 다.그러나 이 서 피 스 는 View hierachy 에 없 기 때문에 디 스 플레이 도 View 의 속성 에 의 해 제어 되 지 않 기 때문에 이동,크기 조정 등 변환 을 할 수 없습니다(Surface View 에 ScrollBy,ScrollTo 작업 은 효과 가 없습니다(투명도,회전 도 있 습 니 다).일반 View 는 이동 을 하고 내부 내용 은 이동 하 며 Surface View 는 이러한 작업 을 하면 내부 가 이동 하지 않 습 니 다.이 를 감 싼 View Group 을 이동 회전 시 키 는 등 작업 을 하면 우리 가 원 하 는 효 과 를 얻 을 수 없습니다.또한 SurfaceView 는 RecyclerView 나 ScrollView 와 같은 기능 에 넣 을 수 없고 일부 View 의 특성 도 사용 할 수 없습니다.
Surface View 는 이동,크기 조정,회전 등 애니메이션 을 지원 하지 않 지만 Surface View 를 이용 하여 지원 되 지 않 는 애니메이션 을 테스트 할 때 7.0,심지어 더 높 은 버 전의 Android 시스템 을 사용 하면 Surface View 도 이동,크기 조정 애니메이션 작업 을 지원 하 는 것 을 발견 할 수 있 습 니 다.
View 와 Surface View 의 차이 점:
View 는 주동 적 인 업 데 이 트 를 적용 하고 SurfaceView 는 잦 은 리 셋 과 같은 수 동적 인 업 데 이 트 를 적용 합 니 다.
View 는 UI 스 레 드 에서 업 데 이 트 됩 니 다.비 UI 스 레 드 에서 업 데 이 트 를 하면 오류 가 발생 할 수 있 습 니 다.주 스 레 드 에서 view 를 업데이트 할 때 시간 이 너무 오래 걸 리 면 오류 가 발생 할 수 있 습 니 다.Surface View 는 하위 스 레 드 에서 리 셋 하면 주 스 레 드 를 막 지 않 고 인터페이스 가 자주 업데이트 되 고 프레임 율 에 대한 요구 가 높 은 경우 에 적 용 됩 니 다.
Surface View 는 리 셋 주파 수 를 제어 할 수 있다.
Surface View 바 텀 은 더 블 캐 시 체 제 를 이용 하여 그림 을 그 릴 때 반 짝 임 문제 가 발생 하지 않 습 니 다.
더 블 버퍼 기술 은 게임 개발 에서 중요 한 기술 로 주로 부분 적 인 스크린 이 반복 되 는 반 짝 임 을 해결 하기 위해 서 이다.게임,동 영상 등 화면 변화 가 빈번 하고 앞 에 다 표시 되 지 않 았 으 며 프로그램 이 다시 그 려 달라 고 요청 하면 화면 이 계속 반 짝 거 린 다.더 블 버퍼 기술 은 처리 할 그림 을 메모리 에서 처리 한 후,그 릴 것 을 메모리 영역 에 먼저 그린 다음,전체적으로 한꺼번에 그 려 서 화면 에 표시 합 니 다.
2 SurfaceView 사용 절차
Surface View 를 사용 하 는 단계:
먼저 Surface View 를 계승 하여 Surface Holder.Callback 인 터 페 이 스 를 실현 해 야 한다.
다시 쓰 는 방법:
Surface Holder.lockCanvas 는 Canvas 대상 을 가 져 오고 캔버스 를 잠 그 며 Canvas 그림 을 호출 합 니 다.Surface Holder.unlockCanvasAndPost 는 캔버스 잠 금 을 끝내 고 변경 사항 을 제출 합 니 다.
3 SurfaceHolder
Surface View 의 더 블 버퍼 메커니즘 은 시스템 메모 리 를 매우 소모 하 는데,안 드 로 이 드 는 Surface View 가 보이 지 않 을 때 Surface View 의 Surface Holder 를 즉시 폐기 해 시스템 자원 을 절약 하 는 목적 을 달성 하기 때문에 Surface Holder 의 리 셋 함 수 를 이용 해 Surface Holder 를 유지 해 야 한다 고 규정 하고 있다.
Surface Holder 의 생 성,소각 또는 변 화 를 알 수 있 도록 세 개의 반전 함 수 를 제공 합 니 다.
void surfaceDestroyed(SurfaceHolder holder):SurfaceHolder 가 소각 되 었 을 때 리 셋 합 니 다.
void surfaceCreated(SurfaceHolder holder):SurfaceHolder 가 생 성 되 었 을 때 리 셋 합 니 다.
void surfaceChange(SurfaceHolder holder):SurfaceHolder 의 크기 나 형식 이 바 뀌 었 을 때 리 셋 됩 니 다.
abstract Canvas lockCanvas():
Canvas 대상 을 가 져 오고 잠 그 고 얻 은 Canvas 대상 은 Surface 의 한 구성원 입 니 다.
** abstract Canvas lockCanvas(Rectdirty):**
dirty 가 지정 한 사각형 영역 만 잠 금 합 니 다.
abstract void unlockCanvasAndPost(Canvascanvas)
서 피 스 의 데 이 터 를 변경 한 후 동기 화 잠 금 을 풀 고 변경 사항 을 제출 한 후 새로운 데 이 터 를 보 여 주 며 같은 때 서 피 스 의 관련 데 이 터 를 잃 어 버 립 니 다.
public abstract void setType (int type):
Surface 의 종 류 를 설정 합 니 다.높 은 버 전에 서 set Type 이라는 방법 은 depreciated 에 의 해 설정 되 었 고 시스템 은 자동 으로 설 정 됩 니 다.
Surface View 의 호환성
Android 4.0 이하 Surface View 는 버퍼 를 자동 으로 유지 하지 않 습 니 다.동 영상 을 재생 할 때 Surface View 를 사용 하여 게임 애플 리 케 이 션 을 개발 하려 면 우리 스스로 이 버퍼 를 유지 해 야 합 니 다.
// 4.0
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
4 Surface View 의 간단 한 사용원형 그리 기:
public class SurfaceViewDemo extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mSurfaceHolder;
private Canvas mCanvas;
private Paint paint;
public SurfaceViewDemo(Context context) {
this(context,null,0);
}
public SurfaceViewDemo(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public SurfaceViewDemo(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("=========surfaceCreated========");
new Thread(new Runnable() {
@Override
public void run() {
draw();
}
}).start();
}
private void draw() {
try {
System.out.println("============draw========");
mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.drawCircle(500,500,300,paint);
mCanvas.drawCircle(100,100,20,paint);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mCanvas != null)
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.println("=========surfaceChanged========");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("=========surfaceDestroyed========");
}
}
리 셋 함수 호출:
첫 입장:
=surfaceCreated
=surfaceChanged
====draw
홈 키 클릭:
=surfaceDestroyed
다시 원래 페이지 로 돌아 가기:
=surfaceCreated
=surfaceChanged
====draw
그래서 Surface View 가 보이 지 않 을 때 Surface Holder 를 없 애고 다시 들 어가 면 surfaceCreated 를 다시 호출 하여 새로운 Surface Holder 를 생 성 합 니 다.surfaceChanged 함 수 는 surfaceCreated 호출 후 이 함 수 는 적어도 한 번 호출 됩 니 다.
Surface View 에서 동 영상 재생,저장 권한 잊 지 마 세 요.
mediaPlayer.setDisplay(getHolder());
비디오 자원 은 시 뮬 레이 터 를 이용 하여 녹화 한 mp4 영상 이다.
public class SurfaceViewDemo2 extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mSurfaceHolder;
private Canvas mCanvas;
private Paint paint;
private MediaPlayer mediaPlayer;
public SurfaceViewDemo2(Context context) {
this(context,null,0);
}
public SurfaceViewDemo2(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public SurfaceViewDemo2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
setZOrderOnTop(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("=========surfaceCreated========");
new Thread(new Runnable() {
@Override
public void run() {
//draw();
play();
}
}).start();
}
private void draw() {
try {
System.out.println("============draw========");
mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.drawCircle(500,500,300,paint);
mCanvas.drawCircle(100,100,20,paint);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mCanvas != null)
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.println("=========surfaceChanged========");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("=========surfaceDestroyed========");
if (mediaPlayer != null ){
stop();
}
}
protected void stop() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
protected void play() {
String path = "/sdcard/DCIM/Camera/VID_20190110_102218.mp4";
File file = new File(path);
if (!file.exists()) {
return;
}
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//
mediaPlayer.setDataSource(file.getAbsolutePath());
// SurfaceHolder
mediaPlayer.setDisplay(getHolder());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
replay();
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
play();
return false;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
protected void replay() {
if (mediaPlayer!=null){
mediaPlayer.start();
}else{
play();
}
}
protected void pause() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}else{
mediaPlayer.start();
}
}
}
Surface View 를 평행 이동,회전 등 동작 을 추가 합 니 다.
mSurfaceView 를 추가 합 니 다.scrollBy(10,10);
효 과 는 다음 과 같다:전혀 효과 가 없다.
패키지 의 viewgroup 에 크기 조정 애니메이션 을 추가 합 니 다.
mContainer.animate().scaleX(0.4f).scaleY(0.7f);
이때 찍 은 사진 은:
찍 은 사진 은 크기 조정 에 전혀 영향 을 받 지 않 았 다.
안 드 로 이 드 에서 Surface View 와 일반 view 의 차이 점 및 사용 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 안 드 로 이 드 에서 Surface View 와 일반 view 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.