Android Surface View 운영 체제 분석-백 엔 드 로 전환 하고 프로그램 에 다시 들 어 갈 때의 이상 처리

많은 친구 들 이 이런 문 제 를 겪 었 습 니 다.프로그램 이 실 행 될 때 백 스테이지 로 전환 한 다음 에 다시 들 어가 면 이상 을 알 릴 수 있 습 니 다.본 고 는 이런 문제 에 대해 Surface View 의 운영 체 제 를 전면적으로 설명 하고 이런 원 리 를 이해 하면 이런 문 제 를 스스로 해결 할 수 있 습 니 다.
       우 리 는 보통 HOME 버튼 을 누 르 거나 버튼 을 되 돌려 주 는 등 동작 을 통 해 백 스테이지 로 전환 한 후에 다시 프로그램 에 들 어 갈 수 있 습 니 다.이 럴 때 이상 을 알 릴 수 있 습 니 다.여기 서 Surface View 가 보고 할 수 있 는 이상 은 주로 두 가지 가 있 는데 다음 과 같다.
       1.캔버스 이상 제출.다음 그림(시 뮬 레이 터 오류 알림 및 Logcat Detail)

자바 코드

public void draw() {  
  try {  
    canvas = sfh.lockCanvas();  
    if (canvas != null) {  
      canvas.drawColor(Color.WHITE);  
      canvas.drawBitmap(bmp, bmp_x, bmp_y, paint);  
    }  
  } catch (Exception e) {  
    Log.v("Himi", "draw is Error!");  
  } finally {//  1  
    if (canvas != null)//  2  
      sfh.unlockCanvasAndPost(canvas);  
  }  
} 
      비고 1 을 먼저 보 겠 습 니 다.이전 글 에서 제 가 왜 sfh.unlock Canvas AndPost(canvas)를 설명 한 적 이 있 습 니 다.finally 에 적 힌 것 은 캔버스 를 정상적으로 제출 할 수 있 도록 하기 위해 서다.
       오늘 은 주로 비고 2 를 말 합 니 다.여기 서 canvas 가 비어 있 는 지 여 부 를 판정 해 야 합 니 다.프로그램 이 배경 에 들 어 갈 때 canvas 는 얻 을 수 없 기 때 문 입 니 다!그러면 canvas 가 비어 있 으 면 캔버스 를 제출 하면 매개 변수 가 이상 한 오류 가 발생 합 니 다!
       2.스 레 드 작 동 이상.다음 그림(시 뮬 레이 터 오류 알림 및 Logcat Detail)

       이러한 이상 은 프로그램 이 실행 되 는 동안 홈 단 추 를 누 른 후에 다시 프로그램 에 들 어 갈 때 발생 하 는 이상 입 니 다.이상 하 게 도 우리 의 스 레 드 가 시작 되 었 습 니 다!왜 돌아 오 면 버튼 이 괜찮아요?
       OK,다음은 안 드 로 이 드 에서 Back 과 Home 버튼 의 메커니즘 을 자세히 설명해 드 리 겠 습 니 다!그리고 문 제 를 분석 하고 문 제 를 해결 하 세 요!
       다음 MySurface View Animation.java 클래스 의 코드 를 보십시오.
자바 코드

