public void setAndConsumeBitmapRegionLoader(final BitmapRegionLoader bitmapRegionLoader) { if (!mSurfaceCreated) { mQueuedNextBitmapRegionLoader = bitmapRegionLoader; return; } if (mCrossfadeAnimator.isRunning()) { if (mQueuedNextBitmapRegionLoader != null) { mQueuedNextBitmapRegionLoader.destroy(); } mQueuedNextBitmapRegionLoader = bitmapRegionLoader; return; } mNextGLPictureSet.load(bitmapRegionLoader); mCrossfadeAnimator .from(0) .to(1) .withDuration(CROSSFADE_ANIMATION_DURATION) .withEndListener( new Runnable() { @Override public void run() { // swap current and next picturesets final GLPictureSet oldGLPictureSet = mCurrentGLPictureSet; mCurrentGLPictureSet = mNextGLPictureSet; mNextGLPictureSet = new GLPictureSet(oldGLPictureSet.mId); mCallbacks.requestRender(); oldGLPictureSet.destroyPictures(); System.gc(); if (mQueuedNextBitmapRegionLoader != null) { BitmapRegionLoader queuedNextBitmapRegionLoader = mQueuedNextBitmapRegionLoader; mQueuedNextBitmapRegionLoader = null; setAndConsumeBitmapRegionLoader(queuedNextBitmapRegionLoader); } } }) .start(); mCallbacks.requestRender(); }