【发布时间】:2018-03-19 10:26:15
【问题描述】:
这个问题是在主题社区提出的,但答案是 没收到。首先,要解决问题。其次,我 认为进行交叉引用会很有用,这样人们 面临这个问题可以很快找到答案。 Question in the thematic community
libGDX 游戏在 Android 设备上的控制台中崩溃而没有任何错误。它发生在游戏的不同部分、不同的屏幕、不同的时间。我看不出原因。 游戏运行良好,没有冻结。游戏不会在更改屏幕等资源密集型操作下崩溃,但在加载屏幕并播放一段时间时已经崩溃。根据 RAM 的使用图表,内存的使用可能是正常的。 CPU 也没有过载。 最奇怪的是,当游戏崩溃时,控制台中没有显示错误。 手机屏幕变黑一会儿,然后系统在主屏幕上发出声音。手机也没有在应用程序中显示错误消息等。 此外,有时在显示 AdMob 视频后,游戏会停止响应输入,尽管图形继续工作,但动画仍在工作。
起初,我认为这可能是由于 AdMob 的实施不正确。但在项目中完全移除 AdMob 后,问题并没有消失。
那么什么会导致应用程序出现这种行为?
也许这是由于AssetManager 中的一些错误?我想指出,我使用了大量的纹理(超过 170 个),打包在一个图集中。 atlas 中的所有纹理占用 4.31MB 磁盘空间,而我的所有资源占用 6.2MB。 我在初始加载游戏期间使用 AssetManager 加载的所有资源。 p>
所以,我的 Res 课程:
public class Res {
public static final String LOCALE_BUNDLE_PATH = "i18n/locale";
public static final String MAIN_ATLAS_PATH = "packs/main/MAIN.atlas";
public static final String MUSIC_M3_THEME_PATH = "music/atc_m3_theme.mp3";
public static final String KICK_SOUND_PATH = "music/atc_kick.mp3";
public static final String FADEIN_SOUND_PATH = "music/atc_fadein.mp3";
public static final String DRAG_START_SOUND_PATH = "music/atc_drag_start.mp3";
public static final String DRAG_STOP_SOUND_PATH = "music/atc_drag_stop.mp3";
public static final String FONT_REGULAR_PATH = "fonts/comfortaa_regular.ttf";
public static final String FONT_LIGHT_PATH = "fonts/comfortaa_light.ttf";
public static final String RUSSO_ONE_REGULAR = "fonts/russo_one_regular.ttf";
public static TextureAtlas MAIN_ATLAS;
public static I18NBundle LOCALE;
/* MUSIC & SOUNDS */
public static Music M3_THEME;
public static Sound KICK_SOUND;
public static Sound FADE_IN_SOUND;
public static Sound DRAG_START_SOUND;
public static Sound DRAG_STOP_SOUND;
private Res () {
MAIN_ATLAS = null;
}
}
还有我的 ResManager:
public class ResManager extends AssetManager {
public void loadResources () {
load(Res.MAIN_ATLAS_PATH, TextureAtlas.class);
load(Res.MUSIC_M3_THEME_PATH, Music.class);
load(Res.KICK_SOUND_PATH, Sound.class);
load(Res.FADEIN_SOUND_PATH, Sound.class);
load(Res.DRAG_START_SOUND_PATH, Sound.class);
load(Res.DRAG_STOP_SOUND_PATH, Sound.class);
load(Res.LOCALE_BUNDLE_PATH, I18NBundle.class);
finishLoading();
Res.MAIN_ATLAS = get(Res.MAIN_ATLAS_PATH, TextureAtlas.class);
Res.M3_THEME = get(Res.MUSIC_M3_THEME_PATH, Music.class);
Res.KICK_SOUND = get(Res.KICK_SOUND_PATH, Sound.class);
Res.FADE_IN_SOUND = get(Res.FADEIN_SOUND_PATH, Sound.class);
Res.DRAG_START_SOUND = get(Res.DRAG_START_SOUND_PATH, Sound.class);
Res.DRAG_STOP_SOUND = get(Res.DRAG_STOP_SOUND_PATH, Sound.class);
Res.LOCALE = get(Res.LOCALE_BUNDLE_PATH, I18NBundle.class);
}
}
我知道在 Android 生态系统中做 TextureAtlas 静态是一个坏主意,但为了方便在代码中使用资源,必须这样做。此外,它仍然从内存中删除,因为我在应用程序关闭时杀死了进程。
@Override
protected void onDestroy() {
android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
}
另外,我正确处理了所有屏幕,显然将 GC 指向了他应该收集的不必要的对象。例如:
@Override
public void dispose() {
stage.dispose(); // Stage
loadingPane = null; // Group
multiplexer = null; // InputMultiplexer
firstScreen.destroy(); // Group
secondScreen.destroy(); // Group
firstScreen = null;
secondScreen = null;
bgSky = null; // Image
ground = null; // Image
dialogCircuit = null; // Group
dialogModule = null; // Group
dialogNotEnough = null; // Group
}
尝试在LeakCanary 的帮助下捕获内存泄漏。但它没有用。日志为空。
告诉我,可能是什么原因?一个非常烦人的问题,扼杀了我使用游戏的所有乐趣。
UPD: Logcat 日志(完整):logs。 游戏包名:net.dailytoys.afterthecrash(讽刺,我懂)
以下是崩溃前最后的日志,关于此应用程序(为方便起见,与完整日志分开):
03-19 17:18:05.198 811-907/? W/InputDispatcher: channel 'ec9957f net.dailytoys.afterthecrash/net.dailytoys.afterthecrash.AndroidLauncher (server)' ~ Consumer closed input channel or an error occurred. events=0x9
03-19 17:18:05.198 811-907/? E/InputDispatcher: channel 'ec9957f net.dailytoys.afterthecrash/net.dailytoys.afterthecrash.AndroidLauncher (server)' ~ Channel is unrecoverably broken and will be disposed!
03-19 17:18:05.213 811-1587/? I/WindowState: WIN DEATH: Window{ec9957f u0 net.dailytoys.afterthecrash/net.dailytoys.afterthecrash.AndroidLauncher}
03-19 17:18:05.217 811-1587/? W/InputDispatcher: Attempted to unregister already unregistered input channel 'ec9957f net.dailytoys.afterthecrash/net.dailytoys.afterthecrash.AndroidLauncher (server)'
03-19 17:18:05.223 811-1251/? I/ActivityManager: Process net.dailytoys.afterthecrash (pid 482) has died
03-19 17:18:05.257 811-1251/? W/ActivityManager: Force removing ActivityRecord{19f34039 u0 net.dailytoys.afterthecrash/.AndroidLauncher t3820}: app died, no saved state
03-19 17:18:05.258 811-1587/? W/WindowManager: Force-removing child win Window{19cfd5d7 u0 SurfaceView} from container Window{ec9957f u0 net.dailytoys.afterthecrash/net.dailytoys.afterthecrash.AndroidLauncher}
03-19 17:18:08.565 11009-11046/? D/IconCache: net.dailytoys.afterthecrash
03-19 17:18:08.566 11009-11046/? W/PackageManager: Failure retrieving resources for net.dailytoys.afterthecrash: Resource ID #0x0
03-19 17:18:09.454 11009-11009/? D/IconCache: net.dailytoys.afterthecrash
03-19 17:18:09.456 11009-11009/? W/PackageManager: Failure retrieving resources for net.dailytoys.afterthecrash: Resource ID #0x0
【问题讨论】:
-
您是否从 ADB 检查了您的游戏轨迹?不是游戏日志,来自安卓日志?
-
@AbdullahTellioglu 您的意思是禁用 logcat 中的过滤器以查看系统日志,而不仅仅是针对特定应用程序?现在我来做,好主意。
-
是的,这就是我的意思,您也可以使用 adb logcat > logcat.txt 将日志保存到文件中。我希望这也有帮助
-
@AbdullahTellioglu 好的,我在帖子中添加了 UPD。
-
仔细检查您是否没有过滤掉错误消息。如果没有任何错误消息,游戏不会崩溃...
标签: java android memory-leaks libgdx crash