Como posso me referir aos recursos do Android em outros diretórios?

9

Inicialmente, meu projeto não se destinava ao Android e seus ativos estão organizados ao longo da seguinte estrutura de diretórios (espero que a arte ASCII seja razoavelmente bem):

/
+- 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/

Meu game/android/jnidiretório está quase vazio porque Android.mkaponta para os caminhos relativos dos arquivos de origem em engine/srce game/src. Na verdade, ele inclui os Makefiles apropriados para que eu nunca precise modificar Android.mkquando adiciono ou removo um arquivo de origem no projeto.

Ambos enginee gamefornecem ativos que precisam ser enviados com a versão do Android. Eu gostaria de me build.xmlreferir a esses ativos sem precisar copiá-los manualmente. Uma regra que copie os ativos no momento da criação e os exclua seria aceitável, mas é claro que eu preferiria uma solução de cópia zero. Isso faz sentido? Como outras pessoas resolveram esse problema de construção de plataforma cruzada?

sam hocevar
fonte

Respostas:

1

Sim, você pode absolutamente usar arquivos em outros diretórios. Coloque os ativos que você possui no assetsdiretório (irmão no resdiretório) e use-o AssetManagerpara acessá-los.

Para carregar bitmaps, você desejará o BitmapFactorye precisará fazer um trabalho extra se pretender carregar imagens dependentes da resolução.

Tenha cuidado ao carregar os Bitmaps mais de uma vez. Como você estará lidando com identificadores de arquivos brutos, provavelmente desejará implementar algum gerenciador de recursos / memória que permita procurar rapidamente referências a objetos Bitmap existentes e similares. Dependendo da sua arquitetura, você pode precisar fazer isso WeakReferencespara não acabar com os dados do jogo inteiro na memória. (Com recursos normais do Android, o ResourceManagergerencia tudo isso para você.)

Anm
fonte
Colocar os ativos no mesmo diretório (seja resou não assets) é precisamente o que eu não quero fazer. Como eu disse na pergunta, tanto enginee gamefornecer activos que eu quero para enviar.
Sam Hocevar
Adicione um script de pré-compilação para vincular ou copiar ativos no assetsdiretório, permitindo preservar qualquer estrutura de diretório específica do jogo. Quanto aos links simbólicos do Windows: windows7home.net/how-to-create-symbolic-link-in-windows-7
Anm:
Embora um script de pré-compilação seja provavelmente a solução mais conveniente, seria bom se sua resposta o mencionasse, talvez junto com um pequeno exemplo, para que pudesse ser aceito. (note que eu estou fazendo o mesmo comentário são em outra resposta)
Sam Hocevar
1

A propriedade de construção da formiga "asset.dir" é responsável por fornecer o nome do diretório de ativos. Por padrão, são "ativos", mas você pode alterá-lo para algo como "../assets". Isso altera o caminho do diretório inteiro, mas se você tiver recursos específicos do Android, ainda poderá usar o diretório "res".

Krzysiek K.
fonte
1

Que estranho as outras respostas aqui não responderem à sua pergunta ... todas elas assumem que você deseja apenas um diretório de ativos ou se refere a res / em vez de assets /.

Também preciso de mais de um diretório de ativos.

Lutei com o <aapt>módulo ant por horas e horas e finalmente desisti e percebi que havia uma maneira muito mais fácil.

Copiei a <target name="-package-resources"...>tag do arquivo de construção mestre que antusa, android_sdk_dir/tools/ant/build.xmle colei a tag no meu projeto build.xml(você deve colar a tag imediatamente antes da build.xmlinclusão do mestre , como build.xmlexplicam os comentários no final do projeto pré-fabricado ) e, em seguida, adicionei uma segunda seção para simplesmente exec zippara adicionar os ativos ao arquivo .ap_ (que está ${out.absolute.dir}/${resource.package.file.name}nesse ponto no arquivo 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>

Esse método tem a vantagem de você ser mais livre para definir a estrutura de diretórios de seus ativos na árvore de origem e no apk (pois é possível exec zipvárias vezes com argumentos diferentes e até envolver zipum script que é executado a zippartir de vários diretórios atuais em seu diretório). árvore de origem). Você também tem o controle de compactação por arquivo (o zip tem uma opção -0 para suprimir a compactação) e não precisa usar a tag nocompress limitada por extensão apenas.

Observe que esse antxml vem ANTES do zipalign no processo de criação de formigas, por isso ainda temos um arquivo "compatível com zip" que atende às necessidades de alinhamento de APKs e Java Android.

No meu caso, eu tenho um aplicativo baseado em NDK e desejo acessar esses ativos apenas do código C (onde qualquer caminho do apk estiver OK). Se você precisar usar as chamadas padrão dos ativos Java Android para acessar esses itens, não tenho certeza se eles devem ou não estar em um caminho dentro do zip denominado ativos / não. execNesse caso, você pode adaptar o truque acima, inserindo um script cdna pasta da árvore de origem relevante e executando zip.

Louis Semprini
fonte
0

Em primeiro lugar, acho que você não pode usar nada fora do res /, mas se você estiver procurando evitar custos adicionais ao seu ciclo de desenvolvimento com uma cópia, tente movê-los ou talvez até usar um link simbólico ...

entalhe
fonte
Definitivamente, não consigo mover os arquivos porque alguns deles são compartilhados entre os jogos e precisam permanecer no enginediretório, que está em um repositório separado. Os links simbólicos podem ser aceitáveis, mas não tenho certeza de que funcionariam bem no Windows e ainda há o problema de sincronizá-los automaticamente build.xml.
Sam Hocevar
2
@ Sam - Você pode deixar os arquivos no seu repositório, mas criar uma etapa de pré-compilação em sua estrutura de construção (aparentemente um arquivo Ant build.xml) para copiar os arquivos para os locais necessários para o seu projeto Android. Essa é uma prática comum ao compartilhar ativos em um jogo de várias plataformas. Veja a tarefa de cópia do Ant: ant.apache.org/manual/Tasks/copy.html
Anm
Embora um script de pré-compilação seja provavelmente a solução mais conveniente, seria bom se sua resposta o mencionasse, talvez junto com um pequeno exemplo, para que pudesse ser aceito. (note que eu estou fazendo o mesmo comentário são em outra resposta)
Sam Hocevar
0

Se você estivesse usando um projeto Maven em vez de um projeto Ant, poderia facilmente redefinir a pasta res para o que quisesse, através da opção de configuração resourceDirectory do android: apk mojo no android-maven-plugin .

  <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>

Infelizmente, a menos que você esteja disposto a migrar do Ant para o Maven, essa resposta pode não ajudá-lo muito ...

hatboyzero
fonte
0

Se você estiver em um sistema operacional unix, poderá vinculá-los com força e dizer ao seu controle de versão para ignorar o res/diretório.

o0 '.
fonte