AndEngine Scoreloop – java.lang.IllegalStateException: you are not calling from the main thread context

| | August 6, 2015

I am a very novice android developer but also created a game using andEngine successfully. Now I want to integrate Scoreloop and everything is fine with Leaderboard view and TOS view, except I am having hard time submitting scores from a game scene. I implemented OnScoreSubmitObserver in the main BaseGameActivity (GameActivity). I used the following line inside the onCreateEngineOptions method:

ScoreloopManagerSingleton.get().setOnScoreSubmitObserver(this);

I also declared the override method perfectly inside GameActivity as mentioned in the scoreloop tutorial:

@Override
public void onScoreSubmit(int status, Exception error) {
    // TODO Auto-generated method stub
    //Calls the ShowResultOverlayActivity. Make sure you have modified the
    //AndroidManifest.xml to reference this overlay class.
    startActivity(new Intent(this, ShowResultOverlayActivity.class));
}

Now I want to submit score from inside a scene using the following line:

ScoreloopManagerSingleton.get().onGamePlayEnded(score, null);

But this shows the following error:

java.lang.IllegalStateException: you are not calling from the main thread context

I also tried implementing OnScoreSubmitObserver on the scene class and tried calling each line mentioned above inside the scene class using “activity” instead of “this”, as “activity” is an instance of the GameActivity. but it also shows the same error. Please help.

2 Responses to “AndEngine Scoreloop – java.lang.IllegalStateException: you are not calling from the main thread context”

  1. The runOnUiThread solution doesn’t work for me, because I call it when game resume, my workaround solution is to use TimerHandler:

        @Override
    protected void onResume() {
        super.onResume();
        final TimerHandler getTimerHandler = new TimerHandler(0.5f, new ITimerCallback() {
            @Override
            public void onTimePassed(final TimerHandler pTimerHandler) {
                if (!AccountUtils.checkSession()) {
                    ResourceManager.getInstance().getCurrentScene().alert("Session timeout´╝ü", new IParamCallback() {
                        @Override
                        public void onCallback(final Object param) {
                            finish();
                        }
                    });
                }
            }
        });
        getEngine().registerUpdateHandler(getTimerHandler);
    }
    
  2. Create a Runnable object that executes the update to Scoreloop, then run that object from whatever thread you like with runOnUIThread. This will always ensure the code runs on the same thread.

    Your runnable would look something like:

    public class ScoreLoopUpdater implements Runnable {
      private float score;
      public ScoreLoopUpdater (Float _score) {
        this.score = _score;
      }
    
      public void run() {
        ScoreloopManagerSingleton.get().onGamePlayEnded(score, null);
      }
    }
    

    So using it would look like:

    ScoreLoopUpdater scoreLoopUpdater = new ScoreLoopUpdater(finalScore);
    Activity.runOnUiThread(scoreLoopUpdater);
    

    If the UI thread doesn’t work, you can try the same on the “main” thread:

    Handler mainHandler = new Handler(context.getMainLooper());
    
    mainHandler.post(scoreLoopUpdater);
    

Leave a Reply