Android游戏状态暂停时更改

时间:2015-03-13 02:20:29

标签: android surfaceview

以半传统方式,我有一个活动游戏(MainActivity),只有一个表面视图(MainSurface)。我设置了两个“游戏状态”,它们将自己渲染到表面视图画布(SplashState和ModelState)。

当应用程序启动时,表面视图将自己移到飞溅状态,以便它可以像这样将自己绘制到屏幕上。

SurfaceHolder holder = getHolder();
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                initInput();
                if(currentState == null){
                    setCurrentState(new SplashState());
                }
                initApp();
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int         width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                pauseApp();
            }
        });

private void pauseApp(){
        running = false;
        while(appThread.isAlive()){
            try{
                appThread.join();
                break;
            } catch (InterruptedException e){

            }
        }
    }

当用户触摸启动画面时,它会调用SurfaceView将状态更改为ModelState(这是应用程序的主要状态)

@Override
    public boolean onTouch(MotionEvent e, int scaledX, int scaledY) {
        setCurrentState(new ModelState());
        return false;
   }

所有这一切都很有效。但是,当我让我的设备睡眠,或使用其他应用程序然后打开我的应用程序,有时我得到ModelState,有时我得到SplashState。有谁能解释为什么?我觉得当应用程序暂停和恢复时,我应该做更多的事情来保存应用程序的当前状态,所以它肯定会重新开始在同一个位置。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

如果您只想保存用户看到的状态(模型或启动),您可以覆盖onPause和onResume来保存和检索状态。当应用程序进入后台时,OnPause和onResume是唯一保证被调用的两种方法,因此saveInstanceState和restoreInstanceState可能不适合你。

尝试使用SharedPreferences对象保存用户所处的状态。这是一个例子:

@Override
protected void onPause() {
    super.onPause();
    sharedPreferences = getSharedPreferences(KEY_SHARED_PREFERENCES, 0);
    SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();

    sharedPreferencesEditor.putString(STATE_KEY, currentState);
    sharedPreferencesEditor.commit();
}

@Override
protected void onResume() {
    super.onResume();

    sharedPreferences.getString(MODEL_KEY, null)
}

答案 1 :(得分:1)

行为的部分原因与SurfaceView的工作方式有关。它的生命周期与通常的Activity生命周期略有不同。

an appendix to the Graphics Architecture doc中讨论了这种现象。简而言之,系统试图避免破坏和重新创建表面。如果您旋转设备,您将获得暂停/恢复和销毁/创建。如果您只是让设备进入睡眠状态并将其唤醒,并且锁定屏幕不会强制进行旋转更改,您将获得暂停/恢复但不会破坏/创建。

诀窍在于以适合决斗生命周期的方式管理渲染线程和资源分配(特别是打开和关闭相机)。

  

有两种基本方法:(1)在Activity上启动/停止线程   启动/停止; (2)在Surface创建/销毁上启动/停止线程。

该文件继续解释每个方法的含义,以及何时必须采取其他行动。两种方法的例子都可以在Grafika中找到;来自相机的#34;纹理"活动使用#1,而"硬件缩放器训练器"活动使用#2。

回到你的代码,你从pauseApp()打电话给surfaceDestroyed()。由于无法保证表面会被销毁,因此当应用暂停时,您的pauseApp()代码可能无法运行。添加一些日志记录到各种状态更改函数,并在导航设备时在logcat中查看它们(或不激活)。