我在这个论坛上一遍又一遍地搜索过谷歌关于这个问题,也许它必须与我的线程或游戏如何开始的方式做一些事情。
这是游戏应用程序的骨架,请告诉我我做错了什么。
这就是我在线程中所做的事情;
public class GameThread extends Thread
{
static final long FPS = 30;
private GameView view;
private boolean running = false;
private SurfaceHolder surfaceHolder;
public boolean isSurfaceCreated = false;
private Object mPauseLock;
private boolean mPaused;
public GameThread(SurfaceHolder surfaceHolder, Handler handler, GameView view)
{
super();
mPauseLock = new Object();
mPaused = false;
this.surfaceHolder = surfaceHolder;
this.view = view;
}
public void setRunning(boolean run)
{
running = run;
}
/**
* pause thread.
*/
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
/**
* resume thread.
*/
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
@Override
public void run()
{
// run our thread on high priority to keep from getting slowdown
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
// wait for surface to become available @ start
while (!isSurfaceCreated && running)
{
try {
sleep(50);
} catch (InterruptedException e) {}
}
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running){
Canvas c = null;
startTime = System.currentTimeMillis();
//long msSinceLastTick = System.currentTimeMillis() - view.lastTickMs;
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder)
{
/*
* stop updating when pause is pressed
*/
if(mPaused == false)
{
view.update();
}
view.onDraw(c);
}
} finally {
if (c != null)
{
surfaceHolder.unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {}
}
}
这是开始活动代码;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
public class test_game extends Activity {
/** Called when the activity is first created. */
private GameView Game;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Game = new GameView(this);
setContentView(Game);
}
@Override
public void onBackPressed()
{
super.onBackPressed();
//KILL ALL
finish();
System.runFinalizersOnExit(true);
System.exit(0);
}
// ===========================================================
// onPause
// ===========================================================
protected void onPause() {
super.onPause();
}
// ===========================================================
// onStop
// ===========================================================
protected void onStop() {
super.onStop();
}
// ===========================================================
// onDestroy
// ===========================================================
@Override
protected void onDestroy() {
super.onDestroy();
}
}
在AndroidManifest.xml中添加了额外的行
android:launchMode="singleTask"
android:alwaysRetainTaskState="true"
GameView看起来像这样;
public class GameView extends SurfaceView {
private SurfaceHolder holder;
private GameThread Thread = null;
private int testVar = 0;
private boolean isPaused = false;
public GameView(Context context)
{
super(context);
loadGameFiles();
holder = getHolder();
Thread = new GameThread(holder, new Handler(), this);
holder.addCallback(new SurfaceHolder.Callback()
{
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
Thread.setRunning(false);
while (retry)
{
try {
Thread.join();
retry = false;
} catch (InterruptedException e)
{
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
Thread.isSurfaceCreated = true;
if(isPaused == true)
{
onResume();
}
Thread.setRunning(true);
Thread.start();
GameMenu();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
});
setFocusable(true);
}
public boolean isPaused()
{
return this.isPaused;
}
/**
* Pauses the physics update & animation.
*/
public void onPause() {
synchronized (holder)
{
if(isPaused == false)
{
isPaused = true;
Thread.onPause();
}
}
}
public void onResume()
{
synchronized (holder)
{
if(isPaused == true)
{
isPaused = false;
Thread.onResume();
}
}
}
etc..
大家好,感谢您的回复,论坛评论框不允许我发布这个;无论如何,这是:
嗨弗兰肯斯坦,我已经尝试了你在这里提出的建议,但仍然行不通。 GameView中的恢复代码如下所示;
public void onResume(){ synchronized (holder)
{ if(isPaused == true){
isPaused = false; //resume notification to the gameview
Thread.onResume(); //resume the thread
}
}
}
This is on the Activity class;
@Override
protected void onPause() {
super.onPause();
Game.onPause();
}
@Override
protected void onResume() {
super.onResume();
Game.onResume();
}
我没有使用过logcat,不知道如何使用它,我可以肯定在java的每个步骤中调用它但它在哪里显示错误/日志?先谢谢你们!
当我恢复时,它会在LogCat中显示以下错误;
添加此行以避免上一个问题;
Thread.isSurfaceCreated = true;
Thread.setRunning(true);
Thread.start();
loadGame();
更新 应用程序返回黑屏,但它没有冻结。
Errors (updated) in logcat;
12-14 16:54:52.176: ERROR/MediaPlayerService(3937): create PVPlayer
12-14 16:55:03.172: ERROR/dalvikvm(4619): Failed to write stack traces to /data/anr/traces.txt (1093 of 3526): Unknown error: 0
12-14 16:55:03.910: ERROR/dalvikvm(25464): Failed to write stack traces to /data/anr/traces.txt (2401 of 3332): Math result not representable
12-14 16:55:03.918: ERROR/dalvikvm(25279): Failed to write stack traces to /data/anr/traces.txt (-1 of 2354): Math result not representable
12-14 16:55:32.394: ERROR/imdg81(19379): IsShutDownStarted()
12-14 16:55:32.590: ERROR/imdg81(19379): IsShutDownStarted()
12-14 16:55:37.902: ERROR/MediaPlayer(19379): error (100, 0)
12-14 16:55:37.930: ERROR/SoundPool(5264): Unable to load sample: (null)
12-14 16:55:39.281: ERROR/SoundBooster(5328): readSBTable: file open error!
12-14 16:55:39.281: ERROR/AcousticEQ(5328): [AEQ] aeqcoe.txt: file open error!
12-14 16:55:39.500: ERROR/AudioService(19379): Media server died.
12-14 16:55:39.500: ERROR/AudioService(19379): Media server started.
12-14 16:55:39.996: ERROR/MediaPlayerService(5328): create PVPlayer
答案 0 :(得分:5)
在你的onSurfaceCreated方法中你有这段代码:
if(isPaused == true){
onResume();
}
Thread.setRunning(true);
Thread.start();
无论如何调用您对Thread.start()的调用(即使isPaused
为真)。由于您的线程已经在这种情况下启动,因此您尝试启动它两次,从而获得非法状态异常。
答案 1 :(得分:2)
谢谢你们!
我已经解决了这个问题,黑屏正在显示,因为线程不是再次创建,而是在我第二次进入屏幕时被操纵。因此,它显示一个空/空线程被操作为黑屏。我已将以下行添加到OnResume()
if(!Thread.isAlive())
{
Thread = new GameThread(holder, new Handler(), this);
}
这是我的问题的解决方法,但现在我要实现onSaveInstanceState& onRestoreInstanceState以避免从beginnig重新启动。