Bagaimana saya bisa merujuk ke aset Android di direktori lain?

9

Proyek saya pada awalnya tidak dimaksudkan untuk Android, dan asetnya diatur di sepanjang struktur direktori berikut (saya harap seni ASCII merender dengan cukup baik):

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

game/android/jniDirektori saya hampir kosong karena Android.mkmenunjuk ke jalur relatif file sumber di engine/srcdan game/src. Sebenarnya, itu bahkan termasuk Makefiles yang tepat sehingga saya tidak perlu memodifikasi Android.mkketika saya menambah atau menghapus file sumber ke proyek.

Keduanya enginedan gamemenyediakan aset yang perlu dikirim bersama Android build. Saya ingin build.xmlmerujuk ke aset ini tanpa harus menyalinnya secara manual. Aturan yang menyalin aset saat membangun kemudian menghapusnya akan diterima, tetapi tentu saja saya lebih suka solusi salinan nol. Apakah ini masuk akal? Bagaimana orang lain memecahkan masalah pembangunan lintas platform ini?

sam hocevar
sumber

Jawaban:

1

Ya, Anda benar-benar dapat menggunakan file di direktori lain. Tempatkan aset yang Anda miliki ke assetsdirektori (saudara ke resdirektori), dan gunakan AssetManageruntuk mengaksesnya.

Untuk memuat bitmap, Anda menginginkannya BitmapFactory, dan Anda harus melakukan beberapa pekerjaan tambahan jika Anda ingin memuat gambar yang bergantung pada resolusi.

Hati-hati memuat Bitmap lebih dari sekali. Karena Anda akan berurusan dengan pegangan file mentah, Anda mungkin ingin menerapkan beberapa manajer sumber daya / memori yang memungkinkan Anda mencari referensi ke objek Bitmap yang ada dan sejenisnya dengan cepat. Tergantung pada arsitektur Anda, Anda mungkin perlu melakukan ini dengan WeakReferencessehingga Anda tidak berakhir dengan seluruh data gim dalam memori. (Dengan sumber daya Android normal, ResourceManagersemua ini menangani untuk Anda.)

Anm
sumber
Menempatkan aset di direktori yang sama (baik itu resatau assets) adalah persis apa yang tidak ingin saya lakukan. Seperti yang saya katakan dalam pertanyaan, keduanya enginedan gamememberikan aset yang ingin saya kirimkan.
sam hocevar
Tambahkan skrip pra-kompilasi untuk menautkan atau menyalin aset ke assetsdirektori, memungkinkan Anda untuk melestarikan struktur direktori spesifik game. Adapun Windows symlinks: windows7home.net/how-to-create-symbolic-link-in-windows-7
Anm
Meskipun skrip pra-kompilasi mungkin merupakan solusi yang paling mudah digunakan, alangkah baiknya jika jawaban Anda menyebutkannya, mungkin bersama-sama dengan contoh singkat, sehingga dapat diterima. (perhatikan bahwa saya membuat komentar yang sama persis di jawaban lain)
sam hocevar
1

Semut membangun properti "asset.dir" bertanggung jawab untuk menyediakan direktori nama aset. Ini "aset" secara default, tetapi Anda dapat mengubahnya menjadi seperti "../asset". Ini mengubah jalur seluruh direktori, tetapi jika Anda memiliki sumber daya khusus Android, Anda masih dapat menggunakan direktori "res".

Krzysiek K.
sumber
1

Betapa aneh bahwa jawaban lain di sini tidak menjawab pertanyaan Anda ... mereka semua menganggap Anda hanya menginginkan satu direktori aset, atau merujuk ke res / bukannya aset /.

Saya juga memerlukan lebih dari satu direktori aset.

Saya berkelahi dengan <aapt>modul semut selama berjam-jam dan akhirnya menyerah dan menyadari ada cara yang jauh lebih mudah.

