2013-01-17 15 views
11

Próbuje narysować coś co każde ms na jednym płótnie. Mam na myśli tylko dodawanie szczegółów do płótna, a nie przerysowywanie go w każdej klatce. Ten kod daje mi trzy różne płótna. Po trzecie, potem znowu pierwszy. Czemu?LockCanvas() zwraca różne płótna

public void run() { 
    this.run = true; 
    Canvas canvas = null; 
    while (run) { 
     try { 
      canvas = this.surfaceHolder.lockCanvas(); 
      synchronized (this.surfaceHolder) { 
       Thread.sleep(delay); 
       draw(new Img(canvas, size)); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } finally { 
      if (canvas != null) { 
      this.surfaceHolder.unlockCanvasAndPost(canvas); 
      } 
     } 
     synchronized (this) { 
      if (wait) { 
       try { 
        wait(); 
       } catch (Exception e) {} 
      } 
     } 
    } 
} 

Jeśli jest to potrójne buforowanie na Androida - jak je wyłączyć lub coś z nim zrobić? Android 4.2.1

+1

Myślę, że obecny Android implementuje potrójne buforowanie. To może wejść tutaj w grę? – DThought

+0

Jaką wersję Androida itp? –

+1

Android 4.2.1 u – user1748526

Odpowiedz

1
  1. Polecam przeciwko nazywania logiczną pole, "run" w Runnable realizacji (w których metoda zwraca void). Nawet jeśli problemy nie wypłyną z konfliktu, jest to mylące. Może "bieganie" lub coś (cokolwiek) będzie miało więcej sensu - łatwiejsze do debugowania.

  2. Nie używaj Object.wait, gdy jesteś wielowątkowy. Nie zawsze (ogólnie rzecz biorąc) nie będzie działać tak, jak można się spodziewać.

  3. Najprawdopodobniej otrzymujesz wiele wystąpień elementu Canvas, ponieważ gdzieś (być może w systemie Android, lub w kodzie ... trudno powiedzieć), "new Canvas (args)" jest wywoływane, podczas gdy Wierzysz, że jesteś jedyną instancją Canvas znajdującą się w innym wątku. Chociaż masz tylko jedno odwołanie, możesz utworzyć więcej niż jedną instancję.

  4. Nie polecam używania synchronizacji (cokolwiek), chyba że masz pewność, że musisz to zrobić.

  5. Trzymaj się. Ten problem jest bardzo mylący - przepracowałem to przez ostatnią wiosnę i nie było to łatwe ani przyjemne.

Nadzieję, że którykolwiek z powyższych pomaga w pewien sposób.

-Brandon

1

Jeśli chcesz zachować poprzednią remisu należy zwrócić je w płótna off-screen i wyciągnąć je na płótnie dostałeś od zamka płótnie.

puesd kodu do zilustrowania pomysł:

Bitmap offScreenBitmap = Bitmap.createBitmap(100,200,Bitmap.ARGB_8888); 
Canvas offScreenCanvas = new Canvas(offScreenBitmap); 

onScreenCanvas = this.surfaceHolder.lockCanvas(); 

//always draw to te offScreenCanvas 
offScreenCanvas.drawXxxx 

//copy the data to on-screen canvas you got from the lock 
onScreenCanvas.drawBitmap(offScreenBitmap); 

unlockAndPost(onScreenCanvas) 

To powinno uzyskać zadanie wykonane. Dobrze?

Potem, trochę pod rzeczy Hood:

Tak, android view (powierzchnia jest rzutem) ma pomnożyć bufory: jeden jest używane przez aplikacje do rysowania i jest wykorzystywany przez układ do renderowania i czasami jest trzecia, jeśli aplikacja nie może zakończyć sporządzania w odpowiednim czasie. Nie ma sposobu, aby to wyłączyć i nie będziesz chciał. I to jest powód, dla którego uzyskujesz inne płótno, gdy blokujesz, jak już zauważyłeś.

Powiązane problemy