1

My aim is to write an android Library that can list all the resources (layouts, drawables. ids, etc.) of the caller application. The caller application need to pass to the library, nothing more than App Name or the package namespace. E.g:

The MyLibrary function:

public void listDrawables(String namespace) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    String resourceNameSpace = namespace + ".R";
    String drawableNamespace = resourceNameSpace + ".drawable";

    final Class drawableClass = Class.forName(drawableNamespace);
    Object drawableInstance = drawableClass.newInstance();
    final Field[] fields = drawableClass.getDeclaredFields();

    for (int i = 0, max = fields.length; i < max; i++) {
        final int resourceId;
        try {
            resourceId = fields[i].getInt(drawableInstance);
            // Use resourceId further
        } catch (Exception e) {
            continue;
    }
}

The caller code (From the App Activity, say com.example.sample.MainActivity.java)

mylibrary.listDrawables("com.example.sample");

I have setup the MyLibrary as a dependent android library for the Sample app.

When this is run, I get this exception inside library at the Class.forName statement:

java.lang.ClassNotFoundException: com.example.sample.R.drawable

I am not able to understand fully, why library can't refer to the class. May be I missed a basic lesson in Java classpath and how build works, but isn't the class already loaded when library runs?

I would also like to know id there is any alternative way to list resources in an external library.

  • Well, `com.example.sample.R.drawable` isn't really a class. `R` is the class that holds all of the resource references. So I would start by removing the `.drawable`. Out of curiosity why do you want to dynamically access a list of Resources like that? – FoamyGuy Aug 31 '13 at 14:35
  • Possible duplicate: http://stackoverflow.com/questions/11288147/get-resources-from-another-apk – dst Aug 31 '13 at 14:39
  • `drawable` is a public final inner class for the generated R class (in case drawables are present), so I was hoping to access that too. – Manas Agarwal Aug 31 '13 at 14:40
  • I was hoping that I don't need to pass all the list of resources to library, which increases the usability of my library (minimal integration code for the client). – Manas Agarwal Aug 31 '13 at 14:42
  • @dst I am not trying to access across apk's. Its within the same app. Also in may case, I dont even have the resources names or ids. Hence to get the list, I need to use reflection on the R class. – Manas Agarwal Aug 31 '13 at 14:43
  • In that case, why don't you just pass along a `Class>` reference to the `R` class (or the `R.drawable` class if you only need that)? – dst Aug 31 '13 at 15:18
  • @dst, you got a point there. Anyways I was reflecting it wrong. Found the right answer. But I'll think of using the `Class>` directly. – Manas Agarwal Aug 31 '13 at 17:19
  • Where you able to create this library? A library like this one will come handy for me today. – moxi Nov 30 '22 at 00:32

1 Answers1

0

Since Drawable is a inner class, you need to access it by using $.

String resourceNameSpace = namespace + ".R";
String drawableNamespace = resourceNameSpace + "$drawable";
  • Ah. This works! Thanks a lot Abhigyan. @FoamyGuy, now I understand what you were hinting at in your comment. I should have read more into Reflection. – Manas Agarwal Aug 31 '13 at 17:14