当前位置: 代码迷 >> java >> 避免线程已启动异常(Android)
  详细解决方案

避免线程已启动异常(Android)

热度:89   发布时间:2023-07-25 19:53:33.0
    java.lang.IllegalThreadStateException: Thread already started
        at java.lang.Thread.checkNotStarted(Thread.java:849)
        at java.lang.Thread.start(Thread.java:1059)
        at com.name.MainActivity$MenuView$1.surfaceCreated(MainActivity.java:496)

如何避免这种情况? 我有一个内部类MenuView ,它扩展了SurfaceView 它更新线程上的画布。 onSurfaceCreated()启动线程, onSurfaceDestroyed()我调用thread.join()停止线程。 但是,如果弹出“ Google Play登录”窗口,并且在焦点对准时我按下主屏幕按钮,然后重新打开该应用程序。 我收到强制关闭错误以及上面发布的异常。

holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                allow_thread_to_run = true;
                boolean retry = true;
                while (retry) {
                    if (t!=null && !t.isAlive()) {
                        t.start();
                        retry = false;
                    }
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                allow_thread_to_run = false;
                boolean retry = true;
                if(t!=null && t.isAlive()) {
                    while (retry) {
                        try {
                            t.join();
                            retry = false;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

    }

那么,为什么这个Google Play窗口成为焦点,导致我的线程两次启动。 从我所看到的,我的设置有必要的检查isAlive() ,以确保避免这种情况!

我同意@adelphus的观点。如果您关心Thread Calss的代码,您会发现。每个Thread对象都有一个标志,该标志反映该线程是否已经启动。

boolean hasBeenStarted = false;

调用start()方法后,它将检查状态并更改其是否为false,否则将引发类似您所拥有的异常的信息。

public synchronized void start() {
    checkNotStarted();

    hasBeenStarted = true;

    nativeCreate(this, stackSize, daemon);
}

以后,状态将永远不会改变。 再次调用start()时,它将引发异常。

  相关解决方案