Structuring libGDX Asset Loading: One AssetManager, Screen-Scoped Lifetimes, No Leaks
libGDX's AssetManager solves loading-screen freezes, Android context-loss crashes, and silent texture leaks when loads and unloads are scoped to screens and reference counts are balanced.
11 Aug 2026, 16:22 UTC

AssetManager centralizes asset loading and lifecycle management for textures, atlases, sounds, and custom types through pluggable AssetLoader implementations. Calling load() queues assets; finishLoading() blocks until done, while update() loads incrementally so a loading screen can render a progress bar using getProgress(). The manager uses reference counting: get() increments usage and unload() decrements it, so assets are only disposed when no one references them. Mismatched load/unload calls are a common source of silent memory leaks.
On Android, OpenGL context loss historically caused 'crashed on resume' bugs. AssetManager tracks what it loaded and can reload managed assets after context loss, mitigating this class of failures. Texture atlases (TextureAtlas) loaded through AssetManager reduce draw calls by batching sprites from a single texture, a key performance decision for 2D games on mobile GPUs.
Screen-scoped loading pattern
Keep one AssetManager in your Game subclass and pass it to screens. Load a screen's assets on entry, show progress with update() and getProgress(), and unload when the screen exits. This keeps the memory footprint bounded on low-end devices. Never mix new Texture() with managed assets—manual textures bypass reference counting and context-loss recovery.
public class GameScreen extends ScreenAdapter { private final AssetManager assets; private boolean ready; public GameScreen(AssetManager assets) { this.assets = assets; assets.load("game/atlas/game.atlas", TextureAtlas.class); assets.load("game/sfx/jump.ogg", Sound.class); } @Override public void render(float delta) { if (!ready) { if (assets.update()) { ready = true; } drawLoadingBar(assets.getProgress()); return; } TextureAtlas atlas = assets.get("game/atlas/game.atlas", TextureAtlas.class); // normal rendering } @Override public void hide() { assets.unload("game/atlas/game.atlas"); assets.unload("game/sfx/jump.ogg"); }}0 replies
A thoughtful contribution can make all the difference. Be the first to share one.