¿Cómo puedo referirme a los activos de Android en otros directorios?

9

Inicialmente, mi proyecto no estaba destinado a Android, y sus activos están organizados a lo largo de la siguiente estructura de directorios (espero que el arte ASCII se muestre razonablemente bien):

/
+- engine/
 |    +- src/
 |     |      enginefile1.cpp
 |     |      ...
 |     `- textures/
 |            texture1.tex
 |            ...
+- game/
 |    +- src/
 |     |      gamefile1.cpp
 |     |      ...
 |    +- textures/
 |     |      gametexture1.tex
 |     |      ...
 |    +- ios/
 |     |      [various iOS-specific files]
 |     `- android/
 |           | build.xml
 |           | AndroidManifest.xml
 |           +- jni/
 |           |     Android.mk
 |           +- assets/
 |             [other Android-specific files]
 `- othergame/

Mi game/android/jnidirectorio está casi vacío porque Android.mkapunta a las rutas relativas de los archivos de origen en engine/srcy game/src. En realidad, incluso incluye los mensajes correctos Makefilepara que nunca tenga que modificar Android.mkcuando agrego o elimino un archivo fuente al proyecto.

Ambos enginey gameproporcionan activos que deben enviarse con la compilación de Android. Me gustaría build.xmlreferirme a estos activos sin tener que copiarlos manualmente. Sería aceptable una regla que copie los activos en el momento de la compilación y luego los elimine, pero, por supuesto, preferiría una solución de copia cero. ¿Esto tiene sentido? ¿Cómo resolvieron otros este problema de compilación multiplataforma?

sam hocevar
fuente

Respuestas:

1

Sí, absolutamente puedes usar archivos en otros directorios. Coloque los activos que tiene en el assetsdirectorio (hermano del resdirectorio) y use el AssetManagerpara acceder a ellos.

Para cargar mapas de bits, querrá el BitmapFactory, y tendrá que hacer un trabajo adicional si tiene la intención de cargar imágenes dependientes de la resolución.

Tenga cuidado al cargar mapas de bits más de una vez. Debido a que se ocupará de identificadores de archivos sin formato, probablemente desee implementar algún administrador de recursos / memoria que le permita buscar rápidamente referencias a objetos existentes de mapa de bits y similares. Dependiendo de su arquitectura, es posible que necesite hacer esto WeakReferencespara no terminar con todos los datos del juego en la memoria. (Con los recursos normales de Android, ResourceManagermaneja todo esto por usted).

Anm
fuente
Colocar los activos en el mismo directorio (ya sea reso assets) es precisamente lo que no quiero hacer. Como dije en la pregunta, tanto enginey gameproporciono activos que quiere enviar.
sam hocevar
Agregue un script de precompilación para vincular o copiar activos en el assetsdirectorio, lo que le permite preservar cualquier estructura de directorio específica del juego. En cuanto a los enlaces simbólicos Windows: windows7home.net/how-to-create-symbolic-link-in-windows-7
Anm
Aunque un script precompilado es probablemente la solución más conveniente, sería bueno que su respuesta lo mencionara, tal vez junto con un breve ejemplo, para que pueda ser aceptado. (tenga en cuenta que estoy haciendo exactamente el mismo comentario en la otra respuesta)
sam hocevar
1

La propiedad de compilación Ant "asset.dir" es responsable de proporcionar el nombre del directorio de activos. Es "activo" de forma predeterminada, pero puede cambiarlo a algo como "../assets". Esto cambia la ruta de todo el directorio, pero si tiene recursos específicos de Android, aún puede usar el directorio "res".

Krzysiek K.
fuente
1

Qué extraño que las otras respuestas aquí no respondan a su pregunta ... todos asumen que solo desea un directorio de activos, o se refieren a res / en lugar de activos /.

También necesito más de un directorio de activos.

Luché con el <aapt>módulo hormiga durante horas y horas y finalmente me di por vencido y me di cuenta de que hay una manera mucho más fácil.

Copié la <target name="-package-resources"...>etiqueta del archivo de compilación maestro que antusa, android_sdk_dir/tools/ant/build.xmly pegué la etiqueta en mi proyecto build.xml(debe pegar la etiqueta justo antes de build.xmlincluir el maestro , como build.xmlexplican los comentarios al final del proyecto prefabricado ), luego agregué una segunda sección para simplemente ejecutar zippara agregar los activos al archivo .ap_ (que se encuentra ${out.absolute.dir}/${resource.package.file.name}en ese punto en el archivo ant):

    <target name="-package-resources" depends="-crunch">
        <!-- only package resources if *not* a library project -->
        <do-only-if-not-library elseText="Library project: do not package resources..." >
            <aapt executable="${aapt}"
                    command="package"
                    versioncode="${version.code}"
                    versionname="${version.name}"
                    debug="${build.is.packaging.debug}"
                    manifest="${out.manifest.abs.file}"
                    assets="${asset.absolute.dir}"
                    androidjar="${project.target.android.jar}"
                    apkfolder="${out.absolute.dir}"
                    nocrunch="${build.packaging.nocrunch}"
                    resourcefilename="${resource.package.file.name}"
                    resourcefilter="${aapt.resource.filter}"
                    libraryResFolderPathRefid="project.library.res.folder.path"
                    libraryPackagesRefid="project.library.packages"
                    libraryRFileRefid="project.library.bin.r.file.path"
                    previousBuildType="${build.last.target}"
                    buildType="${build.target}"
                    ignoreAssets="${aapt.ignore.assets}">
                <res path="${out.res.absolute.dir}" />
                <res path="${resource.absolute.dir}" />
                <!-- <nocompress /> forces no compression on any files in assets or res/raw -->
                <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw -->
            </aapt>
<!--
NEW XML STARTS HERE
-->
            <exec executable="zip" failonerror="true">
                <arg value="-r" />
                <arg value="${out.absolute.dir}/${resource.package.file.name}" />
                <arg value="my_assets_directory_1" />
                <arg value="my_assets_directory_2" />
                <arg value="my_assets_directory_3" />
            </exec>
<!--
NEW XML ENDS HERE
-->
        </do-only-if-not-library>
    </target>

Este método tiene la ventaja de que tiene más libertad para definir la estructura de directorios de sus activos en el árbol de origen y en el apk (ya que puede hacerlo exec zipvarias veces con diferentes argumentos e incluso envolver zipun script que se ejecuta zipdesde múltiples directorios actuales en su árbol de origen). También tiene control de compresión por archivo (zip tiene una opción -0 para suprimir la compresión) y no necesita usar la etiqueta limitada de no compresión por extensión.

Tenga en cuenta que este antxml viene ANTES de zipalign en el proceso de compilación de hormigas, por lo que todavía obtenemos un archivo "compatible con zip" que satisface las necesidades de alineación de APK y Android Java.

En mi caso, tengo una aplicación basada en NDK y quiero acceder a estos activos solo desde el código C (donde cualquier ruta apk está bien). Si necesita usar las llamadas estándar de activos Java de Android para acceder a estos elementos, no estoy seguro de si deben estar o no en una ruta dentro de los activos con nombre zip / o no. Si es así, puede adaptar el truco anterior al execcrear una secuencia de comandos que se encuentre cden la carpeta del árbol de origen relevante y luego se ejecuta zip.

Louis Semprini
fuente
0

Fuera de mi cabeza, no creo que pueda usar nada fuera de res /, pero si está buscando evitar el costo adicional a su ciclo de desarrollo con una copia, puede intentar moverlos o incluso usar un enlace simbólico ...

notlesh
fuente
Definitivamente no puedo mover los archivos porque algunos de ellos se comparten entre juegos y necesitan permanecer en el enginedirectorio, que está en un repositorio separado. Los enlaces simbólicos pueden ser aceptables, pero no estoy seguro de que funcionen bien en Windows y todavía existe el problema de sincronizarlos automáticamente build.xml.
sam hocevar
2
@Sam: puede dejar los archivos en su repositorio, pero cree un paso de precompilación en su marco de compilación (aparentemente un archivo Ant build.xml) para copiar los archivos en los lugares necesarios para su proyecto de Android. Esta es una práctica común cuando se comparten activos en un juego multiplataforma. Vea la tarea Ant copy: ant.apache.org/manual/Tasks/copy.html
Anm
Aunque un script precompilado es probablemente la solución más conveniente, sería bueno que su respuesta lo mencionara, tal vez junto con un breve ejemplo, para que pueda ser aceptado. (tenga en cuenta que estoy haciendo exactamente el mismo comentario en la otra respuesta)
sam hocevar
0

Si estaba utilizando un proyecto Maven en lugar de un proyecto Ant, podría redefinir fácilmente la carpeta res para que sea lo que quisiera a través de la opción de configuración resourceDirectory de android: apk mojo en el complemento android-maven .

  <plugin>
    <groupId>com.jayway.maven.plugins.android.generation2</groupId>
    <artifactId>android-maven-plugin</artifactId>
    <version>${android.maven.version}</version>
    <configuration>
      <resourceDirectory>${project.basedir}/res</resourceDirectory>
    </configuration>
    <extensions>true</extensions>
  </plugin>

Lamentablemente, a menos que estuvieras dispuesto a migrar de usar Ant a Maven, esta respuesta podría no ayudarte mucho ...

hatboyzero
fuente
0

Si está en un sistema operativo Unix, puede vincularlos y decirle a su control de versiones que ignore el res/directorio.

o0 '.
fuente