Ich arbeite an einem Spiel für Android mit Android Studio mit LibGDX in Java. Ich habe kürzlich ein seltsames Problem beim Schließen und erneuten Öffnen des Spiels festgestellt. Wenn ich das Spiel zum ersten Mal öffne, funktioniert es einwandfrei. Wenn ich auf die Schaltfläche BEENDEN klicke und die App schließe, verfügt der Vermögensverwalter darüber. Wenn ich das Spiel erneut öffne, werden einige der Atlasregionen als schwarze Rechtecke in derselben Größe der Region angezeigt. Mir ist aufgefallen, dass dies nur passiert, wenn ich die Entsorgungsmethode des Vermögensverwalters aufrufe. Wenn ich es entferne, tritt das Problem nicht auf. Es ist lustig, aber das Spiel scheint gut zu funktionieren, wenn man diese Methode nicht aufruft, aber ich habe gelesen, dass es empfohlen wird, sie zu entsorgen. Dies ist meine AssetsManager-Klasse:
public final class AssetManagerWrapper extends AssetManager {
ArrayMap<String, FileHandle> configs = new ArrayMap<String, FileHandle>();
public Texture lightTexture;
public Texture alarmTexture;
public TextureAtlas particlesAtlas;
public final void loadGFX() {
FileHandle dirHandle;
dirHandle = Gdx.files.internal(Rules.System.GFX.GFX_FOLDER_NAME);
FileHandle subDirHandle;
for (FileHandle dir : dirHandle.list()) {
subDirHandle = Gdx.files.internal(dir.path());
if (dir.name().equalsIgnoreCase(AssetsPaths.Gfx.Sheets.SHEETS_FOLDER_NAME)) {
for (FileHandle file : subDirHandle.list()) {
if (file.extension().equalsIgnoreCase(Rules.System.GFX.SHEETS_DATA_EXTENSION)) {
load(file.path(), TextureAtlas.class);
}
}
} else {
for (FileHandle file : subDirHandle.list()) {
load(file.path(), Texture.class);
}
}
}
}
public final void loadSounds() {
FileHandle dirHandle;
dirHandle = Gdx.files.internal(Rules.System.SFX.SFX_FOLDER_NAME);
FileHandle subDirHandle;
for (FileHandle dir : dirHandle.list()) {
subDirHandle = Gdx.files.internal(dir.path());
if (dir.name().equalsIgnoreCase(Rules.System.SFX.SOUNDS_FOLDER_NAME)) {
for (FileHandle file : subDirHandle.list()) {
if (file.extension().equalsIgnoreCase(Rules.System.SFX.SOUNDS_DATA_EXTENSION)) {
load(file.path(), Sound.class);
}
}
}
}
}
public void loadParticlesConfigs() {
FileHandle dirHandle;
dirHandle = Gdx.files.internal(AssetsPaths.Configs.CONFIGS_FOLDER_NAME + '/' + AssetsPaths.Configs.PARTICLE_CONFIGS_FOLDER_NAME);
for (FileHandle file : dirHandle.list()) {
if (file.extension().equalsIgnoreCase(Rules.System.GFX.PARTICLE_CONFIGS_DATA_EXTENSION)) {
configs.put(file.nameWithoutExtension(), file);
}
}
}
public final void loadMusic() {
FileHandle dirHandle;
dirHandle = Gdx.files.internal(Rules.System.SFX.SFX_FOLDER_NAME);
FileHandle subDirHandle;
for (FileHandle dir : dirHandle.list()) {
subDirHandle = Gdx.files.internal(dir.path());
if (dir.name().equalsIgnoreCase(Rules.System.SFX.MUSIC_FOLDER_NAME)) {
for (FileHandle file : subDirHandle.list()) {
if (file.extension().equalsIgnoreCase(Rules.System.SFX.MUSIC_DATA_EXTENSION)) {
load(file.path(), Music.class);
}
}
}
}
}
public void loadData() {
loadGFX();
loadSounds();
loadMusic();
loadParticlesConfigs();
finishLoading();
}
@Override
public void finishLoading() {
super.finishLoading();
lightTexture = get(AssetsPaths.Gfx.Other.LIGHT);
alarmTexture = get(AssetsPaths.Gfx.Menu.ALARM);
particlesAtlas = get(AssetsPaths.Gfx.Sheets.Misc.PARTICLES_DATA_FILE);
}
public ArrayMap<String, FileHandle> getConfigs() {
return configs;
}
}
Der Lebenszyklus (Hauptklasse, die Application Listener implementiert):
@Override
public void create() {
assetsManager = new AssetManagerWrapper();
assetsManager.loadData();
soundPlayer = new SoundPlayer(this);
Gdx.input.setCatchBackKey(true);
goToMenu();
}
@Override
public void resume() {
assetsManager.finishLoading();
}
@Override
public void dispose() {
assetsManager.dispose(); //For some reason this creates the black rectangles bug.
soundPlayer.dispose();
if (warScreen != null) {
warScreen.dispose();
}
menuScreen.dispose();
}
Hat jemand eine Idee, was es verursachen könnte? Ist das in Ordnung, dass ich den Aufruf dieser Methode einfach entferne? Danke im Voraus.
quelle
AssetManagerWrapper
Klasse? Wer ruft anloadData
und wann und wer ruft andispose
und wann?Antworten:
Gemäß diesem Abschnitt auf der AssetManager-Seite. Wenn Android pausiert, werden die verwalteten libgdx-Elemente wie Textures bereinigt und müssen neu geladen werden, wenn die App fortgesetzt wird. Dazu rufen Sie
Texture.setAssetManager(manager);
den Asset Manager auf und rufen dann die Aktualisierung auf, wie Sie es beim ersten Laden getan haben.Zweitens können Android-Apps nicht garantieren, dass sie beim Beenden wirklich nicht mehr ausgeführt werden. Android ist derjenige, der wählt, wenn eine App im Hintergrund bereinigt wird. Obwohl Sie "Beenden" ausgewählt haben, wurde Ihre App möglicherweise noch ausgeführt und die Texturen mussten erneut geladen werden.
quelle
Hatte gerade das gleiche Problem. Das Problem war, dass ich einige Texturbereiche als statische Felder hatte. Und um zu vermeiden, dass Texturbereiche für jedes Objekt immer wieder gefunden werden, habe ich eine zusätzliche statische Variable "intitialisiert" hinzugefügt, sodass ich Bereiche nur für das zuerst generierte Objekt gefunden habe, diese Variable für "wahr" festgelegt habe und alle anderen Bereiche übersprungen haben. Das funktioniert gut, wenn ich das Spiel zum ersten Mal starte. Aber wenn ich die App beende und erneut starte und sie im Telefonspeicher verbleibt, behält diese statische "initialisierte" Variable auch ihren Wert bei, was bedeutet, dass Suchregionen nicht erneut aufgerufen wurden. Und alte Regionen existierten, aber ihr Gedächtnis war geleert, so dass ich beim Zeichnen nur schwarze Rechtecke für sie bekam.
Gelöst durch erneutes Aufrufen von findRegion ().
quelle