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:
hard code in your java source
xml & png:
copy xml & png to your project src folder and package to jar, for example
copy a.png to src/com/example/test
load it as following java codes:
InputStream is = YourClassName.class.getClassLoader().getResourceAsStream("com/example/test/a.png");
if ( null != is )
{
Bitmap bmp = BitmapFactory.decodeStream(is);
you can use abstraction to get the R values from the implementing class (the user).
protected abstract void getMyLayoutTextBox(int myLayoutTextBox);
Then the user has to extend your class (which extends Activity
), and implement this method. In your class, you just call getMyLayoutTextBox()
and you'll have the correct R value supplied by the user after he implements your distributable jar.
You can read more about abstraction here.
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:
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.
Copy your res
files to your target project.
Build.
Hi i think this is a late response but still i just what to inform about AAR
Android ARchive - this file can hold your res and manifest files, so that the other develop can just import the aar to their project and compile their code.
This way we might get Manifest merge errors, the fix for it to use replace property in your manifest and this should be checked before distribution.
If you are using Eclipse, go to project "Properties->Java Build Path"
. Under tab "Source"
, add the res folder you want to pack (e.g. res/raw).
It will add the following line into the .classpath
file
<classpathentry kind="src" path="res/raw"/>
After building done, the new jar file will contain the files in res/raw/
folder. You can access them as user558185 suggested.
You can dynamically get resource id using android method.
int preferences = context.getResources().getIdentifier("preferences", "xml", context.getPackageName());
Later your resources have to be included (copied) to your new project.