Embalaje archivos de recursos Android dentro de un archivo Jar distribuible
-
22-09-2019 - |
Pregunta
Estoy trabajando en algo de código Android reutilizable que me gustaría distribuir a otros desarrolladores para su uso dentro de sus propias aplicaciones. El código tiene algunas dependencias de recursos (diseños, XML y PNG dibujables) que me gustaría ser capaz de incluir y de referencia dentro de un único paquete (archivo JAR).
¿Es esto posible, y si es así cuál es el mejor método para hacer esto?
Solución
No tengo ninguna noticia optimista para usted. En general no se puede distribuir su propio paquete tan fácilmente como era de esperar. El principal problema es el archivo R autogenerada. Es probable que algunas referencias a él - usted tiene sus diseños y dibujables. Usuario de la biblioteca tendrá su propio archivo de R - que contiene los identificadores de sus recursos, no para los que su biblioteca ofrece.
En el caso de los recursos dibujable se podía leer en forma clásica, sin el archivo R. Pero por lo que sé que no es capaz de inflar los diseños de los archivos XML externos.
Así lo feo corte en este caso sería distribuir su conjunto biblioteca con todos sus recursos, que el usuario tendría que copiar a su carpeta "res". Para ser honesto, no hay una solución buena a su problema ... lo siento. Saludos!
Otros consejos
Dado que Android hace que la clase R
de forma automática con archivos de recursos en la carpeta /res
, utilizando la clase R
como final static
es imposible.
He encontrado una solución agradable de usar un archivo con los archivos jar
res
. Aquí es cómo lo hice:
-
En el código fuente de la que se va a exportar en el archivo
jar
, no use variablesR
porque va a ser sustituida por una dirección de memoria estática final en tiempo de compilación. En lugar de utilizarR
, hice mi propio método a continuación: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; }
Por ejemplo, si usted tiene un diseño llamado
main.xml
, lo puede conseguir llamando al método:int id = getResourceIdByName(context.getPackageName(), "layout", "main");
Si usted tiene una cadena cuya
id
es "texto1", lo puede conseguir llamando al métodoint id = getResourceIdByName(context.getPackageName(), "string", "text1");
Este método le da su identificador de recursos en tiempo de ejecución. Utiliza la API de reflexión para obtener el estado de
R
en tiempo de ejecución.Mediante el uso de este método se puede evitar el uso de la variable
R
. -
Copiar archivos
res
a su proyecto de destino. -
Generar.
diseños:
codificar en su fuente de Java
XML y PNG:
copiar XML y PNG a la carpeta src del proyecto y el paquete de tarro, por ejemplo
copiar a.png a src / com / example / prueba
cargarlo como siguiendo los códigos de Java:
InputStream is = YourClassName.class.getClassLoader().getResourceAsStream("com/example/test/a.png");
if ( null != is )
{
Bitmap bmp = BitmapFactory.decodeStream(is);
Me acabo de enterar de que la herramienta aapt
en el SDK de Android permite la opción siguiente:
--non-constant-id Make the resources ID non constant. This is required to make an R java class that does not contain the final value but is used to make reusable compiled libraries that need to access resources.
Esto parece prometedor, aunque no he probado esto así que no tengo ni idea de si funciona. Sospecho que esto es para evitar el problema abordado por el post de @ J.J.Kim anteriormente.
Se puede obtener dinámicamente Identificación del recurso mediante el método androide.
int preferences = context.getResources().getIdentifier("preferences", "xml", context.getPackageName());
Más tarde, conviene tener en cuenta sus recursos (copiado) a su nuevo proyecto.
user558185 solución pero aquí es una forma más sencilla. Si usted es recursos en un proyecto de biblioteca (para un plugin de Córdoba, por ejemplo), puede obtener recursos con context.getResources().getIdentifier(name, className, context.getPackageName());
Esto sucede cuando los recursos del proyecto biblioteca de archivos R no se genera correctamente y el R packageName no coincide con el packageName requerida por el proyecto de la biblioteca.
El uso es la misma que la respuesta user558185, pero usar un método nativo de Android.
Hola Creo que esta es una respuesta tardía pero aún así acabo de qué informar sobre AAR
Android Archivo -. Este archivo puede contener sus res y archivos de manifiesto, por lo que el otro puede desarrollar simplemente importar el AAR a su proyecto y compilar el código
De esta manera podríamos obtener errores de combinación de manifiesto, el arreglo para que utilice reemplazar propiedad en su manifiesto y este debe ser revisado antes de su distribución.
Puede utilizar la abstracción para obtener los valores R de la clase de aplicación (el usuario).
protected abstract void getMyLayoutTextBox(int myLayoutTextBox);
A continuación, el usuario tiene que extender su clase (que se extiende Activity
), y poner en práctica este método. En su clase, que acaba de llamar getMyLayoutTextBox()
y tendrá el valor correcto R suministrada por el usuario después de que implementa el frasco de distribución.
Puede leer más sobre abstracción aquí .
Si está utilizando Eclipse, vaya a "Properties->Java Build Path"
proyecto. En la pestaña "Source"
, añadir la res carpeta que desea empaquetar (por ejemplo Res. / Crudo) .
Se añade la siguiente línea en el archivo .classpath
Después de la construcción de hecho, el nuevo archivo JAR contendrá los archivos de la carpeta res/raw/
. Se puede acceder a ellos como user558185 sugerido.