Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 针对月球着陆器示例,surfaceView中运行线程的非法线程例外_Java_Android_Multithreading - Fatal编程技术网

Java 针对月球着陆器示例,surfaceView中运行线程的非法线程例外

Java 针对月球着陆器示例,surfaceView中运行线程的非法线程例外,java,android,multithreading,Java,Android,Multithreading,因此,我有一个应用程序,它使用一个表面视图,为UI运行一个单独的线程。它几乎是直接从月球着陆示例应用程序中获取的。该应用程序还在另一个线程上使用蓝牙服务,但我确信这与问题无关,因为我可以一起禁用蓝牙,但这种情况仍然存在 我的应用程序中的问题是,当关闭然后重新打开时,除了抛出错误外,该应用程序不会在thread.start之后开始运行UI线程。在Lunar示例中,onSurfaceCreated方法中有thread.start。问题是,当我重新启动应用程序时,它会在Pause上调用,然后在Surf

因此,我有一个应用程序,它使用一个表面视图,为UI运行一个单独的线程。它几乎是直接从月球着陆示例应用程序中获取的。该应用程序还在另一个线程上使用蓝牙服务,但我确信这与问题无关,因为我可以一起禁用蓝牙,但这种情况仍然存在

我的应用程序中的问题是,当关闭然后重新打开时,除了抛出错误外,该应用程序不会在thread.start之后开始运行UI线程。在Lunar示例中,onSurfaceCreated方法中有thread.start。问题是,当我重新启动应用程序时,它会在Pause上调用,然后在SurfaceDestroy上,线程已经在运行,当我尝试启动它时,会出现错误。我的onSurfaceCreated、onPause、onResume和onsurfacedestromed代码与示例完全相同。我知道如果this.getState==Thread.State.NEW{,我可以使用它,但这似乎会掩盖我的一些其他问题。我想掌握活动生命周期

我的问题是月球着陆器是如何停止线程的?为什么我的不停止使用相同的代码并在onSurfaceCreated方法上运行。显然我遗漏了一些东西。据我所知,在月球示例中,destroy的线程上唯一调用的是thread.join

编辑3:如果需要的话,这里是答案

这是我的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
            }
    }
}
我真的很迷茫。任何帮助都将不胜感激,谢谢

编辑:

所以我做了更多的测试。当用户点击Home并在Pause上完全退出应用程序时,然后像我之前所说的那样点击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

在surfaceCreated中创建一个新的线程实例并启动它。然后调用thread.join in surfaceDestroyedto销毁它。

发布您的logcat输出。好了,谢谢提醒我。月球着陆器示例不这样做怎么办?他们正在同步surfaceView,并在pause restore and unpause meth中显式设置状态od。我也在这样做。我使用一个SetStateMode方法,该方法也会像同步SurfaceHolder一样同步SurfaceHolder。我使用此方法将其设置为在onPause方法中暂停。我在视图点击上以相同的方式取消暂停。您是否尝试过创建新实例?是否有效?尚未尝试。我是否应该在视图中创建thread的实例结构者?