Come posso fare riferimento alle risorse Android in altre directory?


9

Inizialmente il mio progetto non era pensato per Android e le sue risorse sono organizzate secondo la seguente struttura di directory (spero che l'arte ASCII sia resa ragionevolmente bene):

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

La mia game/android/jnidirectory è quasi vuota perché Android.mkpunta ai percorsi relativi dei file sorgente in engine/srce game/src. In realtà, include anche i messaggi corretti in Makefilemodo che non debba mai modificare Android.mkquando aggiungo o rimuovo un file sorgente al progetto.

Entrambi enginee gameforniscono risorse che devono essere spedite con la build Android. Vorrei build.xmlfare riferimento a queste risorse senza doverle copiare manualmente. Una regola che copia le risorse al momento della creazione, quindi le elimina, sarebbe accettabile, ma ovviamente preferirei una soluzione a zero copie. ha senso? In che modo altri hanno risolto questo problema di costruzione multipiattaforma?

Risposte:


1

Sì, puoi assolutamente usare i file in altre directory. Posiziona le risorse che hai nella assetsdirectory (fratello nella resdirectory) e usa AssetManagerper accedervi.

Per caricare bitmap, ti consigliamo il BitmapFactory, e dovrai fare un lavoro extra se intendi caricare immagini dipendenti dalla risoluzione.

Fai attenzione a caricare Bitmap più di una volta. Poiché avrai a che fare con handle di file non elaborati, probabilmente vorrai implementare un gestore di risorse / memoria che ti consenta di cercare rapidamente riferimenti a oggetti Bitmap esistenti e simili. A seconda della tua architettura, potresti doverlo fare in WeakReferencesmodo da non finire con tutti i dati di gioco in memoria. (Con le normali risorse Android, ResourceManagergestisce tutto questo per te.)


Posizionare le risorse nella stessa directory (sia essa reso assets) è esattamente ciò che non voglio fare. Come ho detto nella domanda, entrambi enginee gameforniscono risorse che voglio spedire.
sam hocevar,

Aggiungi uno script di pre-compilazione per collegare o copiare risorse nella assetsdirectory, consentendoti di preservare qualsiasi struttura di directory specifica del gioco. Per quanto riguarda i link simbolici di Windows: windows7home.net/how-to-create-symbolic-link-in-windows-7
Anm,

Sebbene uno script di pre-compilazione sia probabilmente la soluzione più comoda, sarebbe bello se la tua risposta lo menzionasse, magari insieme a un breve esempio, in modo che potesse essere accettato. (nota che sto facendo lo stesso identico commento nell'altra risposta)
sam hocevar,

1

La proprietà di build Ant "asset.dir" è responsabile della fornitura del nome della directory degli asset. Sono "risorse" per impostazione predefinita, ma puoi cambiarlo in qualcosa come "../assets". Questo cambia il percorso dell'intera directory, ma se si dispone di risorse specifiche per Android, è comunque possibile utilizzare la directory "res".


1

Che strano che le altre risposte qui non rispondano alla tua domanda ... tutti presumono che tu voglia una sola directory degli asset, o fai riferimento a res / invece di assets /.

Ho anche bisogno di più di una directory di risorse.

Ho combattuto con il <aapt>modulo formica per ore e ore e alla fine ho rinunciato e mi sono reso conto che c'è un modo molto più semplice.

Ho copiato il <target name="-package-resources"...>tag dal file di build principale che antutilizza android_sdk_dir/tools/ant/build.xmle incollato il tag nel mio progetto build.xml(è necessario incollare il tag prima che il master build.xmlsia incluso, come build.xmlspiegano i commenti alla fine del progetto prefabbricato ), quindi ho aggiunto una seconda sezione da eseguire semplicemente zipper aggiungere le risorse al file .ap_ (che si trova ${out.absolute.dir}/${resource.package.file.name}a quel punto nel file 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>

Questo metodo ha il vantaggio di essere più libero di definire la struttura delle directory delle risorse nella struttura di origine e nell'apk (poiché è possibile exec zippiù volte con argomenti diversi e persino avvolgere zipuno script che viene eseguito zipda più directory correnti nella propria albero dei sorgenti). Hai anche il controllo della compressione per file (zip ha un'opzione -0 per sopprimere la compressione) e non è necessario utilizzare il tag nocompress limitato, solo per estensione.

Nota che questo antxml arriva PRIMA di zipalign nel processo di compilazione della formica, quindi abbiamo ancora un archivio "compatibile con zip" che soddisfa le esigenze di allineamento di APK e Android Java.

Nel mio caso ho un'app basata su NDK e voglio accedere a queste risorse solo dal codice C (dove qualsiasi percorso apk è OK). Se è necessario utilizzare le chiamate degli asset Java Android standard per accedere a questi elementi, non sono sicuro che debbano essere o meno in un percorso all'interno dello zip denominato asset. In tal caso, è possibile adattare il trucco di cui sopra execinserendo uno script cdnella cartella dell'albero dei sorgenti pertinente, quindi viene eseguito zip.


0

Al di fuori della mia testa, non penso che tu possa usare qualcosa al di fuori di res /, ma se stai cercando di evitare costi aggiuntivi per il tuo ciclo di sviluppo con una copia, potresti provare a spostarli invece o forse anche usando un link simbolico ...


Non posso assolutamente spostare i file perché alcuni sono condivisi tra i giochi e devono rimanere nella enginedirectory, che si trova in un repository separato. I collegamenti simbolici potrebbero essere accettabili, ma non sono sicuro che funzionerebbero bene su Windows e quindi c'è ancora il problema di averli sincronizzati automaticamente build.xml.
sam hocevar,

2
@Sam - Puoi lasciare i file al loro posto nel tuo repository, ma crea un passo di pre-compilazione nel tuo framework di build (apparentemente un file Ant build.xml) per copiare i file nei luoghi necessari per il tuo progetto Android. Questa è una pratica comune quando si condividono risorse in un gioco multipiattaforma. Vedi l'attività di copia della formica: ant.apache.org/manual/Tasks/copy.html
Anm

Sebbene uno script di pre-compilazione sia probabilmente la soluzione più comoda, sarebbe bello se la tua risposta lo menzionasse, magari insieme a un breve esempio, in modo che potesse essere accettato. (nota che sto facendo lo stesso identico commento nell'altra risposta)
sam hocevar,

0

Se stavi usando un progetto Maven in contrapposizione a un progetto Ant, potresti facilmente ridefinire la cartella res in modo che corrisponda a ciò che volevi tramite l' opzione di configurazione della directory di risorse di Android: apk mojo nel plug- in 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>

Purtroppo, a meno che tu non sia disposto a migrare dall'uso della formica all'utilizzo di Maven, questa risposta potrebbe non aiutarti molto ...


0

Se ci si trova su un sistema operativo unix, è possibile collegarli e indicare al controllo della versione di ignorare la res/directory.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.