Loading Content using separate thread on Android

In XNA this is what I use for simple content loading:

// Need threading
using System.Threading;

bool loaded = false;

protected override void LoadContent() {
    spriteBatch = new SpriteBatch(GraphicsDevice);

    Thread t = new Thread(LoadAll);
    t.Start();
}

void LoadAll() {
    // Here I load most of my resources like Texture2D, Sounds, Music
    // For example
    background = Content.Load<Texture2D>("background");

    loaded = true;
}

Then in my Update and Draw methods I check for loaded to be true to switch scenes, etc…

Can this work fine as is on different platforms? Meaning iOS, Android, WindowsPhone, Ouya? I’m trying it on Monogame on Android on my Galaxy S4 and for the most part it works but sometimes it crashes.

Want to add that it doesn’t crash all the time but when it does I get this error:

Thread finished: #4
[Surface] dequeueBuffer_DEPRECATED: Fence::wait returned an error: -4
[Error in swap buffers] OpenTK.Platform.Android.EglException: EglSwapBuffers failed with error 12299 (0x300b)
[Error in swap buffers] at OpenTK.Platform.Android.AndroidGraphicsContext.Swap () [0x00090] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/163212a9/source/monodroid/src/OpenGLES/Android/AndroidGraphicsContext.cs:146
[Error in swap buffers] at OpenTK.Platform.Android.AndroidGameView.SwapBuffers () [0x0001f] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/163212a9/source/monodroid/src/OpenGLES/Android/AndroidGameView.cs:228
[Error in swap buffers] at Microsoft.Xna.Framework.AndroidGamePlatform.Present () [0x00000] in :0
[IMGSRV] :0: WSEGL_GetDrawableParameters: Native buffer became NULL
[IMGSRV] :0: KEGLGetDrawableParameters: Native window is invalid
[libEGL] eglMakeCurrent:796 error 300b (EGL_BAD_NATIVE_WINDOW)

Hi nanexcool,

no idea about the crash, I suppose that it’s a problem with the thread not being an UI thread. I had similar problems in WP8 some time ago.

Now I use an “enumerator loader”. Each tick in the draw loop I load “one knot” of the enumerator. It’s obviously not a solution for your problem, but if you don’t need a fluid animation while loading (i.e. you only use a progress bar) and you can change the loader function into an enumerator, it works quite well and it’s compatible across all platforms because you’re loading in the Update/Draw thread.

That sounds like an elegant solution.

Maybe I’m overthinking this, but do you just load one asset then yield each time or do you have a stopwatch that yields after x amount of milliseconds have passed?

Hi!

I use the first method but I do that in blocks (i.e. load all textures, load audio, precalculate things) instead of doing it asset by asset (I don’t need much granularity in the loading bar, just enough to make the user know the game is not frozen, which usually happens in android)

If there’s some functions with heavy stuff (i.e. loadModels) I do another IEnumerable function and access each item of the enumerable yielding after every iteration.

If I had macros in C# I’d probably do it the second way but I haven’t found the way to do that in C# (yet :slight_smile: ) so I prefer cleaner code to fluidity