public class MySurfaceViewAnimation extends SurfaceView implements Callback, Runnable {  
  private Thread th;  
  private SurfaceHolder sfh;  
  private Canvas canvas;  
  private Paint paint;  
  private Bitmap bmp;  
  private int bmp_x, bmp_y;  
  public MySurfaceViewAnimation(Context context) {  
    super(context);  
    this.setKeepScreenOn(true);  
    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.himi_dream);  
    sfh = this.getHolder();  
    sfh.addCallback(this);  
    paint = new Paint();  
    paint.setAntiAlias(true);  
    this.setLongClickable(true);  
    th = new Thread(this, "himi_Thread_one");  
    Log.e("Himi", "MySurfaceViewAnimation");  
  }  
  public void surfaceCreated(SurfaceHolder holder) {  
    th.start();  
    Log.e("Himi", "surfaceCreated");  
  }  
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
    Log.e("Himi", "surfaceChanged");  
  }  
  public void surfaceDestroyed(SurfaceHolder holder) {  
    Log.e("Himi", "surfaceDestroyed");  
  }  
  public void draw() {  
    try {  
      canvas = sfh.lockCanvas();  
      if (canvas != null) {  
        canvas.drawColor(Color.WHITE);  
        canvas.drawBitmap(bmp, bmp_x, bmp_y, paint);  
      }  
    } catch (Exception e) {  
      Log.v("Himi", "draw is Error!");  
    } finally {//  1  
      if (canvas != null)//  2  
        sfh.unlockCanvasAndPost(canvas);  
    }  
  }  
  public void run() {  
    while (true) {  
      draw();  
      try {  
        Thread.sleep(100);  
      } catch (Exception ex) {  
      }  
    }  
  }  
} 
  이상 은 우리 가 자주 사용 하 는 사용자 정의 Surface View 이 고 Runnable 인터페이스 의 오래된 프레임 워 크 를 사용 합 니 다.그 중에서 저 는 이러한 구조,생 성,상태 변화,소멸 함수 에 인쇄 를 추가 합 니 다!
       OK,첫 번 째 그림 을 보 겠 습 니 다.(프로그램 이 막 실행 되 었 습 니 다)

        위의 그림 의 왼쪽 부분 은 Dubug 입 니 다.이것 은 우리 가 실행 중인 라인 을 보 여 줍 니 다.이름 은"himi"입 니 다.Thread_one”。
       위의 그림 의 오른쪽 부분 은 LogCat 로그 입 니 다.여러분 은 프로그램 에 처음 들 어 갔 을 때 view 구조 함수 에 먼저 들 어 갔 고 그 다음 에 view 를 만 든 다음 에 view 상태 가 바 뀌 었 습 니 다.OK,이것 은 모두 가 알 고 있 습 니 다!
       다음은 제 가 홈(핸드폰 에 있 는 작은 집)버튼 을 누 르 겠 습 니 다.이때 프로그램 이 백 스테이지 에 있 고 다시 프로그램 에 들 어 가 는 과정 입 니 다!

       위의 그림 에서 볼 수 있 듯 이 우리 의 스 레 드 는 하나 입 니 다.여 기 는 주로 홈 을 클릭 하고 다시 프로그램 에 들 어 가 는 과정 을 관찰 합 니 다.다음 과 같 습 니 다.
       홈 을 누 르 면 view 를 호출 하여 소각 한 다음 프로그램 에 들 어가 면 view 생 성 에 들 어가 고 마지막 으로 view 상태 가 바 뀝 니 다.
       위의 과정 은 쉽게 이해 할 수 있 습 니 다.중요 한 캐릭터 가 등 판 했 습 니 다~Back 버튼!Back 버튼 눌 러 봐.무슨 일이 일 어 났 는 지!

       왼쪽 Debug 란 을 먼저 보고 스 레 드 가 하나 더 생 겼 습 니 다!LogCat 을 보 니 홈 버튼 을 누 르 는 것 보다 구조 함 수 를 한 번 더 호출 한 것 같 습 니 다!
       자,우리 가 테스트 한 프로그램 을 보면 홈 을 누 르 는 것 과 Back 단 추 를 누 르 고 다시 프로그램 에 들 어 갈 때 절차 가 다 르 고 스 레 드 수량 도 달라 집 니 다!
       그러면 여기 서 왜 우리 가 Back 버튼 을 누 르 면 이상 하지 않 고 Home 을 누 르 면 이상 하 다 는 것 을 설명 할 수 있 습 니 다!
       이유:Back 단 추 를 누 르 고 다시 프로그램 에 들 어 갈 때 view 구조 함수 에 먼저 들 어 갔 기 때 문 입 니 다.그러면 여기 서 new 스 레 드 가 나 와 서 시작 한 것 입 니 다!그러면 우 리 는 홈 을 클릭 하면 달라 집 니 다.홈 을 클릭 한 후에 다시 프로그램 에 들 어가 면 구조 함수 에 들 어가 지 않 고 view 에 들 어가 서 이 함 수 를 만 듭 니 다.view 에서 이 함 수 를 만 드 는 과정 에서 우 리 는 스 레 드 를 시작 하 는 작업 이 있 습 니 다.사실은 첫 번 째 시작 프로그램의 스 레 드 가 실행 되 고 있 습 니 다.so~여기 서 이상 합 니 다.스 레 드 가 시작 되 었 다 고 합 니 다!
       어떤 어린이 신발 들 은 우리 가 왜 th=new Thread(this,"himiThread_one”);view 생 성 함수 에 넣 으 면 되 잖 아?!
       네,괜찮아 요!하지만 몇 번 반복 하면 프로그램 에 많은 프로 세 스 가 생 길 것 입 니 다!이 그림

       스 레 드 가 작 동 되 는 이상 을 피 할 수 있 지만 우리 가 원 하 는 결과 가 아 닌 것 이 분명 합 니 다!
       그렇다면 가장 적합 한 해결 방안 을 소개 한다.
       MySurfaceViewAnimation.java 수정:
자바 코드

public class MySurfaceViewAnimation extends SurfaceView implements Callback, Runnable {  
  private Thread th;  
  private SurfaceHolder sfh;  
  private Canvas canvas;  
  private Paint paint;  
  private Bitmap bmp;  
  private int bmp_x, bmp_y;  
  private boolean himi; //  1  
  public MySurfaceViewAnimation(Context context) {  
    super(context);  
    this.setKeepScreenOn(true);  
    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.himi_dream);  
    sfh = this.getHolder();  
    sfh.addCallback(this);  
    paint = new Paint();  
    paint.setAntiAlias(true);  
    this.setLongClickable(true);  
    Log.e("Himi", "MySurfaceViewAnimation");  
  }  
  public void surfaceCreated(SurfaceHolder holder) {  
    himi = true;  
    th = new Thread(this, "himi_Thread_one");//  2  
    th.start();  
    Log.e("Himi", "surfaceCreated");  
  }  
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
    Log.e("Himi", "surfaceChanged");  
  }  
  public void surfaceDestroyed(SurfaceHolder holder) {  
    himi = false;//  3  
    Log.e("Himi", "surfaceDestroyed");  
  }  
  public void draw() {  
    try {  
      canvas = sfh.lockCanvas();  
      if (canvas != null) {  
        canvas.drawColor(Color.WHITE);  
        canvas.drawBitmap(bmp, bmp_x, bmp_y, paint);  
      }  
    } catch (Exception e) {  
      Log.v("Himi", "draw is Error!");  
    } finally {  
      if (canvas != null)  
        sfh.unlockCanvasAndPost(canvas);  
    }  
  }  
  public void run() {  
    while (himi) {//  4  
      draw();  
      try {  
        Thread.sleep(100);  
      } catch (Exception ex) {  
      }  
    }  
  }  
} 
        여기 서 수정 한 부분 은 다음 과 같은 몇 가지 가 있다.
       1.우 리 는 모두 하나의 스 레 드 가 시 작 된 후에 run 방법 이 실행 되 기만 하면 스 레 드 가 소각 된다 는 것 을 알 고 있 습 니 다.그래서 저 는 불 값 의 구성원 변 수 를 추 가 했 습 니 다.himi(비고 1)여 기 는 우리 의 스 레 드 가 사라 지 는 스위치 를 제어 할 수 있 습 니 다!(비고 4)
       2.스 레 드 를 시작 하기 전에 이 불 값 을 ture 로 설정 하여 스 레 드 를 계속 실행 하도록 합 니 다.
       3、view 가 소각 할 때 이 불 값 을 false 로 설정 하여 현재 스 레 드 를 소각 합 니 다!(비고 3)
       OK,이 그림 과 설명 은 충분히 상세 합 니 다.여러분 들 이 나중에 게임 을 진정 으로 개발 할 때 반드시 엄밀 한 코드 를 가지 고 후환 을 남기 지 않 기 를 바 랍 니 다.
       이상 은 Android Surface View 운영 체제 에 대해 상세 하 게 소개 하고 관련 지식 을 계속 보충 하 겠 습 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기