{"record":{"id":"fbb4e2a789e4b443","repo":"koral--/android-gif-drawable","slug":"libraryloader-not-initialized-call-libraryloader","errorCode":null,"errorMessage":"LibraryLoader not initialized. Call LibraryLoader.initialize() before using library classes.","messagePattern":"LibraryLoader not initialized\\. Call LibraryLoader\\.initialize\\(\\) before using library classes\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"android-gif-drawable/src/main/java/pl/droidsonroids/gif/LibraryLoader.java","lineNumber":41,"sourceCode":"\t * Initializes loader with given `Context`. Subsequent calls should have no effect since application Context is retrieved.\n\t * Libraries will not be loaded immediately but only when needed.\n\t *\n\t * @param context any Context except null\n\t */\n\tpublic static void initialize(@NonNull final Context context) {\n\t\tsAppContext = context.getApplicationContext();\n\t}\n\n\tprivate static Context getContext() {\n\t\tif (sAppContext == null) {\n\t\t\ttry {\n\t\t\t\t@SuppressLint(\"PrivateApi\")\n\t\t\t\tfinal Class<?> activityThread = Class.forName(\"android.app.ActivityThread\");\n\t\t\t\t@SuppressLint(\"DiscouragedPrivateApi\")\n\t\t\t\tfinal Method currentApplicationMethod = activityThread.getDeclaredMethod(\"currentApplication\");\n\t\t\t\tsAppContext = (Context) currentApplicationMethod.invoke(null);\n\t\t\t} catch (Exception e) {\n\t\t\t\tthrow new IllegalStateException(\"LibraryLoader not initialized. Call LibraryLoader.initialize() before using library classes.\", e);\n\t\t\t}\n\t\t}\n\t\treturn sAppContext;\n\t}\n\n\tstatic void loadLibrary() {\n\t\ttry {\n\t\t\tSystem.loadLibrary(BASE_LIBRARY_NAME);\n\t\t} catch (final UnsatisfiedLinkError e) {\n\t\t\tReLinker.loadLibrary(getContext(), BASE_LIBRARY_NAME);\n\t\t}\n\t}\n}\n","sourceCodeStart":23,"sourceCodeEnd":55,"githubUrl":"https://github.com/koral--/android-gif-drawable/blob/26ff795f78b7fe8bbaf375a947b2bda95fc58e3d/android-gif-drawable/src/main/java/pl/droidsonroids/gif/LibraryLoader.java#L23-L55","documentation":"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.","triggerScenarios":"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).","commonSituations":"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().","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"],"exampleFix":"// before\nclass MyApplication : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        val gif = GifDrawable(assets, \"anim.gif\") // throws IllegalStateException\n    }\n}\n\n// after\nclass MyApplication : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        LibraryLoader.initialize(this)\n        val gif = GifDrawable(assets, \"anim.gif\")\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Kotlin: ensure initialization before any GIF API use\nfun ensureGifLibrary(context: Context) {\n    LibraryLoader.initialize(context.applicationContext)\n}","typeGuard":null,"tryCatchPattern":"// Kotlin\ntry {\n    val gif = GifDrawable(assets, \"anim.gif\")\n} catch (e: IllegalStateException) {\n    if (e.message?.contains(\"LibraryLoader not initialized\") == true) {\n        LibraryLoader.initialize(applicationContext)\n        // retry the operation\n    } else throw e\n}","preventionTips":["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)"],"tags":["android","library-loader","initialization","native-library","illegal-state"],"backgroundTag":"library-not-initialized","analyzedSha":"26ff795f78b7fe8bbaf375a947b2bda95fc58e3d","analyzedAt":"2026-09-10T14:37:11.595Z","contentChangedAt":"2026-09-10T14:37:11.595Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}