Android OpenGL:睡眠后的疯狂长宽比

时间:2011-08-25 05:41:58

标签: android opengl-es

4 个答案:

答案 0 :(得分:6)

我现在正在处理这个问题,此时它出现是与SurfaceHolder.setFixedSize()相关的Android错误。

我要做的就是这样做:等待游戏加载,推动电源,让屏幕变为空白,再次推动电源(快速),解锁幻灯片(快速)。顺便说一句,这是关于HTC Thunderbolt 2.3.4的。

以下是正常的事件过程(不使用setFixedSize):

----- power button pushed ------
JavaMain: onPause: called, thread: 1
ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=1 layout=34 uiMode=17 seq=1509 skin=default}
JavaMain: onConfigurationChanged, orientation: 1 thread: 1
JavaMain: mSView(old): 800x480
JavaMain: surfaceChanged: width: 480, height:800, thread: 1
JavaMain: onWindowFocusChanged: called, thread: 1
(screen is now off)
------ power button pushed, and slide-lock undone -----
JavaMain: onResume: called, thread: 1
ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=1510 skin=default}
JavaMain: onConfigurationChanged, orientation: 2 thread: 1
JavaMain: mSView(old): 480x800
JavaMain: onWindowFocusChanged: called, thread: 1
JavaMain: surfaceChanged: width: 800, height:480, thread: 1
(back in game)

请注意,在onPause之后,我的表面视图将重做为纵向,而在onResume之后,它将更改回横向。我在清单中将screenOrientation设置为landscape。

现在看看在同一序列中发生了什么,但现在使用了SurfaceHolder.setFixedSize()(以降低分辨率):

----- power button pushed -------
JavaMain: onPause: called, thread: 1
ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=1 layout=34 uiMode=17 seq=1513 skin=default}
JavaMain: onConfigurationChanged, orientation: 1 thread: 1
JavaMain: mSView(old): 800x480
JavaMain: surfaceChanged: width: 640, height:384, thread: 1
JavaMain: onWindowFocusChanged: called, thread: 1
(screen is now off)
------ power button pushed, and slide-lock undone -----
JavaMain: onResume: called, thread: 1
ActivityManager: Config changed: { scale=1.0 imsi=310/12 loc=en_US touch=3 keys=1/1/2 nav=1/1 orien=2 layout=34 uiMode=17 seq=1514 skin=default}
JavaMain: onConfigurationChanged, orientation: 2 thread: 1
JavaMain: mSView(old): 480x800
JavaMain: onWindowFocusChanged: called, thread: 1
(back in game, with a messed up screen as in OP)

现在注意,在onPause之后,surfaceChanged反映了我指定的固定大小,但是在onResume上,表面视图是纵向(有点意外)。 但真正缺少的是使用我的固定大小参数调用surfaceChanged。在你问之前,onConfigurationChanged()中没有做.setFixedSize()没有任何效果。

更新和解决方案:

事实上,解决方案归结为恢复(实际上,从不允许任何更改)我的表面视图。这是通过在onConfigurationChanged中为您的活动进行超级调用后添加以下两行来实现的。 (Asumming你有以下清单设置集。)

android:configChanges="orientation"
android:screenOrientation="landscape"

这有效地防止了表面视图尺寸被设置为其他任何东西(例如肖像)。 顺便提一下,当我指定screenOrientation = landscape !!! 时,我想要的是什么(我在这里看着你,Google)

public void onConfigurationChanged(Configuration newConfig) {       
    super.onConfigurationChanged(newConfig);

    // -- stomp any attempts by the OS to resize my view.
    // -- Hardcoded values for illustration only. In real life
    // -- you'll need to save these when the surface view is originally created
    mSView.getLayoutParams().width = 800;
    mSView.getLayoutParams().height = 480;
}

答案 1 :(得分:1)

你需要调用gl.glViewport(0,0,width,height);或类似于GL10.Renderer的onSurfaceChanged方法。我的假设是当设备从睡眠状态唤醒时,某些东西必须改变视口,但是当您的应用首次启动时,视口会为您初始化,这就是为什么它在您睡觉之前正常工作。

答案 2 :(得分:0)

答案 3 :(得分:0)

您需要执行以下三个步骤:

  1. AndroidManifest.xml - android:configChanges="keyboard|keyboardHidden|screenSize|orientation"
  2. 您的活动使用布局FrameLayout
  3. 在java代码中

    public void onSurfaceChanged(GL10 gl,int w,int h){ //你需要测试w> h然后才进行图形初始化 ... }