Android crash when app is closed and reopened

前端 未结 3 1594
渐次进展
渐次进展 2020-11-28 07:47

I have a really simple android app that just displays a blank white screen. When I close the app by pressing the HOME button, then try to open the app again, it crashes and

相关标签:
3条回答
  • 2020-11-28 08:17

    The solution below was tested. The code checks thread state, and if terminated creates a new one. No crashes, the only problem I can see is the game state is not saved so basically getting back from a HOME key press, starts the game again. p.s. remember to pass through the context from Lunarview view and set to mContextLunarView. Hope this helps. These forums are awesome. Keep it up.

    public void surfaceCreated(SurfaceHolder holder) {
        // start the thread here so that we don't busy-wait in run()
        // waiting for the surface to be created    
    
        if(thread.getState() == Thread.State.TERMINATED) {
            //LunarView Thread state TERMINATED..make new...under CheckCreateThread
    
            thread = new LunarThread(holder, mContextLunarView, new Handler() {
                @Override
                public void handleMessage(Message m) {
                    mStatusText.setVisibility(m.getData().getInt("viz"));
                    mStatusText.setText(m.getData().getString("text"));
                }
            });     
        }   
    
        thread.setRunning(true);
        thread.start();
    }
    
    0 讨论(0)
  • 2020-11-28 08:18

    Here is a simple solution which may be acceptable in some cases, like a background animation screen and activities which states do not need to be restored - the surface view activity needs to finish on pause.

    protected void onPause()  { 
     super.onPause(); 
     finish();
    } 
    

    The better solution is to move the creation of the thread from the constructor into on surfaceCretaed like this:

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
      _thread = new TutorialThread(holder, this);
      _thread.setRunning(true);
      _thread.start(); 
    }
    

    Then in the thread loop create a pause flag:

    if(!pause){
      _panel.onDraw(c); 
    }
    

    finally in onPause and onRestore for the activity set the pause flag:

       protected void onResume() {
                super.onResume();
                pause = false;    
            }
    
            protected void onPause()  {   
                super.onPause();   
                pause = true;   
            } 
    

    When the user clicks Home button surfaceDestroyed is invoked which will shut down the current thread "_thread". When he returns to the app, surfaceCreated will assign the reference "_thread" to a new thread, while the old thread object will be removed by the garbage collector.

    0 讨论(0)
  • 2020-11-28 08:19

    I've answered a question like this here.

    The error you're getting is probably caused by your Thread (without seeing the full Logcat it's hard to tell though). You're starting it every time the surface is created, which will make your application crash because you can't call Thread.start() twice. Look at my link above for a more in-depth description of the problem and how you should solve it.

    Since my explanation wasn't enough I will post the whole solution:

    Inside your Runnable/Thread:

    private Object mPauseLock = new Object();  
    private boolean mPaused;
    
    // Constructor stuff.      
    
    // This should be after your drawing/update code inside your thread's run() code.
    synchronized (mPauseLock) {
        while (mPaused) {
            try {
                mPauseLock.wait();
            } catch (InterruptedException e) {
            }
        }
    }
    
    // Two methods for your Runnable/Thread class to manage the thread properly.
    public void onPause() {
        synchronized (mPauseLock) {
            mPaused = true;
        }
    }
    
    public void onResume() {
        synchronized (mPauseLock) {
            mPaused = false;
            mPauseLock.notifyAll();
        }
    }
    

    In your SurfaceView class:

    private boolean mGameIsRunning;
    
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // Your own start method.
        start();
    }
    
    public void start() {
        if (!mGameIsRunning) {
            thread.start();
            mGameIsRunning = true;
        } else {
            thread.onResume();
        }
    }
    
    0 讨论(0)
提交回复
热议问题