{"record":{"id":"2541234339d6068d","repo":"didi/DoKit","slug":"reflect-failed","errorCode":null,"errorMessage":"reflect failed.","messagePattern":"reflect failed\\.","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/Utils.java","lineNumber":72,"sourceCode":"            return;\n        }\n        if (sApp.equals(app)) return;\n        UtilsBridge.unInit(sApp);\n        sApp = app;\n        UtilsBridge.init(sApp);\n    }\n\n    /**\n     * Return the Application object.\n     * <p>Main process get app by UtilsFileProvider,\n     * and other process get app by reflect.</p>\n     *\n     * @return the Application object\n     */\n    public static Application getApp() {\n        if (sApp != null) return sApp;\n        init(UtilsBridge.getApplicationByReflect());\n        if (sApp == null) throw new NullPointerException(\"reflect failed.\");\n        Log.i(\"Utils\", UtilsBridge.getCurrentProcessName() + \" reflect app success.\");\n        return sApp;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // interface\n    ///////////////////////////////////////////////////////////////////////////\n\n    public abstract static class Task<Result> extends ThreadUtils.SimpleTask<Result> {\n\n        private Consumer<Result> mConsumer;\n\n        public Task(final Consumer<Result> consumer) {\n            mConsumer = consumer;\n        }\n\n        @Override\n        public void onSuccess(Result result) {","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/Utils.java#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nContext ctx = Utils.getApp(); // in :push process -> NPE reflect failed.\n\n// after\npublic class MyApplication extends Application {\n  @Override protected void attachBaseContext(Context base) {\n    super.attachBaseContext(base);\n    Utils.init(base); // every process, including non-main\n  }\n}\nContext ctx = Utils.getApp();","handlingStrategy":"validation","validationCode":"if (Utils.getApp4Activity() == null) { /* fall back to passed Context */ }","typeGuard":null,"tryCatchPattern":"try { app = Utils.getApp(); } catch (NullPointerException e) { app = yourContext.getApplicationContext(); } // last-resort only; prefer Utils.init in Application","preventionTips":["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."],"tags":["android","initialization","reflection","multiprocess"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}