Home » Java » java – ANR thread wait-Exceptionshub

java – ANR thread wait-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have a problem with my Java’s understanding of the following problem. I have a game on Google Store and occasionally I’m getting ANR error on my developer console which points to onPause method within my custom Activity. I have a hard time reproducing the problem as well as understanding thread’s intrinsic mechanisms. Stack call for this particular ANR looks like this (proguarded):

  at java.lang.Object.wait (Object.java)
- waiting on <0x0f6bfc18> (a java.lang.Object)
  at java.lang.Object.wait (Object.java:442)
  at java.lang.Object.wait (Object.java:568)
  at xengine.XEngineActivity.onPause (XEngineActivity.java)
- locked <0x0f6bfc18> (a java.lang.Object)
  at android.app.Activity.performPause (Activity.java:8168)
  at android.app.Instrumentation.callActivityOnPause (Instrumentation.java:1508)
  at android.app.ActivityThread.performPauseActivityIfNeeded (ActivityThread.java:4725)

The part of the function where the problem occurs is pasted below, where final Object threadsLock = new Object(); Can anyone spot what’s wrong with it?

@Override
protected void onPause() {
    synchronized(threadsLock) {
        if(gameState != GameState.INITIALIZATION) {
            gameState = isFinishing() ? GameState.FINISHED : GameState.PAUSED;
            while(true) {
                try {
                    threadsLock.wait();
                    break;
                } catch (InterruptedException e) {
                    // TODO: ??
                }
            }
        }
    }
    audioMgr.pauseMusic();
    audioMgr.pause(true);
    inputMgr.onPause(); 
    if(isFinishing())
        audioMgr.release(); 
    else
        audioMgr.pauseMusic();
    glView.onPause();
    super.onPause();
}

EDIT:

public void onDrawFrame(GL10 unused) {
    GameState gameState;
    boolean backButton;

    synchronized(xengine.threadsLock) {
        gameState = xengine.gameState;
        backButton = xengine.backButtonPressed;
    }

    if(backButton) {
        xengine.getScreen().onBackButtonPressed();
    }

    if(gameState == GameState.INITIALIZATION) {
        xengine.getScreen().onResume();
        synchronized(xengine.threadsLock) {
            xengine.gameState = GameState.RUNNING;
        }
        previousFrameTime = SystemClock.uptimeMillis();
    }
    else if(gameState == GameState.RUNNING) {
        gameRunning();
    } 
    else if(gameState == GameState.PAUSED) {
        gamePaused();
    } 
    else if(gameState == GameState.FINISHED) {
        gameFinished();         
    }

    if(backButton) {
        synchronized(xengine.threadsLock) {
            xengine.backButtonPressed = false;
        }
    }
}

private void gamePaused() {
    xengine.getScreen().onPause();
    xengine.shadersMgr.release();
    synchronized(xengine.threadsLock) {
        xengine.gameState = GameState.IDLE;
        xengine.threadsLock.notifyAll();
    }
}
How to&Answers: