LockCanvas () возвращает различные холсты

Пытается нарисовать что-то каждый мс на одном холсте. Я имею в виду только добавление деталей к холсту, а не перерисовку всего кадра. Таким образом, этот код дает мне три разных полотна. В-третьих, сначала сначала. Зачем?

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

Если это андроидная тройная буферизация – как отключить ее или что-то сделать с ней? Android 4.2.1

Solutions Collecting From Web of "LockCanvas () возвращает различные холсты"

1) Я бы рекомендовал не называть логическое поле «run» в реализации Runnable (в котором метод возвращает void). Даже если проблемы не выходят из конфликта, это запутывает. Может быть, «работает», или что-то (что-то), будет иметь больше смысла – легче отлаживать.

2) Не используйте Object.wait при многопоточности. Это не всегда (как правило, не будет) действовать так, как вы могли бы ожидать.

3) Скорее всего, вы получаете несколько экземпляров вашего члена Canvas, потому что где-то (возможно, в каркасе Android или, может быть, в вашем коде … трудно сказать), «новый Canvas (args)» вызывается, в то время как вы верите в Ваш единственный экземпляр Canvas выходит из другого потока. Хотя у вас есть только одна ссылка, может быть создано несколько экземпляров.

4) Я бы не рекомендовал использовать синхронизированный (независимо), если вы не уверены, что вам нужно это сделать.

5) Повесьте там. Эта проблема очень запутанна – я проработал ее прошлой весной, и это было нелегко или весело.

Надеюсь, что любое из вышеперечисленных помогает в некотором роде.

-Brandon

Если вам нравится сохранять предыдущий розыгрыш, вы должны нарисовать их на экранном холсте и нарисовать их на холсте, который вы получили из холста блокировки.

Пуэд-код, чтобы проиллюстрировать идею:

 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) 

Это должно выполнить вашу задачу. Правильно?

Затем, немного под капотом:

Да, вид android (поверхность IS A view) имеет многократные буферы: один используется приложениями для рисования, а один используется системой для рендеринга, а иногда есть третий, если приложение не может завершить рисование своевременно. Невозможно отключить его, и вы не захотите. И именно по этой причине вы получаете разный холст при блокировке, как вы уже заметили.