{"record":{"id":"3f4f19c50fd484d0","repo":"didi/DoKit","slug":"unable-to-obtain-resources-for-package-data-u","errorCode":null,"errorMessage":"Unable to obtain resources for package: \" + data.uri","messagePattern":"Unable to obtain resources for package: \" \\+ data\\.uri","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"warning","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/Utils.java","lineNumber":372,"sourceCode":"      id = resources.getIdentifier(name, type, pkg);\n    } else {\n      throw new FileNotFoundException(\"More than two path segments: \" + data.uri);\n    }\n    return id;\n  }\n\n  static Resources getResources(Context context, Request data) throws FileNotFoundException {\n    if (data.resourceId != 0 || data.uri == null) {\n      return context.getResources();\n    }\n\n    String pkg = data.uri.getAuthority();\n    if (pkg == null) throw new FileNotFoundException(\"No package provided: \" + data.uri);\n    try {\n      PackageManager pm = context.getPackageManager();\n      return pm.getResourcesForApplication(pkg);\n    } catch (PackageManager.NameNotFoundException e) {\n      throw new FileNotFoundException(\"Unable to obtain resources for package: \" + data.uri);\n    }\n  }\n\n  /**\n   * Prior to Android 5, HandlerThread always keeps a stack local reference to the last message\n   * that was sent to it. This method makes sure that stack local reference never stays there\n   * for too long by sending new messages to it every second.\n   */\n  static void flushStackLocalLeaks(Looper looper) {\n    Handler handler = new Handler(looper) {\n      @Override public void handleMessage(Message msg) {\n        sendMessageDelayed(obtainMessage(), THREAD_LEAK_CLEANING_MS);\n      }\n    };\n    handler.sendMessageDelayed(handler.obtainMessage(), THREAD_LEAK_CLEANING_MS);\n  }\n\n  @TargetApi(HONEYCOMB)","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/Utils.java#L354-L390","documentation":"Utils.getResources(Context, Request) maps the URI's authority (package name) to a Resources instance via PackageManager.getResourcesForApplication(pkg). If that package is not installed, NameNotFoundException is caught and rethrown as FileNotFoundException('Unable to obtain resources for package: <uri>'). This is the standard failure when loading a resource URI that points at another app's package which is not available.","triggerScenarios":"Passing android.resource://com.other.app/drawable/foo where com.other.app is not installed on the device; package renamed so the authority no longer matches any installed package; querying a package while it is being uninstalled/updated.","commonSituations":"Loading plugin/other-app resources (e.g. themes or icon packs) without checking installation; hard-coded package names that change across app versions; emulator vs. device differences where an optional companion app is absent.","solutions":["Check installation first: context.getPackageManager().getPackageInfo(pkg, 0) in try/catch, or getApplicationInfo(pkg, 0), before issuing the load.","Fall back to a bundled resource when the target package is missing.","Use getPackageManager().canResolvePackage / queryIntentActivities to gate optional-app resource loads at a higher level."],"exampleFix":"// before\npicasso.load(Uri.parse(\"android.resource://com.other.app/drawable/icon\")).into(iv);\n\n// after\nString pkg = \"com.other.app\";\ntry {\n    context.getPackageManager().getPackageInfo(pkg, 0);\n    picasso.load(Uri.parse(\"android.resource://\" + pkg + \"/drawable/icon\")).into(iv);\n} catch (PackageManager.NameNotFoundException e) {\n    iv.setImageResource(R.drawable.default_icon);\n}","handlingStrategy":"try-catch","validationCode":"static boolean pkgInstalled(Context ctx, String pkg) {\n    try {\n        ctx.getPackageManager().getPackageInfo(pkg, 0);\n        return true;\n    } catch (PackageManager.NameNotFoundException e) {\n        return false;\n    }\n}","typeGuard":null,"tryCatchPattern":"// Not surfaced as NameNotFoundException; Picasso wraps it. Guard before the load:\nif (pkgInstalled(context, pkg)) {\n    picasso.load(resourceUri).into(iv);\n} else {\n    iv.setImageResource(R.drawable.fallback);\n}","preventionTips":["Check package installation before referencing cross-app resources.","Treat hard-coded package names as config that can drift — verify at runtime.","Provide a bundled fallback for optional companion-app resources."],"tags":["android","picasso","package-manager","resource","missing-dependency"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}