본문 바로가기

안드로이드

SurfaceView

반응형

개념

anroid.View.view

    android.view.surfaceView 로 view를 상속받고있다

 

-그래픽 처리가 빠른 View

-일반적인 경우에는 view를 통해서 draw()를 그리는것과 별 차이가 없다.

 

그럼 왜 필요하냐?

  안드로이드의 모든 View의 모든행위들은 UI쓰레드에서 동작한다.

  하지만, camerapreview나 동영상 재생같은 처리들은 1초에 몇십프레임을 출력해야하는 

  무거운 작업들이고, AndroidUI혼자 감당하기에는 자원이 부족하여 ANR을 발생하게된다.

   Surfaceview는 UI쓰레드와 별도로 백그라운드 쓰레드에서 동작하여 사용자가 원하는 뷰를 

   원할하게 업데이트를 해주고, 가속성이 좋다.

 

- 일반 view는 ondraw()메소드를 시스템에서 자동으로 호출해줌으로써 화면을그린다.

   하지만 sufaceview는 스레드를 이용해 강제로 화면에 그림을 그린다.

 

애니매이션, 동영상,, 연산처리가 필요한 뷰를  3D작업등에도 이용할수 있다.

구성 

surfaceciew는 자기영역의 부분을 window를 뚫어서 자신이 보여지게끔 하고 

window와 view가 블렌딩되어 화면에 보여지게된다

구현 

 

1. 서피스 홀더: 서피스뷰에 필요한 기능을 제공한다, 콜백인터페이스는 서피스뷰의 변화상태를 

관리하는 인터페이스이다.

2. 잠금기능: 서피스 뷰에 1개의 어플리케이션의 접근만 허용하도록 잠금기능을 제공합니다.

 

 

실습 

 

package com.example.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

public class StageView extends SurfaceView implements SurfaceHolder.Callback {
    static final String TAG = "StageView";
    SurfaceHolder holder;
    Thread thread;

    int width = 0;
    int height = 0;


    public StageView(Context context) {
        super(context);
        Log.d(TAG,"StageView");
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        width = metrics.widthPixels;
        height = metrics.heightPixels;

        //view를 생성할때 surface를 관리하는 holder를 함께생성
        //holder를 상속했기때문에 getholder메소드 호출가능하다.
        holder = getHolder();
        //홀더에 콜백추가
        //surfaceviewd에 변경사항이 있을때 마다 아래에 3개메소드실행
        holder.addCallback(this);
        thread = new StageView.DrawThread();
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
        Log.d(TAG,"surfaceCreated");
        thread.start();
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
        Log.d(TAG,"surfaceChanged");
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
        Log.d(TAG,"surfaceDestroyed");
        thread = null;
    }

    private class DrawThread extends Thread {
        float x = 0, y = 0, r = 50;
        Paint paint;

        public void run() {
            paint = new Paint();
            paint.setColor(Color.RED);
            while (thread != null) {
                //그림판에 락을 걸어 잠근다.
                Canvas canvas = holder.lockCanvas();

                //circle이동
                x += 10;
                y += 10;
                canvas.drawColor(Color.WHITE);
                canvas.drawCircle(x, y, 50, paint);

                if (x > width) x = 0;
                if (y > height) y = 0;

                holder.unlockCanvasAndPost(canvas);
            }
        }
    }
}
package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.widget.FrameLayout;

public class MainActivity extends AppCompatActivity {
    static final String TAG = "MainActivity";
    private FrameLayout stage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreate");
        setContentView(R.layout.activity_main);
        stage = findViewById(R.id.stage);
        //서피스 뷰생성
        SurfaceView view = new StageView(this);
        //뷰에 서피스뷰 넣어주기
        stage.addView(view);

    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/stage"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

 

 

 

 

 

출처:https://dduddublog.tistory.com/68 

 

Android SurfaceView

SurfaceView란? SufaceView라는 이름에서 알 수 있듯이 Textview나 ImageView처럼 내용을 표시할 수 있는 View이다. SurfaceView에서 직접 내용을 뿌려주지는 않고, SurfaceHolder를 통해 데이터를 받아서 처리한..

dduddublog.tistory.com

https://blog.naver.com/muri1004/221054311714

 

[Android] SurfaceView 개념 및 예제

SurfaceView 란? SurfaceView는 View를 상속받는 클래스이다. 일반 View는 onDraw 메소드를 시스템...

blog.naver.com

https://heepie.me/243

 

[2018.01.01] 88. 서피스 뷰(Surface View) 개념과 실습

도입 이번 포스팅에서는 서피스 뷰(Surface View)의 개념을 학습한 뒤 실습을 할 예정이다. 안드로이드 머티리얼 디자인을 실습하며 안드로이드의 Window와 서피스 뷰 개념에 대해 궁금했고 개념을

heepie.me

 

반응형

'안드로이드' 카테고리의 다른 글

window  (0) 2022.10.13
onCreate()에서 finish경우 빈화면  (0) 2022.09.08
안드로이드 Mainthread 와 subthread  (0) 2022.01.11
뷰의 터치이벤트 관리  (0) 2021.10.18
KeyEvent  (0) 2021.06.23