0

Summary

I'm trying to reliably remove a view from my layout, from my GL Rendering thread.

Details

I've got a splash screen which is added to my main layout, so my views are in this order:

  • GLSurfaceView
  • Splashscreen (which is a simple Android View)

All my objects and anything that can be loaded in the background is loaded from an AsyncTask, then, my GL Textures are loaded on the GL Thread (as is required), I'm then removing the Splashscreen from my layout to reveal my app's main menu screen.

90% of the time it works perfectly, (load time on my device is approx 3.5 seconds), however, occasionally, it appears to either never remove the view, or can take up to 8 seconds.

This is my current implementation

In my Activity class, I have the following method setup

public void dismissSplashScreen(){

        removeSplash = new Runnable(){

        public void run(){

            //Is splashscreen currently visible?
            if (splash.isShown()){

                //Remove the splashscreen
                layout.removeView(splash);

                //Recycle splash screen as it's no longer required
                recycle();                  
            }

        }
    };

        //Remove it
        handler.post(removeSplash);

}

And then in my GLRenderer's onSurfaceCreated method, I have this:

public void onSurfaceChanged(GL10 gl, int deviceWidth, int deviceHeight) {

    GLES20.glViewport(offsetX, offsetY, width, height);

    Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

    loadGLTextures();

    //Everything is done! Dismiss the splash to reveal main menu
    activity.dismissSplashScreen();

}

I also attempted to use runOnUIThread, but the results were the same, if not worse. Is my implementation correct here? What things can I check and is there a simpler way to remove this view from my layout once everything is done? (I can't dismiss it from the activity class directly as I have to wait for the GL textures to load on the GL thread).

genpfault
  • 51,148
  • 11
  • 85
  • 139
Zippy
  • 3,826
  • 5
  • 43
  • 96

1 Answers1

0

Sorted.

The reason was because I am calling activity.dismissSplashScreen from onSurfaceChanged and onSurfaceChanged is being called multiple times (a common problem I gather and one which I've not been able to get to the bottom of yet).

So what I think was happening, was it was posting my runnable to the queue and then posting another before the first one had either started or completed, sometimes a third time.

So everything was getting a bit confused.

I simply added a boolean flag to guarantee that the runnable was posted only once like so:

if (!splashIsGone){
        activity.dismissSplash();
        splashIsGone = true;
    }
Zippy
  • 3,826
  • 5
  • 43
  • 96