我正在为Android制作一款游戏,当我退出游戏并重新启动时,我的线程遇到了一些问题 . 我正在尝试中断MainActivity中onPause函数中的线程,并使用notify在gamepanel中的start函数中恢复线程 . 它有时可行,但它并没有真正暂停游戏 .
What is the proper way to implement the activity lifecycle while pausing a thread? 特别是一个游戏线程,在用户离开时不应该调用游戏更新功能 .
public class MainActivity extends Activity {
private GamePanel gamepanel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//removes title
requestWindowFeature(Window.FEATURE_NO_TITLE);
//full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
gamepanel = new GamePanel(this);
setContentView(gamepanel);
SoundHandler.setContext(this);
}
@Override
protected void onPause() {
super.onPause();
gamepanel.getThread().interrupt();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onRestart() {
super.onRestart();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
boolean retry = true;
while (retry) {
try {
gamepanel.getThread().setRunning(false);
gamepanel.getThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
retry = false;
}
}
}
扩展surfaceView的Gamepanel:
@Override
public void surfaceDestroyed (SurfaceHolder holder){}
/**create surface.
*
* @param holder
*/
@Override
public void surfaceCreated (SurfaceHolder holder){
//we can safely start the game loop
System.out.println("CREATING SURFACE");
loadingscreen = false;
start();
}
public void start() {
if(!mGameIsRunning) {
thread.start();
thread.setRunning(true);
mGameIsRunning = true;
} else {
thread.onResume();
}
}
线程类
public class MainThread extends Thread {
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
public boolean running = false;
public static Canvas canvas;
private long startTime;
private long fps = 1/30;
public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel) {
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
startTime = System.nanoTime();
}
@Override
public void run()
{
while(running) {
if((System.nanoTime() - startTime) / 1000000000> fps) {
canvas = null;
//try locking the canvas for pixel editing
try {
canvas = surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
this.gamePanel.update();
this.gamePanel.draw(canvas);
this.gamePanel.checkSpeed();
}
} catch (Exception e) {
} finally {
if (canvas != null) {
try {
surfaceHolder.unlockCanvasAndPost(canvas);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
gamePanel.surfaceDestroyed(surfaceHolder);
}
public void onResume(){
synchronized(this){
this.notify();
}
}
public void setRunning(boolean b)
{
running=b;
}
public boolean getRunning(){
return running;
}
}
1 回答
boolean running
周围没有记忆障碍你可以synchronize
或使用private volatile boolean running;
. 然后你需要在某个地方调用setRunning(false)
来阻止它,你似乎没有 . 这些原因可能就是你的线程没有放弃的原因 .但我认为无论如何将游戏渲染到一个单独的线程中都没有任何意义 . 如果无论如何都无法更新和渲染超快(例如1/60秒或更好),那么将其移动到线程将无济于事 .