如何暂停和恢复surfaceView线程

我有一个surfaceview设置和运行,但是当我恢复它,我得到一个错误,该线程已经开始。 什么是正确的方式来处理应用程序的背景,然后回到前台? 我已经修好了,并设法让应用程序回来没有崩溃…但surfaceView不再绘制对象。 我的代码:

@Override public void surfaceCreated(SurfaceHolder holder) { Log.e("sys","surfaceCreated was called."); if(systemState==BACKGROUND){ thread.setRunning(true); } else { thread.setRunning(true); thread.start(); Log.e("sys","started thread"); systemState=READY; } } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.e("sys","surfaceDestroyed was called."); thread.setRunning(false); systemState=BACKGROUND; } 

Solutions Collecting From Web of "如何暂停和恢复surfaceView线程"

简单的解决scheme是简单地杀死并重启线程。 创build方法resume() – 创build线程对象并启动它并暂停() – 杀死线程(请参阅Lunarlander示例) – 在SurfaceView类中调用这些来自surfaceCreated和surfaceDestroyed的线程来启动和停止线程。

现在,在运行SurfaceView的Activity中,还需要从Activity的(或片段)onResume()和onPause()调用SurfaceView中的resume()和pause()方法。 这不是一个优雅的解决scheme,但它会工作。

这个错误似乎与月球着陆器错误有关,这个错误非常有名(做一个谷歌search)。 毕竟这个时候,在几个android版本发布后,这个bug依然存在,没有人更新它。 我发现这个工作与最less的代码混乱:

  public void surfaceCreated(SurfaceHolder holder) { if (thread.getState==Thread.State.TERMINATED) { thread = new MainThread(getHolder(),this); } thread.setRunning(true); thread.start(); } 
 public void surfaceCreated(SurfaceHolder holder) { if (!_thread.isAlive()) { _thread = new MyThread(this, contxt); } 

 public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; _thread.setRunning(false); while (retry) { try { _thread.join(); retry = false; } catch (InterruptedException e) { // we will try it again and again... } } } 

我发现的最好的方法是重写控制表面视图的活动的onResume方法,以便使用该方法重新实例化SurfaceView,然后使用setContentView进行设置。 这种方法的问题是,你需要重新加载你的SurfaceView正在照顾的任何状态。

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyCustomSurfaceView(this)); } @Override protected void onResume() { super.onResume(); setContentView(new MyCustomSurfaceView(this)); } 

试图评论上面接受的答案,但不能,新的这一点。 我不认为你应该从你的SurfaceView和Activity调用你的开始/停止线程方法。 这将导致双重启动/停止线程,并且不能多次启动一个线程。 只要从Activity的onPause和onResume调用你的方法。 它们在退出并重新进入应用程序时被调用,以确保您的状态得到正确处理。 surfaceDestroyed并不总是被调用,这让我一阵子了。

如果使用此方法,请确保在处理canvas之前检查运行代码中的有效曲面,因为在曲面可用之前,活动将在onResume中启动线程。

  while (_run) { if (_surfaceHolder.getSurface().isValid()) { ... } } //end _run 

这是我用过的。 该应用程序现在不崩溃。

查看课程:

 holder.addCallback(new Callback() { public void surfaceDestroyed(SurfaceHolder holder) { gameLoopThread.setRunning(false); gameLoopThread.stop(); } public void surfaceCreated(SurfaceHolder holder) { gameLoopThread.setRunning(true); gameLoopThread.start(); } 

在GameLoopThread中:

 private boolean running = false; public void setRunning(boolean run) { running = run; } @Override 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){} } } 

我希望这会有所帮助。

您应该使用Activities onPause()和onResume()方法。

首先,在surfaceCreated()中,启动线程。 另外,在onResume()中,确保线程还没有启动(在线程内部保存一个variables)。 如果没有运行,请将其设置为再次运行。 在onPause()中,暂停该线程。 在surfaceDestroyed中,再次暂停线程。

这个众所周知的问题的另一个解决scheme。 可悲的是,我不明白它为什么起作用 – 它意外地出来了。 但是它对我很好,而且很容易实现:没有重写ActivityonPause()onResume()onStart()onStop() ,也没有写特殊的线程方法(如resume()pause() )是必要的。

特殊要求是把所有变化的variables放在渲染线程类以外的东西上。

要添加到渲染线程类的要点:

 class RefresherThread extends Thread { static SurfaceHolder threadSurfaceHolder; static YourAppViewClass threadView; static boolean running; public void run (){ while(running){ //your amazing draw/logic cycle goes here } } } 

现在,有关YourAppViewClass重要内容:

 class YourAppViewClass extends SurfaceView implements SurfaceHolder.Callback { static RefresherThread surfaceThread; public YourAppViewClass(Activity inpParentActivity) { getHolder().addCallback(this); RefresherThread.threadSurfaceHolder = getHolder(); RefresherThread.threadView = this; } @Override public void surfaceCreated(SurfaceHolder holder) { surfaceThread = new RefresherThread(); surfaceThread.running=true; surfaceThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { surfaceThread.running=false; try { surfaceThread.join(); } catch (InterruptedException e) { } } } 

上面的两个代码块并不是完整的类,而仅仅是需要哪些方法的命令的概念。 另外请注意,每个返回到应用程序调用surfaceChanged()

对不起,这样的空间消耗的答案。 我希望它能正常工作,并会有所帮助。