所以我有一个应用程序,它使用一个表面视图,为UI运行一个单独的线程。它几乎直接来自Lunar Landing示例应用程序。该应用程序还在另一个线程上使用蓝牙服务,但我确信这与问题无关,因为我可以一起禁用蓝牙,但它仍然会发生。
我的应用程序中的问题是,关闭后重新打开的应用程序在thread.start()
之后没有开始运行UI线程,除非它抛出错误。在Lunar示例中,他们在onSurfaceCreated方法中有thread.start()
。问题是当我重新启动我的应用程序(它调用onPause然后onSurfaceDestroy)时,线程已经在运行,当我尝试启动它时出现错误。我的onSurfaceCreated,onPause,onResume和onSurfaceDestroyed的代码与示例完全相同。我知道我可以使用if (this.getState() == Thread.State.NEW) {
,但这似乎会掩盖我的其他一些问题。我想掌握活动生命周期。
我的问题是Lunar Lander如何阻止线程?为什么我没有使用相同的代码停止并在onSurfaceCreated方法上运行。显然我错过了一些东西。据我所知,在Lunar示例中,在破坏线程上调用的唯一内容是thread.join()
。
编辑3:如果需要,这是Lunar Lander Example Code。
所以这些是我的surfaceview中的三种覆盖方法......
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "surfaceCreated");
// start the bluetooth service
thread.startBluetoothService();
// start the game
//if (this.getState() == Thread.State.NEW) {
Log.d(TAG, "thread start");
// start running the thread
this.start();
//}
Log.d(TAG, "running to true");
// release the thread lock
setRunning(true);
}
// surfaceChanged is called at least once after surfaceCreated
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(TAG, "surfaceChanged");
// reset the surface size
thread.setSurfaceSize(width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "surfaceDestroyed");
// make sure to shut down the thread cleanly
boolean retry = true;
// stop the running thread
thread.setRunning(false);
// continuously try to shut down the thread
while (retry){
try{
// blocks calling thread until termination
thread.join();
// stop the bluetooth service
//thread.stopBluetoothService();
retry = false;
}catch(InterruptedException e){
//try to shut it down again
}
}
}
我真的很失落所有这一切。非常感谢任何帮助,谢谢!
编辑:
所以我做了一些测试。当用户点击主页(完全退出应用程序)onPause时,然后onSurfaceDestroy就像我之前说过的那样。然后当它重新启动时,我得到onResume,接着是onSurfaceCreated。我认为我的问题是当你重新进入应用程序时它没有调用onCreate。
还有一些问题...... 什么区别onPause和onDestroy的区别?我认为我的问题是因为onCreate没有被调用,所以我没有新创建的UI线程,看起来它仍在运行。
即使在onPause上线程是否应停止?因为那时我不会被运行onCreate,它会重新实例化线程。这是onCreate代码......
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wobble);
// get view and thread
wobbleView = (WobbleView) findViewById(R.id.wobble);
wobbleThread = wobbleView.getThread();
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
// alert the user of bluetooth failure
Toast.makeText(this, "Bluetooth is not available, using internal devices sensors", Toast.LENGTH_LONG).show();
// set the data source to internal sensors - so we'll just use the devices accel
wobbleThread.setDataSource(WobbleThread.INTERNAL_SENSORS);
// bluetooth is supported so make sure its enabled and
}else{
// make sure bluetooth is enabled on the device
if (!mBluetoothAdapter.isEnabled()) {
Log.d(TAG, "starting request to enable bluetooth");
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
// all is well with bluetooth - use bluetooth
Log.d(TAG, "setting bluetooth to bluetooth");
wobbleThread.setDataSource(WobbleThread.BLUETOOTH);
}
// give the LunarView a handle to the TextView used for messages
wobbleView.setTextView(
(TextView) findViewById(R.id.text_accel),
(TextView) findViewById(R.id.game_msg),
(TextView) findViewById(R.id.text_score),
(TextView) findViewById(R.id.bluetooth_status)
);
if (savedInstanceState == null) {
// we were just launched: set up a new game
//wobbleThread.setState(wobbleThread.STATE_READY);
} else {
//wobbleThread.setRunning(true);
// we are being restored: resume a previous game
//wobbleThread.restoreState(savedInstanceState);
}
}
编辑2: 一些logcat输出
所以这是我在重新打开应用程序后调用thread.start()时得到的。
11-18 22:50:44.104 4868-4868/com.bme.shawn.wobble E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalThreadStateException: Thread already started
at java.lang.Thread.checkNotStarted(Thread.java:871)
at java.lang.Thread.start(Thread.java:1025)
at com.bme.shawn.wobble.WobbleThread.startGame(WobbleThread.java:213)
at com.bme.shawn.wobble.WobbleView.surfaceCreated(WobbleView.java:94)
at android.view.SurfaceView.updateWindow(SurfaceView.java:580)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:240)
at android.view.View.dispatchWindowVisibilityChanged(View.java:7903)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1071)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1289)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1050)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5750)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:791)
at android.view.Choreographer.doCallbacks(Choreographer.java:591)
at android.view.Choreographer.doFrame(Choreographer.java:561)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:777)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5406)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
如果我使用thread.getState检查并绕过错误,当我关闭然后重新打开应用程序时,我会得到这个。 (基本上记录所有内容)在这种情况下,当应用程序重新打开时,线程根本没有绘制。这是非常奇怪的,因为没有检查我得到一个错误,说线程已经在运行。
11-18 22:59:13.444 5345-5345/com.bme.shawn.wobble D/WobbleActivity﹕ onPause
11-18 22:59:13.584 5345-5345/com.bme.shawn.wobble D/WobbleView﹕ surfaceDestroyed
11-18 22:59:17.794 5345-5345/com.bme.shawn.wobble D/WobbleActivity﹕ onResume
11-18 22:59:17.804 5345-5345/com.bme.shawn.wobble D/WobbleView﹕ surfaceCreated
11-18 22:59:17.804 5345-5345/com.bme.shawn.wobble D/WobbleThread﹕ running to true
11-18 22:59:17.804 5345-5345/com.bme.shawn.wobble D/WobbleView﹕ surfaceChanged
11-18 22:59:17.804 5345-5345/com.bme.shawn.wobble D/WobbleThread﹕ setting surface sizes
11-18 22:59:17.824 5345-5345/com.bme.shawn.wobble D/dalvikvm﹕ GC_FOR_ALLOC freed 3343K, 2% free 6585K/6668K, paused 13ms, total 13ms
11-18 22:59:17.844 5345-5345/com.bme.shawn.wobble E/IMGSRV﹕ :0: PVRDRMOpen: TP3, ret = 44
11-18 22:59:17.854 5345-5345/com.bme.shawn.wobble E/IMGSRV﹕ :0: PVRDRMOpen: TP3, ret = 50
答案 0 :(得分:0)
在surfaceCreated()
中创建一个新线程实例并启动它。并在thread.join()
中调用surfaceDestroyed()
来销毁它。