Packaging Android resource files within a distributable Jar file

Jeff Gilfelt picture Jeff Gilfelt · Jan 3, 2010 · Viewed 27k times · Source

I am working on some reusable Android code that I would like to distribute to other developers for use within their own applications. The code has some resource dependencies (layouts, xml & png drawables) that I would like to be able to include and reference within a single package (Jar file).

Is this possible, and if so what is the best method to do this?

Answer

J.J. Kim picture J.J. Kim · Aug 19, 2011

Since Android makes the R class automatically with resource files under the /res folder, using the R class as final static is impossible.

I found a nice solution to use a jar file with the res files. Here is how I did it:

  1. In your source code which will be exported in the jar file, don't use R variable because it will be replaced with a final static memory address in compile time. Instead of using R, I made my own method below:

    public static int getResourceIdByName(String packageName, String className, String name) {
        Class r = null;
        int id = 0;
        try {
            r = Class.forName(packageName + ".R");
    
            Class[] classes = r.getClasses();
            Class desireClass = null;
    
            for (int i = 0; i < classes.length; i++) {
                if (classes[i].getName().split("\\$")[1].equals(className)) {
                    desireClass = classes[i];
    
                    break;
                }
            }
    
            if (desireClass != null) {
                id = desireClass.getField(name).getInt(desireClass);
            }
    
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    
        return id;
    }
    

    For example, if you have a layout named main.xml, you can get it by calling the method:

    int id = getResourceIdByName(context.getPackageName(), "layout", "main");
    

    If you have a string whose id is "text1", you can get it by calling method

    int id = getResourceIdByName(context.getPackageName(), "string", "text1");
    

    This method gives you your resource id at runtime. It uses the reflection API to get the status of R at runtime.

    By using this method you can avoid using the R variable.

  2. Copy your res files to your target project.

  3. Build.