Tencent/tinker · error · IllegalStateException

resource references is null

Error message

resource references is null

What it means

To inject patched resources, Tinker enumerates every live Resources instance via ActivityThread's internal registry (mResourceImpls on N+, mActiveResources on older versions). This IllegalStateException means both lookups yielded null, so there is no known set of Resources objects to patch and the resource patch cannot be applied.

Source

Thrown at tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerResourcePatcher.java:167

                final Field mResourceReferences = findField(resourcesManagerClass, "mResourceReferences");
                references = (Collection<WeakReference<Resources>>) mResourceReferences.get(resourcesManager);

                try {
                    final Field mResourceImplsField = findField(resourcesManagerClass, "mResourceImpls");
                    resourceImpls = (Map<Object, WeakReference<Object>>) mResourceImplsField.get(resourcesManager);
                } catch (Throwable ignored) {
                    resourceImpls = null;
                }
            }
        } else {
            final Field fMActiveResources = findField(activityThread, "mActiveResources");
            final HashMap<?, WeakReference<Resources>> activeResources7 =
                    (HashMap<?, WeakReference<Resources>>) fMActiveResources.get(currentActivityThread);
            references = activeResources7.values();
        }
        // check resource
        if (references == null) {
            throw new IllegalStateException("resource references is null");
        }

        final Resources resources = context.getResources();

        // fix jianGuo pro has private field 'mAssets' with Resource
        // try use mResourcesImpl first
        if (SDK_INT >= 24) {
            try {
                // N moved the mAssets inside an mResourcesImpl field
                resourcesImplFiled = findField(resources, "mResourcesImpl");
            } catch (Throwable ignore) {
                // for safety
                assetsFiled = findField(resources, "mAssets");
            }
        } else {
            assetsFiled = findField(resources, "mAssets");
        }

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Update Tinker to a version supporting the device's Android release.
  2. Reproduce on the exact device/ROM, dump ActivityThread fields, and report to Tinker maintainers.
  3. Disable resource patching (tinker not configured for RES, or only ship DEX patches) if the app can tolerate missing resource fixes on that ROM.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight on the target device before enabling resource patches
try {
    Object at = ShareReflectUtil.getActivityThread(context, null);
    ShareReflectUtil.findField(at, SDK_INT >= 24 ? "mResourcesManager" : "mActiveResources");
} catch (Throwable t) {
    disableResourcePatchForThisDevice();
}

Try / catch

try {
    TinkerResourcePatcher.monkeyPatchExistingResources(context, externalResourceFile);
} catch (TinkerRuntimeException e) {
    // resource injection unsupported here: continue with dex-only patch
    Log.w(TAG, "resource patch skipped: " + e.getMessage());
}

Prevention

When it happens

Trigger: MonkeyPatchResourcePatcher running on a framework where ActivityThread's resource-registry field was renamed, removed, or typed differently by the OEM; also when reflection to ActivityThread itself failed earlier and the fallback path also found nothing.

Common situations: Non-AOSP or heavily modified ROMs; preview/beta Android versions whose ActivityThread internals differ; devices where hidden-API restrictions block reading these fields.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/0be86660cc3f6361. Report an issue: GitHub.