我在我制作的应用中遇到了这个问题。这是一个简单的游戏,我使用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即可将我重定向到onActivityResultGameActivity。在这里,我只是再次调用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应用程序类”的具体说明。这样,数据将在应用程序的生命周期内是安全的。

    09-04 06:58