@@ -212,6 +212,8 @@ public enum RenderMode {
212212 * that is being used.
213213 */
214214 private static class BufferedCanvas {
215+ private int lastHeight = 0 ;
216+ private int lastWidth = 0 ;
215217 private volatile Bitmap bgBuffer ; // all drawing is done on this buffer.
216218 private volatile Bitmap fgBuffer ;
217219 private Canvas canvas = new Canvas ();
@@ -226,11 +228,21 @@ public synchronized void swap() {
226228 fgBuffer = tmp ;
227229 }
228230
231+ /**
232+ * Used when rendering in background mode and a view is attached
233+ * but not resized, so that rendering buffers will be reinitialized.
234+ */
235+ public void resizeToLast () {
236+ resize (lastHeight , lastWidth );
237+ }
238+
229239 public synchronized void resize (int h , int w ) {
230240 if (w <= 0 || h <= 0 ) {
231241 bgBuffer = null ;
232242 fgBuffer = null ;
233243 } else {
244+ lastHeight = h ;
245+ lastWidth = w ;
234246 try {
235247 bgBuffer = Bitmap .createBitmap (w , h , Bitmap .Config .ARGB_8888 );
236248 fgBuffer = Bitmap .createBitmap (w , h , Bitmap .Config .ARGB_8888 );
@@ -408,35 +420,43 @@ protected final void init(Context context, AttributeSet attrs, int defStyle) {
408420
409421 layoutManager .onPostInit ();
410422 if (renderMode == RenderMode .USE_BACKGROUND_THREAD ) {
411- renderThread = new Thread (new Runnable () {
412- @ Override
413- public void run () {
414-
415- keepRunning = true ;
416- while (keepRunning ) {
417- isIdle = false ;
418- synchronized (pingPong ) {
419- Canvas c = pingPong .getCanvas ();
420- renderOnCanvas (c );
421- pingPong .swap ();
422- }
423- synchronized (renderSync ) {
424- postInvalidate ();
425- // prevent this thread from becoming an orphan
426- // after the view is destroyed
427- if (keepRunning ) {
428- try {
429- renderSync .wait ();
430- } catch (InterruptedException e ) {
431- keepRunning = false ;
432- }
433- }
423+ startBackgroundRendering ();
424+ }
425+ }
426+
427+ protected void startBackgroundRendering () {
428+ if (renderThread != null ) {
429+ return ;
430+ }
431+
432+ renderThread = new Thread (() -> {
433+ System .out .println ("Thread started with id " + this .hashCode ());
434+
435+ keepRunning = true ;
436+ while (keepRunning ) {
437+ isIdle = false ;
438+ synchronized (pingPong ) {
439+ Canvas c = pingPong .getCanvas ();
440+ renderOnCanvas (c );
441+ pingPong .swap ();
442+ }
443+ synchronized (renderSync ) {
444+ postInvalidate ();
445+ // prevent this thread from becoming an orphan
446+ // after the view is destroyed
447+ if (keepRunning ) {
448+ try {
449+ renderSync .wait ();
450+ } catch (InterruptedException e ) {
451+ keepRunning = false ;
434452 }
435453 }
436- pingPong .recycle ();
437454 }
438- }, "Androidplot renderThread" );
439- }
455+ }
456+ System .out .println ("Thread exited with id " + this .hashCode ());
457+ renderThread = null ;
458+ pingPong .recycle ();
459+ }, "Androidplot renderThread" );
440460 }
441461
442462 /**
@@ -745,11 +765,12 @@ public void redraw() {
745765 // only enter synchronized block if the call is expected to block OR
746766 // if the render thread is idle, so we know that we won't have to wait to
747767 // obtain a lock.
748- if (isIdle ) {
768+ if (renderThread != null && isIdle ) {
749769 synchronized (renderSync ) {
750770 renderSync .notify ();
751771 }
752772 }
773+
753774 } else if (renderMode == RenderMode .USE_MAIN_THREAD ) {
754775
755776 // are we on the UI thread?
@@ -778,6 +799,17 @@ protected void onDetachedFromWindow() {
778799 }
779800 }
780801
802+ @ Override
803+ protected void onAttachedToWindow () {
804+ super .onAttachedToWindow ();
805+
806+ // necessary to support rendering in recyclerview etc.
807+ if (renderMode == RenderMode .USE_BACKGROUND_THREAD && renderThread == null ) {
808+ pingPong .resizeToLast ();
809+ startBackgroundRendering ();
810+ renderThread .start ();
811+ }
812+ }
781813
782814 @ Override
783815 protected synchronized void onSizeChanged (int w , int h , int oldw , int oldh ) {
0 commit comments