didi/DoKit · error · NullPointerException
reflect failed.
Error message
reflect failed.
What it means
Utils.getApp() returns the cached Application (sApp), and when the cache is empty it obtains it via UtilsBridge.getApplicationByReflect(). If reflection cannot find the Application (returns null), a NullPointerException("reflect failed.") is thrown. Reflection is the fallback path used mainly in processes other than the main process, where the ContentProvider-based initialization (UtilsFileProvider) does not run.
Source
Thrown at Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/Utils.java:72
return;
}
if (sApp.equals(app)) return;
UtilsBridge.unInit(sApp);
sApp = app;
UtilsBridge.init(sApp);
}
/**
* Return the Application object.
* <p>Main process get app by UtilsFileProvider,
* and other process get app by reflect.</p>
*
* @return the Application object
*/
public static Application getApp() {
if (sApp != null) return sApp;
init(UtilsBridge.getApplicationByReflect());
if (sApp == null) throw new NullPointerException("reflect failed.");
Log.i("Utils", UtilsBridge.getCurrentProcessName() + " reflect app success.");
return sApp;
}
///////////////////////////////////////////////////////////////////////////
// interface
///////////////////////////////////////////////////////////////////////////
public abstract static class Task<Result> extends ThreadUtils.SimpleTask<Result> {
private Consumer<Result> mConsumer;
public Task(final Consumer<Result> consumer) {
mConsumer = consumer;
}
@Override
public void onSuccess(Result result) {View on GitHub (pinned to 626827cddb)
Solutions
- Call Utils.init(getApplicationContext()) in Application.attachBaseContext() so sApp is always populated before any Utils call.
- For non-main processes, initialize Utils explicitly in that process (e.g. in the service's onCreate) instead of relying on reflection.
- Check UtilsBridge.getApplicationByReflect() chain (ActivityThread -> mInitialApplication) works on the target device/ROM; avoid calling getApp() during very early process startup.
Example fix
// before
Context ctx = Utils.getApp(); // in :push process -> NPE reflect failed.
// after
public class MyApplication extends Application {
@Override protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Utils.init(base); // every process, including non-main
}
}
Context ctx = Utils.getApp(); Defensive patterns
Strategy: validation
Validate before calling
if (Utils.getApp4Activity() == null) { /* fall back to passed Context */ } Try / catch
try { app = Utils.getApp(); } catch (NullPointerException e) { app = yourContext.getApplicationContext(); } // last-resort only; prefer Utils.init in Application Prevention
- Always call Utils.init(application) in Application.attachBaseContext so every process seeds sApp.
- In non-main processes, prefer passing a Context explicitly instead of relying on reflection.
When it happens
Trigger: Calling Utils.getApp() in a non-main process (push service, web process, :remote service) before or without Utils.init(app); calling it in a process where the ActivityThread.currentActivityThread().getApplication() reflection chain fails; proguard/R8 stripping or OEM ROM differences breaking the reflection lookup.
Common situations: Library used inside a multiprocess app where UtilsFileProvider only initializes in the main process; an app class that never calls Utils.init(this) in attachBaseContext; aggressive obfuscation removing activity-thread internals on some devices.
Related errors
- buildAndInstall() should only be called once.
- Cannot set the LeakDirectoryProvider after it has already be
- mDb == null || mDb.mockApiDao()
- Singleton instance already exists.
- Context must not be null.
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/2541234339d6068d.
Report an issue: GitHub.