我有一些当前在Activities上运行的代码,我正在使用一个主Activity和几个Frag来转换它。我的一个活动在onCreate()方法中运行GLSurfaceView。所以我将其修改为onCreateView。但问题是每当新的Fragment尝试启动时应用程序崩溃并且我收到以下错误:
E/GLSurfaceView: eglCreateWindowSurface
java.lang.IllegalArgumentException: Make sure the SurfaceView or associated SurfaceHolder has a valid Surface
at com.google.android.gles_jni.EGLImpl._eglCreateWindowSurface(Native Method)
at com.google.android.gles_jni.EGLImpl.eglCreateWindowSurface(EGLImpl.java:90)
at android.opengl.GLSurfaceView$DefaultWindowSurfaceFactory.createWindowSurface(GLSurfaceView.java:808)
at android.opengl.GLSurfaceView$EglHelper.createSurface(GLSurfaceView.java:1077)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1471)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
任何人都可以暗示我在转换为片段时遇到了什么问题吗?
这是我在主Activity中启动第一个Fragment的地方:
//Start the fragment
Fragment gameManager = new GameManager();
fragmentManager.beginTransaction()
.add(R.id.fragment_container,gameManager)
.addToBackStack(null)
.commit();
以下是GameManager的相关代码,它是一个片段: (1)空构造函数:
public GameManager(){
}
(2)onCreateView()代码:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
fa = (FragmentActivity) super.getActivity();
CatAndroidApp app = (CatAndroidApp) getActivity().getApplicationContext();
RelativeLayout frame = new RelativeLayout(getActivity());
TextureManager texture = app.getTextureManagerInstance();
if (texture == null) {
texture = new TextureManager(getResources());
app.setTextureManagerInstance(texture);
}
//changed constructor
view = new GameView(this,getActivity());
renderer = new GameRenderer(view);
view.setRenderer(renderer);
view.requestFocus();
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT, 1));
frame.addView(view);
boolean horizontal = getActivity().getResources().getDisplayMetrics().widthPixels < getActivity().getResources().getDisplayMetrics().heightPixels;
resources = new ResourceView(getActivity());
resources.setOrientation(horizontal ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
RelativeLayout.LayoutParams params;
if (horizontal)
params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
else
params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
params.addRule(horizontal ? RelativeLayout.ALIGN_PARENT_BOTTOM : RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
frame.addView(resources, params);
board = app.getBoardInstance();
turnHandler = new UpdateHandler();
return view;
}
最后,这是GameView的代码:
package com.catandroid.app.common.ui.views;
import javax.microedition.khronos.opengles.GL10;
import com.catandroid.app.common.components.BoardGeometry;
import com.catandroid.app.CatAndroidApp;
import com.catandroid.app.common.controllers.GameManager;
import com.catandroid.app.common.controllers.GameRenderer;
import com.catandroid.app.common.ui.TextureManager;
import com.catandroid.app.common.ui.resources.UIButton;
import com.catandroid.app.common.ui.resources.UIButton.Type;
import com.catandroid.app.common.players.Player;
import android.content.Context;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.os.Vibrator;
import android.view.MotionEvent;
import android.view.GestureDetector;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.View;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
public class GameView extends GLSurfaceView implements OnGestureListener,
OnDoubleTapListener, OnScaleGestureListener {
private int width, height;
private GameRenderer renderer;
private GestureDetector gesture;
private ScaleGestureDetector pinch;
private UIButton[] buttons;
private boolean buttonsPlaced = false;
private GameManager game;
public GameView(GameManager manager, Context context) {
super(context);
game = manager;
gesture = new GestureDetector(context, this);
pinch = new ScaleGestureDetector(context, this);
setSystemUiVisibility(getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LOW_PROFILE);
buttons = new UIButton[UIButton.Type.values().length];
int size = (int) (0.5 * BoardGeometry.BUTTON_SIZE * getResources().getDisplayMetrics().density);
for (UIButton.Type type : UIButton.Type.values())
buttons[type.ordinal()] = new UIButton(type, size, size);
buttonsPlaced = false;
}
@Override
public void setRenderer(Renderer renderer) {
super.setRenderer(renderer);
this.renderer = (GameRenderer) renderer;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
renderer.setSize(getContext().getResources().getDisplayMetrics(), width, height);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// handle touch events in GestureDetector
return gesture.onTouchEvent(event) || pinch.onTouchEvent(event);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distX, float distY) {
// ignore scrolling started over a button
for (UIButton button : buttons)
if (button.isPressed())
return false;
// shift the board
renderer.getGeometry().translate(distX, distY);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float vx, float vy) {
// throw out button press if scrolling over a button
release((int) e2.getX(), (int) e2.getY(), false);
// ignore flings
return false;
}
@Override
public boolean onDown(MotionEvent event) {
setSystemUiVisibility(getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LOW_PROFILE);
// press down (consider activating buttons)
press((int) event.getX(), (int) event.getY());
// always return true to allow gestures to register
return true;
}
@Override
public void onShowPress(MotionEvent event) {
// this is handled already in onDown
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
// handle in onSingleTapConfirmed
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
// button click
return release((int) event.getX(), (int) event.getY(), true);
}
@Override
public void onLongPress(MotionEvent event) {
// TODO: long press resource to trade for it
Vibrator vibrator = (Vibrator) getContext().getSystemService(
Context.VIBRATOR_SERVICE);
// consider buttons then a click on the board
if (release((int) event.getX(), (int) event.getY(), true) ||
click((int) event.getX(), (int) event.getY())) {
vibrator.vibrate(50);
} else {
vibrator.vibrate(20);
}
}
@Override
public boolean onDoubleTapEvent(MotionEvent event) {
// ignore intermediate events triggered in a double tap
return false;
}
@Override
public boolean onDoubleTap(MotionEvent event) {
// try to ignore double taps on a button
if (release((int) event.getX(), (int) event.getY(), false))
return true;
// double top zooms to point or zooms out
BoardGeometry boardGeometry = renderer.getGeometry();
boardGeometry.toggleZoom((int) event.getX(), (int) event.getY());
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
BoardGeometry boardGeometry = renderer.getGeometry();
boardGeometry.zoomBy(detector.getScaleFactor());
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void addButton(Type type) {
buttons[type.ordinal()].setEnabled(true);
buttonsPlaced = false;
}
public void removeButtons() {
for (UIButton button : buttons)
button.setEnabled(false);
}
public void placeButtons(int width, int height) {
if (buttonsPlaced)
return;
// first button is always in the top left corner
int x = 0;
int y = height;
for (UIButton button : buttons) {
if (!button.isEnabled())
continue;
int endwidth = width - button.getWidth() / 2;
int endheight = button.getHeight() / 2;
// set position
UIButton.Type type = button.getType();
if (type == UIButton.Type.CANCEL || type == UIButton.Type.ROLL
|| type == UIButton.Type.ENDTURN) {
// set position to far right/bottom
if (width < height)
button.setPosition(endwidth,
height - button.getHeight() / 2);
else
button.setPosition(button.getWidth() / 2, endheight);
} else {
// set to next available position
button.setPosition(x + button.getWidth() / 2,
y - button.getHeight() / 2);
// get next position
if (height >= width) {
// portrait
int size = button.getWidth();
x += size;
if (x + 1.5 * size > endwidth) {
x = 0;
y -= button.getHeight();
}
} else {
// landscape
int size = button.getHeight();
y -= size;
if (y - 1.5 * size < endheight) {
y = height;
x += button.getWidth();
}
}
}
}
buttonsPlaced = true;
}
public void drawButtons(TextureManager texture, GL10 gl) {
for (UIButton button : buttons) {
if (button.isEnabled())
texture.draw(button, gl);
}
}
private boolean click(int x, int y) {
Player player = CatAndroidApp.getInstance().getBoardInstance().getCurrentPlayer();
BoardGeometry boardGeometry = renderer.getGeometry();
GameRenderer.Action action = renderer.getAction();
if (!player.isHuman())
return false;
int select = -1;
switch (action) {
case NONE:
return false;
case ROBBER:
// select a hexagon
select = boardGeometry.getNearestHexagon(x, y);
break;
case TOWN:
case CITY:
// select a vertex
select = boardGeometry.getNearestVertex(x, y);
break;
case ROAD:
// select an edge
select = boardGeometry.getNearestEdge(x, y);
break;
}
if (select >= 0) {
game.select(action, select);
return true;
}
return false;
}
private boolean press(int x, int y) {
// consider buttons
for (UIButton button : buttons) {
if (button != null && button.press(x, height - y))
return true;
}
return false;
}
private boolean release(int x, int y, boolean activate) {
boolean released = false;
// consider buttons
for (UIButton button : buttons) {
if (button.release(x, height - y)) {
released = true;
if (activate)
game.buttonPress(button.getType());
}
}
return released;
}
}
答案 0 :(得分:0)
在活动中调用finish(),使其停止并移除曲面。删除finish()修复了问题。