我在我制作的应用中遇到了这个问题。这是一个简单的游戏,我使用onCreate
方法从Room数据库中加载数据,将加载的数据保存在List<GameData> gameData
中,然后启动游戏。
gameDao.getAll()
.subscribe(gameDatas -> {
gameData.addAll(gameDatas);
startGame();
});
在
startGame
中,我随机选择[0, gameData.size()]
范围内的数字,并使用相应的gameData
做一些游戏相关的工作。public void startGame(){
Random random = new Random();
int randomNumber = random.nextInt(gameData.size());
// do something with gameData[ramdomNumber]
}
所以,然后用户继续玩,然后当用户迷路时,我用
GameOverActivity
将他发送给startActivityForResult(gameOver,1123)
里面的
GameOverActivity
用户可以因此,当用户按下重新启动按钮时,我只需完成
GameOverActivity
即可将我重定向到onActivityResult
的GameActivity
。在这里,我只是再次调用startGame
方法,并且应该可以启动一个新游戏。现在问题有时出在某些设备上,
gameData
变空,因此当我调用startGame
时,random.nextInt(gameData.size())
内出现异常java.lang.RuntimeException:
at android.app.ActivityThread.performResumeActivity (ActivityThread.java:3790)
at android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3830)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3038)
at android.app.ActivityThread.-wrap11 (Unknown Source)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1696)
at android.os.Handler.dispatchMessage (Handler.java:105)
at android.os.Looper.loop (Looper.java:164)
at android.app.ActivityThread.main (ActivityThread.java:6944)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)
Caused by: java.lang.RuntimeException:
at android.app.ActivityThread.deliverResults (ActivityThread.java:4491)
at android.app.ActivityThread.performResumeActivity (ActivityThread.java:3762)
Caused by: java.lang.IllegalArgumentException:
at java.util.Random.nextInt (Random.java:388)
at com.company.game.GameActivity.startGame (GameActivity.java:149)
at com.company.game.GameActivity.onActivityResult (GameActivity.java:477)
at android.app.Activity.dispatchActivityResult (Activity.java:7556)
at android.app.ActivityThread.deliverResults (ActivityThread.java:4487)
我没有低估为什么
gameData
会被清除,而且我无法检查,因为我在测试时从未遇到过,并且从PlayConsole获得了崩溃报告。知道是什么原因造成的吗? 最佳答案
我怀疑操作系统由于内存需求而销毁GamaActivity并为onActivityResult重新创建它时会发生问题。这是正常的Android Activity 生命周期的一部分。现在,当发生这种情况时,gameData
将为null,并调用inCreate进行初始化。 onCreate
将再次调用Room函数来填充gameData
,但是由于Room是异步的,因此它将在填充gameData
之前让onCreate完成。届时,将调用onActivityResult
,并且由于Room代码尚未完成,因此gameData
可能仍为空,因此应用程序崩溃。
解决此问题的正确方法是将gameData
移出Activity
类,然后移至Application
类。这就是它所属的位置,因为数据应该绑定(bind)到应用程序,而不是 Activity 。您将必须扩展Application类,并在Application的onCreate中初始化Room数据。只是谷歌“扩展Android应用程序类”的具体说明。这样,数据将在应用程序的生命周期内是安全的。