lockCanvas () retourne différentes canvass

Essayer de dessiner quelque chose chaque ms sur une seule canvas. Je veux dire seulement append des détails à la canvas, et non pas redessiner tous les frameworks. Donc, ce code me donne trois canvass différentes. Troisièmement, puis encore une fois. Pourquoi?

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) {} } } } } 

S’il s’agit d’un sortingple tampon Android – comment l’éteindre ou en faire quelque chose? Android 4.2.1

  1. Je déconseille de nommer un champ booléen, “run” dans une implémentation Runnable (dans laquelle la méthode retourne void). Même si les problèmes ne surgissent pas du conflit, c’est déroutant. Peut-être que “courir”, ou quelque chose (n’importe quoi), aurait plus de sens – plus facile à déboguer.

  2. N’utilisez pas Object.wait lorsque vous utilisez plusieurs threads. Il n’agira pas toujours (généralement, pas) comme vous pouvez vous attendre.

  3. Vous obtiendrez probablement plusieurs instances de votre membre Canvas car quelque part (peut-être dans le cadre d’Android ou dans votre code… difficile à dire), «nouveau Canvas (args)» est appelé alors que vous croyez être votre seule l’instance Canvas est sortie sur un autre thread. Bien que vous n’ayez qu’une seule référence, vous pouvez créer plusieurs instances.

  4. Je ne recommanderais pas d’utiliser synchronisé (peu importe) à moins que vous ne soyez sûr de le faire.

  5. Accrochez-vous. Ce problème est très déroutant. J’y ai travaillé au spring dernier et ce n’était ni facile ni amusant.

J’espère que tout ce qui précède aide d’une certaine manière.

-Brandon

Si vous souhaitez conserver votre dessin précédent, vous devez les dessiner sur une canvas hors écran et les dessiner sur la canvas obtenue à partir de la zone de locking.

Le code puesd pour illustrer l’idée:

 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) 

Cela devrait faire votre travail. Droite?

Ensuite, un peu sous le capot

Oui, la vue Android (vue de surface IS A) comporte plusieurs mémoires tampons: l’une est utilisée par les applications pour le dessin et l’autre par le système pour le rendu. Pas moyen de l’éteindre et vous ne voudrez pas. Et c’est la raison pour laquelle vous obtenez une canvas différente lorsque vous verrouillez, comme vous l’avez déjà observé.