Saya menyalin <target name="-package-resources"...>tag dari file master build yang antmenggunakan,, android_sdk_dir/tools/ant/build.xmldan menempelkan tag ke proyek saya build.xml(Anda harus menempelkan tag tepat sebelum master build.xmldimasukkan, seperti komentar di akhir proyek yang dibuat sebelumnya build.xmlmenjelaskan), kemudian menambahkan bagian kedua untuk sekadar mengeks zipuntuk menambahkan aset ke file .ap_ (yang ${out.absolute.dir}/${resource.package.file.name}saat itu ada di file semut):

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

Metode ini memiliki keuntungan bahwa Anda lebih bebas untuk menentukan struktur direktori dari aset Anda di pohon sumber dan di apk (karena Anda dapat exec zipbeberapa kali dengan argumen yang berbeda, dan bahkan membungkus zipdalam skrip yang berjalan zipdari beberapa direktori saat ini di Anda pohon sumber). Anda juga memiliki kontrol kompresi per file (zip memiliki opsi -0 untuk menekan kompresi) dan tidak perlu menggunakan tag nocompress terbatas per ekstensi hanya.

Catatan antxml ini hadir SEBELUM zipalign dalam proses pembuatan semut, jadi kami masih mendapatkan arsip "kompatibel-zip" yang memenuhi kebutuhan pelurusan APK dan Android Java.

Dalam kasus saya, saya memiliki aplikasi berbasis NDK dan saya ingin mengakses aset ini hanya dari kode C (di mana setiap jalur apk OK). Jika Anda perlu menggunakan panggilan aset Java Android standar untuk mengakses item ini, saya tidak yakin apakah item tersebut harus berada di jalur di dalam zip yang bernama aset / atau tidak. Jika demikian, Anda dapat menyesuaikan trik di atas dengan execmemasukkan skrip yang cdke folder hierarki sumber yang relevan, kemudian jalankan zip.

Louis Semprini
sumber
0

Dari atas kepala saya, saya tidak berpikir Anda dapat menggunakan apa pun di luar res /, tetapi jika Anda ingin menghindari biaya tambahan untuk siklus dev Anda dengan salinan, Anda dapat mencoba memindahkannya atau bahkan mungkin menggunakan symlink ...

notlesh
sumber
Saya pasti tidak dapat memindahkan file karena beberapa di antaranya dibagikan di seluruh permainan dan perlu tetap berada di enginedirektori, yang berada dalam repositori terpisah. Symlinks mungkin dapat diterima tetapi saya tidak yakin mereka akan bekerja dengan baik pada Windows dan kemudian masih ada masalah dengan mereka disinkronkan secara otomatis oleh build.xml.
sam hocevar
2
@ Sam - Anda dapat meninggalkan file di repositori Anda, tetapi membuat langkah pra-kompilasi dalam kerangka kerja Anda (jelas file Ant build.xml) untuk menyalin file ke tempat-tempat yang diperlukan untuk proyek Android Anda. Ini adalah praktik umum ketika berbagi aset dalam game multi-platform. Lihat tugas salin Ant: ant.apache.org/manual/Tasks/copy.html
Anm
Meskipun skrip pra-kompilasi mungkin merupakan solusi yang paling mudah digunakan, alangkah baiknya jika jawaban Anda menyebutkannya, mungkin bersama-sama dengan contoh singkat, sehingga dapat diterima. (perhatikan bahwa saya membuat komentar yang sama persis di jawaban lain)
sam hocevar
0

Jika Anda menggunakan proyek Maven sebagai lawan dari proyek Ant, Anda dapat dengan mudah mendefinisikan kembali folder res menjadi apa pun yang Anda inginkan melalui opsi konfigurasi resourceDirectory android: apk mojo di plugin 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>

Sedihnya, kecuali jika Anda bersedia bermigrasi dari menggunakan Semut ke menggunakan Maven, jawaban ini mungkin tidak banyak membantu Anda ...

hatboyzero
sumber
0

Jika Anda menggunakan OS unix, Anda dapat menautkannya dengan keras, dan memberi tahu kontrol versi Anda untuk mengabaikannya res/ direktori.

o0 '.
sumber