使用LibGDX集成ObjectBox时重复打开BoxStore崩溃问题求助
解决ObjectBox与LibGDX结合时的"Another BoxStore is still open"崩溃问题
这个问题的核心是Android应用生命周期与LibGDX的ApplicationListener生命周期不一致导致的:当你按Home键退到后台时,Android不会立即销毁应用进程,之前创建的BoxStore实例(尤其是通过静态引用持有的)会保留在内存中;当你重新打开应用时,LibGDX会重新初始化你的ApplicationListener,再次执行创建BoxStore的代码,此时旧的实例还处于打开状态,就会触发冲突报错。
下面是具体的解决方案:
1. 用单例模式全局管理BoxStore实例
BoxStore设计为每个数据库目录对应一个实例,所以我们可以封装一个单例类来确保全局只有一个BoxStore实例,并且每次获取前检查其状态:
public class ObjectBoxManager { private static BoxStore sBoxStore; // 获取全局唯一的BoxStore实例 public static BoxStore getInstance() { if (sBoxStore == null || sBoxStore.isClosed()) { // 初始化目录(你的原有逻辑) FileHandle dbDir = Gdx.files.local("objectstorefile"); if (!dbDir.isDirectory()) { dbDir.mkdirs(); } // 创建新的BoxStore实例 sBoxStore = MyObjectBox.builder().directory(dbDir.file()).build(); } return sBoxStore; } // 安全关闭BoxStore public static void closeStore() { if (sBoxStore != null && !sBoxStore.isClosed()) { sBoxStore.close(); sBoxStore = null; // 置空确保下次能重新创建 } } }
之后在你的LibGDX代码中,不再手动创建BoxStore,而是通过ObjectBoxManager.getInstance()获取实例即可。
2. 结合Android生命周期关闭BoxStore
因为LibGDX的pause()回调只是应用退到后台的通知(此时应用可能还会被重新唤醒),我们需要在应用真正销毁时关闭BoxStore。在你的LibGDX Android启动Activity(通常是AndroidLauncher)中,重写onDestroy()方法:
public class AndroidLauncher extends AndroidApplication { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initialize(new YourGameApplicationListener()); } @Override protected void onDestroy() { super.onDestroy(); // 应用销毁时关闭BoxStore ObjectBoxManager.closeStore(); } }
这样当Android系统销毁你的Activity时,会确保BoxStore被正确关闭,避免残留实例导致下次启动冲突。
3. 额外注意事项
- 不要在LibGDX的
create()方法中重复创建BoxStore,始终通过单例获取,确保每次进入应用时都检查实例状态。 - 避免在LibGDX的
pause()中关闭BoxStore:退到后台时应用可能只是暂停,后续还会恢复,频繁关闭/重建会影响性能。 - 如果你的LibGDX应用支持多平台(比如桌面、iOS),可以在单例中针对不同平台做初始化适配,保持逻辑统一。
内容的提问来源于stack exchange,提问作者Russ Wheeler
相关产品推荐
相关产品推荐

