【问题标题】:My game freezes/crashes after back or menu button is pressed按下返回或菜单按钮后我的游戏冻结/崩溃
【发布时间】:2018-05-27 14:12:32
【问题描述】:

我正在开发一款安卓游戏,但我遇到了一个奇怪的问题。每次我按下返回/菜单/任务按钮并尝试返回游戏时,游戏都会冻结(无响应(等待/关闭))。我什至添加了 onPause、onResume、onStop 功能,但问题仍然存在。 我的代码可能有问题,这是我的 MainActivitiy。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);

    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    Constants.SCREEN_WIDTH = dm.widthPixels;
    Constants.SCREEN_HEIGHT = dm.heightPixels;
    setContentView(new GamePanel(this));

    String a = getApplicationInfo().dataDir;
    GamePlayScene.filePath = a;
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
    super.onSaveInstanceState(savedInstanceState);
}

@Override
public void onPause(){
super.onPause();
}

@Override
public void onResume(){
    super.onResume();
}
@Override
public void onStart(){
    super.onStart();
}
@Override
public void onStop(){
    super.onStop();
}

这是我的主线程

public class MainThread extends Thread{
public static final int MAX_FPS = 30;
private double avarageFPS;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
private boolean running;
public static Canvas canvas;

public void setRunning(boolean running){
    this.running = running;
}
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel){
    super();
    this.surfaceHolder = surfaceHolder;
    this.gamePanel = gamePanel;
}
@Override
public void run() {
    long startTime;
    long timeMillis = 1000 / MAX_FPS;
    long waitTime;
    long frameCount = 0;
    long totalTime = 0;
    long targetTime = 1000 / MAX_FPS;

    while (running) {
        startTime = System.nanoTime();
        canvas = null;
        try {
            canvas = this.surfaceHolder.lockCanvas();
            synchronized (surfaceHolder) {
                this.gamePanel.update();
                this.gamePanel.draw(canvas);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (canvas != null) {
                try {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        timeMillis = (System.nanoTime() - startTime) / 1000000;
        waitTime = targetTime = timeMillis;
        try {
            if (waitTime > 0) {
                this.sleep(waitTime);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        totalTime += System.nanoTime() - startTime;
        frameCount++;
        if (frameCount == MAX_FPS) {
            avarageFPS = 1000 / ((totalTime / frameCount) / 1000000);
            frameCount = 0;
            totalTime = 0;
            System.out.println(avarageFPS);
        }
    }
}

在游戏开始时我得到了这个,但这不会导致游戏出现任何问题:

12-14 00:19:41.967 6778-6778/com.apps.lazy.rainbowjet E/OpenGLRenderer: Getting MAX_TEXTURE_SIZE from GradienCache 12-14 00:19:41.967 6778-6778/com.apps.lazy.rainbowjet E/OpenGLRenderer: MAX_TEXTURE_SIZE: 16384 12-14 00:19:41.971 6778-6778/com.apps.lazy.rainbowjet E/OpenGLRenderer: Getting MAX_TEXTURE_SIZE from Caches::initConstraints() 12-14 00:19:41.971 6778-6778/com.apps.lazy.rainbowjet E/OpenGLRenderer: MAX_TEXTURE_SIZE: 16384

在我按下任何按钮并返回游戏后,我得到了这个:

12-14 00:26:17.174 12130-12163/com.apps.lazy.rainbowjet W/System.err: at android.view.SurfaceView.dispatchDraw(SurfaceView.java:343) 12-14 00:26:17.174 12130-12163/com.apps.lazy.rainbowjet W/System.err: at android.view.View.draw(View.java:14468) 12-14 00:26:17.174 12130-12163/com.apps.lazy.rainbowjet W/System.err: at android.view.SurfaceView.draw(SurfaceView.java:334) 12-14 00:26:17.174 12130-12163/com.apps.lazy.rainbowjet W/System.err: at com.apps.lazy.rainbowjet.GamePanel.draw(GamePanel.java:66) 12-14 00:26:17.174 12130-12163/com.apps.lazy.rainbowjet W/System.err: at com.apps.lazy.rainbowjet.MainThread.run(MainThread.java:43)

这是游戏面板

public class GamePanel extends SurfaceView implements SurfaceHolder.Callback 
{
private MainThread thread;

private SceneManager manager;
private boolean isRunning = true;

public GamePanel(Context context){
    super(context);


    getHolder().addCallback(this);
    Constants.CURRENT_CONTEXT = context;
    thread = new MainThread(getHolder(), this);
    manager = new SceneManager();
    setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){
}

@Override
public void surfaceCreated(SurfaceHolder holder){
    thread = new MainThread(getHolder(), this);
    thread.setRunning(true);
    thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder){
    boolean retry = true;
    while(true){
        try{
            thread.setRunning(false);
            thread.join();
        }catch(Exception e) {e.printStackTrace();}
        retry = false;
        }
    }

@Override
public boolean onTouchEvent(MotionEvent event) {
    manager.recieveTouch(event);
            return true;
        //return super.onTouchEvent(event);
}

public void update(){
manager.update();
}

@Override
public void draw(Canvas canvas){
    super.draw(canvas);
    manager.draw(canvas);
}
}

【问题讨论】:

  • 这样做的简单原因是您在主线程上进行了大量计算,或者您正在泄漏内存。查看您的日志并发布它们

标签: java android button android-activity


【解决方案1】:

好的,首先,你添加了onPauseonResumeonStop,但是你所做的一切都是调用super函数,所以基本上覆盖是没有用的。在这些函数中,您必须调用 super 并实际执行其他操作。

其次,如果是后退菜单的问题,你应该在onBackPressed函数中处理它。

在你的 MainActivity 中试试这个:

@Override
public void onBackPressed() {
    MainThread myThread = getMainThread();
    myThread.setRunning(false);
    super.onBackPressed();
}

getMainThread() 在哪里检索您的线程在活动中的引用(无论它在哪里)

【讨论】:

  • 在这一行 MainThread myThread = getMainThread(); getMainThread(): 方法未找到,因为 MainThread 是一个类,我无法在其中创建 getter,因为我无法返回该类本身,顺便说一句,它不仅带有后退按钮,每当我离开游戏并尝试返回时,它都带有每个按钮它,它冻结或很少崩溃
  • 请问MainThread是你写的一个类吗?它在哪里引用?它是否在活动中的某处声明?您如何启动该线程?我想那不是Android's MainThread
  • 对不起,如果我不清楚,但getMainThread() 是我刚刚编的一个名字。我想在您的活动中,您有一些方法或全局变量来获取该 MainThread 实例。
  • GamePanel 在哪里?是被Activity调用的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多