Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What EXACTLY does Resources$NotFoundException mean?

Tags:

android

I recently posted a Resources$NotFoundException bug here and got the usual generic suggestions about deleting the "gen" folder, doing a clean, doing a refresh, etc, etc. There are hundreds (thousands?) of other programmers getting the same exception and getting the same suggestions all over S.O. and the web. But I can't seem to find anyplace where anyone describes what that error really means.

The documentation is vague: http://developer.android.com/reference/android/content/res/Resources.NotFoundException.html

Resources$NotFoundException is a runtime error so presumably it's looking for something in the APK file.

  1. How are resources built into the APK file at build-time? We start with the XML file and then what...?
  2. How are they referenced at runtime?
  3. What is the relationship between the resource ID I see in the debugger and how it's identified in the APK file?
  4. What (Windows) tools can I use to examine an APK file to find these resource myself?

Thanks in advance for the answers to any of these questions!

PS - if you think you have an answer to the original bug please post it there and not to this thread; this is a different question.

like image 546
user316117 Avatar asked May 21 '13 13:05

user316117


1 Answers

  1. Resource can be packaged in various ways from raw assets, to optimized images to packaged byte data. All zipped into one apk. Id of a resource is what helps finding it back. During the development, build tool (aapt) continually scan res directory for xml, images etc and generate numeric constants in R.java. Read a detail about android's build process.

  2. At runtime the Resources instance decides where to look for, depending on whether which of its get method is called. The numeric id helps it query the resource mapping and find the correct one. Actual data loading is handled by native low-level code.

  3. Debugger can show you objects and their fields. To find out what is missing read the error message NotFoundException traces in logcat. It lists hex value of resource id.

  4. ApkTool lets you deflate an apk file and re-construct the res directory.

Update:

How are resources packaged:

If you have an apk and want to see full resource table run aapt tool in SDK as:

 aapt list -v myApp.apk

It will show details as:

Archive:  ./myApp.apk
 Length   Method    Size  Ratio   Offset      Date  Time  CRC-32    Name
--------  ------  ------- -----  -------      ----  ----  ------    ----
     468  Deflate     228  51%         0  11-07-12 23:25  29fb0660  res/color/abs__primary_text_disable_only_holo_dark.xml
     468  Deflate     228  51%       332  11-07-12 23:25  bae4791a  res/color/abs__primary_text_disable_only_holo_light.xml
    2942  Stored     2942   0%    280417  10-27-12 16:52  9b5af43b  res/drawable-xhdpi/ic_mus.png
    2330  Stored     2330   0%    283418  10-27-12 16:52  21f5ba4d  res/drawable-xhdpi/ic_pic.png
    1556  Stored     1556   0%    285810  10-27-12 16:52  31c3402b  res/drawable-xhdpi/ic_vid.png

You will see the method (deflate,stored etc) and offset in binary data where a resource is stored, and length, which denotes how many bytes to read after offset to get that resource.

What does Resources.NotFoundException prints:

Here's the code which generates it:

public void getValue(int id, TypedValue outValue, boolean resolveRefs)
        throws NotFoundException {
    boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs);
    if (found) {
        return;
    }
    throw new NotFoundException("Resource ID #0x"
                                + Integer.toHexString(id));
}

Thus, it prints hex value of the Id which Resources instance is requested to load.

Here's a part of R.java:

public static int absForceOverflow=0x7f010039;

You can see Id is assigned similar Hex values.

Can I solve this error?

The error should not have occurred at first place if build tools compiled you project successfully. There's not much you can do except cleaning or rebuilding the project. This represents a bug in build tools or resource loader OR data corruption in apk on device.

like image 190
S.D. Avatar answered Sep 29 '22 13:09

S.D.