我制作了一个有两个窗口的应用程序,当我从主窗口转到首选项时,一切都很好,但是当我尝试返回主活动时,应用程序崩溃,线程已启动错误。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GameView(this));
startService(new Intent(this, MyService.class));
}
public void onResume(){
super.onResume();
}
// Initiating Menu XML file (menu.xml)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.layout.menu, menu);
return true;
}
public void onBackPressed() {
super.onBackPressed();
stopService(new Intent(this, MyService.class));
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
更新:这是来自 LogCat 的日志(我正在使用 Eclipse):
09-30 11:59:17.348: D/AndroidRuntime(2917): Shutting down VM
09-30 11:59:17.348: W/dalvikvm(2917): threadid=1: thread exiting with uncaught exception (group=0x40aa7210)
09-30 11:59:17.368: E/AndroidRuntime(2917): FATAL EXCEPTION: main
09-30 11:59:17.368: E/AndroidRuntime(2917): java.lang.IllegalThreadStateException: Thread already started.
09-30 11:59:17.368: E/AndroidRuntime(2917): at java.lang.Thread.start(Thread.java:1045)
09-30 11:59:17.368: E/AndroidRuntime(2917): at com.examples.todolist.GameView$1.surfaceCreated(GameView.java:45)
ManiFest 文件(来自它的活动):
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service
android:name="MusicService"
android:enabled="true">
</service>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="PreferencesActivity"></activity>
<service android:enabled="true" android:name=".MyService" />
</application>
在我的项目中,我有 MainActivity.java - 这是主窗口,PreferencesActivity.java - 这是首选项窗口,GameView.java - 负责绘制内容和 GameManager.java - 控制 FPS。在游戏视图中,我有 main、onDraw 和 onTouch 事件。以下是 GameView 的主要内容:
public GameView(Context context) {
super(context);
gameLoopThread = new GameManager(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
bmp1 = BitmapFactory.decodeResource(getResources(),
R.drawable.wall_sprite);
}
这是一个gameManager.java,因为我发现它与运行有关。我仍然试图弄清楚如何使线程(或屏幕?)被破坏,然后再做一次。
公共类 GameManager 扩展线程 {
static final long FPS = 30;
private GameView view;
private boolean running = false;
// class constructor
public GameManager(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {
}
}
}
}