其他分享
首页 > 其他分享> > android – 如何保留具有GLSurfaceView的活动的状态

android – 如何保留具有GLSurfaceView的活动的状态

作者:互联网

我的问题是我们的游戏可以立即切换到菜单和设置模式但是需要4-6秒来加载纹理,init GL渲染模式最终我只使用6个简单的纹理在游戏中创建6个精灵.

请帮我回答两个问题:
1.如何在android os中预加载我们的资产以更快地启动我们的游戏?
2.为了使用技巧在活动之间创建实例切换,如何使用GLSurfaceView状态保留我的活动?

我是为了帮助您了解我的情况,请阅读以下代码:

您可以在以下配置中看到使用3种活动的游戏:

 <application android:label="@string/app_name"
  android:icon="@drawable/icon" android:allowBackup="true">
  <activity android:name=".Menu" android:screenOrientation="portrait" 
  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
  android:launchMode="singleTop">
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>

  </activity>
  <activity android:name=".ReTouch" android:screenOrientation="portrait" />

  <activity android:name=".Preference" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />

 </application>

我的.ReTouch类是从RokonActivity扩展的类(我在游戏中使用rokon引擎),这个引擎将创建一个GLSurefaceView来在OpenGL ES中渲染我的游戏
你可以在这里获得RokonAcitivity的源代码:http://code.google.com/p/rokon/source/browse/tags/release/1.1.1/src/com/stickycoding/Rokon/RokonActivity.java

 public class ReTouch extends RokonActivity {
 public static final int REPLAY_DELAY_INTERVAL = 1000;
 private ReTouchGameBoard reTouchGame;

和.Menu,.Preference是Android应用程序中的两个正常标准活动.

我正在使用此方法来启动和切换活动:

  playButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    soundPool.play(soundId, 1, 1, 1, 0, 1);
    startActivity(new Intent(Menu.this, ReTouch.class));
   }
  });
  settingButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    soundPool.play(soundId, 1, 1, 1, 0, 1);
    startActivity(new Intent(Menu.this, Preference.class));
   }
  });
  quitButton.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    soundPool.play(soundId, 1, 1, 1, 0, 1);
    finish();
   }
  });

解决方法:

我避免了这个问题,而不是为我的游戏解决它:

我使用’FrameLayout’作为主要布局,其中’GLSurfaceView’作为其中的第一个布局(即在堆栈的底部),接下来是’菜单’视图组,以及一个不透明的’加载’屏幕顶部(设置为match_parent以填充屏幕):

<FrameLayout 
    android:id="@+id/graphics_frameLayout1" 
    android:layout_width="fill_parent" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="fill_parent">
    <android.opengl.GLSurfaceView 
        android:id="@+id/graphics_glsurfaceview1" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent">
    </android.opengl.GLSurfaceView>
    <LinearLayout
        android:id="@+id/menu_linearLayout1"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:visiblility="gone"
        android:background="#000000">// opaque background
        // menus etc be here
    </LinearLayout>
    <LinearLayout       
        android:layout_height="fill_parent" 
        android:id="@+id/loading_linearLayout1" 
        android:layout_width="fill_parent" 
        android:orientation="vertical"
        android:background="#000000">// opaque background
        <ProgressBar 
            style="?android:attr/progressBarStyleLarge" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:id="@+id/loading_progressBar1">
        </ProgressBar>
        <TextView 
            android:layout_width="wrap_content" 
            android:id="@+id/loading_textView1" 
            android:layout_height="wrap_content" 
            android:text="Loading...">
        </TextView>
    </LinearLayout>
</FrameLayout>

加载完成后,我将加载视图组设置为不可见或消失,并将菜单视图组设置为可见.一旦用户选择了启动游戏的选项,我就会启动游戏逻辑线程并再次使菜单消失

我有一个活动层次结构(ReTouchMenuActivity扩展了ReTouchActivity,然后在一个新文件中,ReTouchActivity扩展了RokonActivity),这样我就不会将整个游戏放在一个无法管理的单个文件中

我在单独的线程中加载其他资源(例如,3D模型的顶点数据),然后在绘制数组之前加载顶点,纹理坐标等(即gl.glVertexPointer(3,GL10.GL_FLOAT,0,meshVertices);

真正的问题是你必须在GL线程中加载纹理,它可以阻止UI线程(虽然没有崩溃),导致在加载大纹理时没有对用户输入的响应.我自己在运行Android 2.1的中兴刀片上使用上述游戏可能需要两秒钟来加载一些大纹理(1mb)甚至圆形进度条在这段时间内停止旋转.

当用户点击退出按钮时,我注意到你完成了()活动,但当用户离开应用程序时没有点击退出按钮(比如当他们接到来电或从通知栏中选择某些内容时),活动/应用程序仍然在后台运行.当他们将活动/应用程序带回堆栈顶部时(即用户重新打开它),您必须重新加载纹理.如果在这种情况下不重新加载纹理,则用户只需加载空白而不是纹理

如果您尝试将GL传递给Renderer类’onDraw方法的GL句柄/对象保存为变量,例如由纹理加载线程使用,那么在onDraw方法返回并且纹理加载失败后它就会脱离上下文.

我假设是因为当用户离开应用程序时,android会擦除所有图形数据/ openGL状态,以防其他应用程序想要使用它.因此我假设你不能完全按照你的目标去做(在android os或其他任何方面预加载纹理).虽然如果其他人知道的更好,我会有兴趣听到.

编辑:

This question有一些关于加快纹理实际加载时间的好答案

标签:android,glsurfaceview
来源: https://codeday.me/bug/20190710/1422534.html