Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Packaging Android resource files within a distributable Jar file

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?

like image 563
Jeff Gilfelt Avatar asked Jan 03 '10 13:01

Jeff Gilfelt


People also ask

Can jar contain resources?

jar ) contain your executable classes and resource files. A jar can also contain other jar files, which is useful when your program needs some library which is packaged in a jar.

What are resources file in Android?

Resources are the additional files and static content that your code uses, such as bitmaps, layout definitions, user interface strings, animation instructions, and more. You should always externalize app resources such as images and strings from your code, so that you can maintain them independently.


2 Answers

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.

like image 189
J.J. Kim Avatar answered Sep 20 '22 23:09

J.J. Kim


I don't have any optimistic news for you. In general you cannot distribute your own package as easily as you would expect. The main problem is the autogenerated R file. You probably make some references to it - you have your layouts and drawables. User of your library will have his own R file - containing ids for his resources, not for the ones your library provides.

In case of drawable resources you could read them in classic way, without R file. But as far as I know you are not able to inflate layouts from external xml files.

So the ugly hack here would be to distribute your library together with all your resources, which user would have to copy to his "res" folder. To be honest, there is no good solution to your problem... sorry. Regards!

like image 21
Ramps Avatar answered Sep 18 '22 23:09

Ramps