koral--/android-gif-drawable · error · IllegalStateException
LibraryLoader not initialized. Call…
Error message
LibraryLoader not initialized. Call LibraryLoader.initialize() before using library classes.
What it means
LibraryLoader needs an application Context to load the native libpl_droidsonroids_gif.so. When LibraryLoader.initialize(context) was never called, it falls back to reflection into android.app.ActivityThread.currentApplication() to grab the context; if that reflection fails (or returns null on non-main threads before the app is up), it wraps the failure in this IllegalStateException at getContext(), invoked from loadLibrary() when any GIF class first touches native code.
Solutions
- Call LibraryLoader.initialize(context) with the application context early, e.g. in Application.onCreate, before creating any GIF views/drawables
- In tests, initialize with the instrumentation/target context: LibraryLoader.initialize(InstrumentationRegistry.getInstrumentation().targetContext.applicationContext)
- Check the wrapped cause (the IllegalStateException's cause) for the actual reflection failure (ClassNotFoundException, InvocationTargetException, null return) and fix that environment issue
- Ensure GIF-loading code does not run in processes/threads where no Application context exists; defer it or supply a context explicitly
Example fix
// before
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
val gif = GifDrawable(assets, "anim.gif") // throws IllegalStateException
}
}
// after
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
LibraryLoader.initialize(this)
val gif = GifDrawable(assets, "anim.gif")
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Kotlin: ensure initialization before any GIF API use
fun ensureGifLibrary(context: Context) {
LibraryLoader.initialize(context.applicationContext)
} Try / catch
// Kotlin
try {
val gif = GifDrawable(assets, "anim.gif")
} catch (e: IllegalStateException) {
if (e.message?.contains("LibraryLoader not initialized") == true) {
LibraryLoader.initialize(applicationContext)
// retry the operation
} else throw e
} Prevention
- Always call LibraryLoader.initialize(applicationContext) in Application.onCreate
- In instrumented tests initialize with the target context before touching GIF classes
- Do not use GIF views/drawables in code paths without an available Application context (e.g. plain JVM unit tests)
When it happens
Trigger: Using GifImageView/GifTextView/GifDrawable/GifTextureView before calling LibraryLoader.initialize(context), e.g. in unit tests, instrumented tests, content providers, Application.onCreate ordering issues, background threads created before the app context is available, or environments where ActivityThread reflection fails (non-standard runtimes, Robolectric).
Common situations: Developers hit this in JVM unit tests instantiating GifDrawable without Robolectric providing a context, in multi-process apps where a secondary process runs GIF code before initialization, and in library consumers embedding the gif library in SDKs that never call initialize().
Related errors
- Sample size out of range <1, 65535>
- Bitmap is recycled
- Bitmap ia too small, size must be greater than or equal to…
- Only Config.ARGB_8888 is supported. Current bitmap config
- Position is not positive
AI-assisted analysis of koral--/android-gif-drawable@26ff795f78 (2026-09-10).
Data as JSON: /api/errors/fbb4e2a789e4b443.
Report an issue: GitHub.
Appendix: source
Thrown at android-gif-drawable/src/main/java/pl/droidsonroids/gif/LibraryLoader.java:41
* Initializes loader with given `Context`. Subsequent calls should have no effect since application Context is retrieved.
* Libraries will not be loaded immediately but only when needed.
*
* @param context any Context except null
*/
public static void initialize(@NonNull final Context context) {
sAppContext = context.getApplicationContext();
}
private static Context getContext() {
if (sAppContext == null) {
try {
@SuppressLint("PrivateApi")
final Class<?> activityThread = Class.forName("android.app.ActivityThread");
@SuppressLint("DiscouragedPrivateApi")
final Method currentApplicationMethod = activityThread.getDeclaredMethod("currentApplication");
sAppContext = (Context) currentApplicationMethod.invoke(null);
} catch (Exception e) {
throw new IllegalStateException("LibraryLoader not initialized. Call LibraryLoader.initialize() before using library classes.", e);
}
}
return sAppContext;
}
static void loadLibrary() {
try {
System.loadLibrary(BASE_LIBRARY_NAME);
} catch (final UnsatisfiedLinkError e) {
ReLinker.loadLibrary(getContext(), BASE_LIBRARY_NAME);
}
}
}
View on GitHub (pinned to 26ff795f78)