2012-09-07 5 views
3

일반적인 Android 그래픽 흐름에 따라 약간의 문제가 있습니다. 많은 예가 있지만 내 것이 효과가없는 것처럼 보입니다. 내 주요 활동에서 나는 다음과 같이한다.Android SurfaceView, OnDraw가 호출되었지만 invalidate()없이 디스플레이가 업데이트되지 않음

super.onCreate(savedInstanceState);       
setContentView(R.layout.activity_main); 

내 리소스 파일에는 SurfaceView를 대체하는 3 개의 사용자 정의 클래스가있다.

super(context, attrs); 
getHolder().addCallback(this); 
this.thread = new MyThread(getHolder(),this); 

내 스레드의 실행 방법에있어서 나는이 (많은 예에서 해제 내가 본)을 수행합니다 :이 스레드가 시작

Canvas c; 
try { 
    c = surfaceHolder.lockCanvas(null); 
    synchronized (surfaceHolder) { 
     panel.onDraw(c); 
    } 
} finally { 
    if (c != null) { 
    surfaceHolder.unlockCanvasAndPost(c); 
} 

이 표면보기 내 생성자에서이 같은 뭔가를 내 SurfaceView의 'surfaceCreated'이벤트에서.

public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    <some drawing stuff here using canvas> 
} 

내가 실행하면, 스레드가 실제로 실행 않으며, 내가 된 onDraw가 (내가 거기에서 인쇄 명령을 로그 넣어)라는지고 있음을 볼 수 있지만 내 그래픽으로 업데이트되지 않습니다 : 된 onDraw에서 나는이 작업을 수행 예상했다.

E/AndroidRuntime(748): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

을 난 내가 할 필요가 없습니다 본 적이 예제를 따라 실현 : 나는 this.invalidate()를 호출하면 나는이와 충돌 할 때까지 예상대로, 그러나, 그래픽은 시대의 소수를 업데이트 할 OnDraw에서 invalidate를 호출하지만, onDraw의 코드가 유효한지 확인하기 위해 수행했습니다. 따라서 invalidate()가 없으면 onDraw 이벤트가 호출되고 내 코드가 그래픽을 제대로 업데이트해야하지만 화면이 업데이트되지 않는 것으로 보입니다. 주 활동이 실제로 아이들을 다시 칠할 필요가 있다고 결정하는 방법에 뭔가 빠져 있습니다.

모든 아이디어는 크게 감사하겠습니다. 몇 가지 작업 데모에서 물건을 복사하려고했지만 잠시 머물렀다. 감사합니다

+0

SurfaceViews에는 표면 파트와 뷰 파트의 두 부분이 있습니다. 후자는 UI View 계층 구조의 일부이며, UI 스레드 (onDraw()를 통해)에서만 가져올 수 있지만 View 시스템에서 수행 할 작업이 있다고 판단 될 경우 (예 : 무효화 후) 호출됩니다. 전자는 완전히 독립적 인 레이어이며 임의의 스레드에서 언제든지 업데이트 할 수 있습니다. 두 가지를 모두 사용하고 싶습니까? – fadden

답변

0

당신이 run()에서하는 것들은 당신이하는 일을합니다. 그리기 프로세스를 반복해야합니다.

한 가지 방법은 while 루프

while(true){ 
    try { 
     c = surfaceHolder.lockCanvas(null); 
     synchronized (surfaceHolder) { 
      panel.onDraw(c); 
     } 
    } finally { 
     if (c != null) { 
     surfaceHolder.unlockCanvasAndPost(c); 
    } 
} 
+0

죄송합니다. 내 작은 코드 스 니펫이 완료되지 않았습니다.나는 while 루프를 가지고 있고 스레드가 그 루프에서 돌아가고 있음을 볼 수있다. 문제의 관련성이없는 일부 코드를 잘라내려고했지만 어쨌든 고맙겠습니다. –

0

이미 같은 문제를 겪고 안에 모든 것을 넣어 수 있습니다. 어떤 해결책도 찾을 수 없기 때문에 일종의 해결 방법을 만들었습니다. Bitmap을 버퍼로 만들고 해당 비트 맵을 그립니다. 그리기 후 전체 비트 맵을 뷰 자체에 그립니다.

Canvas bmpCanvas; 
Bitmap bmp; 

을 그리고 당신의 onDraw()에서 사용하는 - 방법을 보여처럼 : 뷰 클래스에서 이러한 변수를 선언

@Override 
protected void onDraw(Canvas canvas) { 

    if(bmp == null || bmpCanvas == null) { 

     bmp = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
     bmpCanvas = new Canvas(bmp); 
    } 

    //do drawing-stuff here 

    canvas.drawBitmap(bmp, 0, 0, p); //where p is a Paint-Object. 
} 

를 이제보기를 업데이트하기 위해 /이 방법의 사용을 호출하거나 invalidate 또는 postInvalidate()invalidate 같은 스레드에서 또는 다른 스레드에서 메서드를 호출하는지 여부에 따라 다릅니다.

관련 문제