NullPointerException not in my code but in onResume() for LibGDX AndroidInput

Viewed 314

This the stack trace:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.epl.game, PID: 18789
    java.lang.RuntimeException: Unable to resume activity {com.epl.game/com.epl.game.AndroidLauncher}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.badlogic.gdx.backends.android.AndroidInput.onResume()' on a null object reference
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4205)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4237)
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.badlogic.gdx.backends.android.AndroidInput.onResume()' on a null object reference
        at com.badlogic.gdx.backends.android.AndroidApplication.onResume(AndroidApplication.java:300)
        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1453)
        at android.app.Activity.performResume(Activity.java:7962)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4195)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4237) 
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:49 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

This is my main project

package com.epl.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Rectangle;

import org.omg.PortableServer.POAManagerPackage.State;

import java.util.ArrayList;
import java.util.Random;

public class epl extends ApplicationAdapter {
    MyTextInputListener listener = new MyTextInputListener();
    SpriteBatch batch;
    Texture background;
    Texture[] man;
    State[] gsm;
    int batsmanState = 0;
    int pause = 0;
    float gravity = 0.2f;
    float velocity = 0;
    int manY = 0;
    Rectangle manRectangle;
    BitmapFont font1;
    BitmapFont font2;
    BitmapFont font3;
    Texture dizzy;
    int score = 0;
    int gameState = 0;
    int i1 = 0;
    int i2 = 0;
    State state0;
    State state1;
    State state2;
    State state3;
    State state4;
    State state5;

    Random random;
    String humanName;

    ArrayList<Integer> coinXs = new ArrayList<>();
    ArrayList<Integer> coinYs = new ArrayList<>();
    ArrayList<Rectangle> coinRectangles = new ArrayList<>();
    Texture coin;
    int coinCount;

    ArrayList<Integer> bombXs = new ArrayList<>();
    ArrayList<Integer> bombYs = new ArrayList<>();
    ArrayList<Rectangle> bombRectangles = new ArrayList<>();
    Texture bomb;
    int bombCount;
    PlayServices ply;

    @Override
    public void create() {
        batch = new SpriteBatch();
        background = new Texture("bg.png");
        man = new Texture[4];
        man[0] = new Texture("batsman.jpg");
        man[1] = new Texture("batsman.jpg");
        man[2] = new Texture("batsman.jpg");
        man[3] = new Texture("batsman.jpg");

        gsm = new State[6];
        gsm[0] = (state0);
        gsm[1] = (state1);
        gsm[2] = (state2);
        gsm[3] = (state3);
        gsm[4] = (state4);
        gsm[5] = (state5);


        manY = Gdx.graphics.getHeight() / 2;

        coin = new Texture("ball.png");
        bomb = new Texture("stump.jpeg");
        random = new Random();

        dizzy = new Texture("out.jpeg");

        font1 = new BitmapFont();
        font1.setColor(Color.RED);
        font1.getData().setScale(10);

        font2 = new BitmapFont();
        font2.setColor(Color.RED);
        font2.getData().setScale(10);

        font3 = new BitmapFont();
        font3.setColor(Color.RED);
        font3.getData().setScale(10);
    }

    public void makeCoin() {
        float height = random.nextFloat() * Gdx.graphics.getHeight();
        coinYs.add((int) height);
        coinXs.add(Gdx.graphics.getWidth());
    }



    public void makeBomb() {
        float height = random.nextFloat() * Gdx.graphics.getHeight();
        bombYs.add((int)height);
        bombXs.add(Gdx.graphics.getWidth());
    }
    private String myText;
    public class MyTextInputListener implements Input.TextInputListener {
        @Override
        public void input(String text) {
        }

        @Override
        public void canceled() {
            whatIsYourName();
        }

        public String getText() {
            return myText;
        }

        public void whatIsYourName() {
            Gdx.input.getTextInput(listener, "Name : ", "", "eg:Jonathan");
            humanName = listener.getText();
                gameState = 1;
            }
        }


    public epl(PlayServices ply){
        this.ply = ply;
    }

    @Override
    public void render () {
        batch.begin();
        batch.draw(background, 0, 0, Gdx.graphics.getWidth(), 
        Gdx.graphics.getHeight());

        if (gameState == 1 && state1 == null) {
            // GAME IS LIVE
            // BOMB
            if (bombCount < 250) {
                bombCount++;
            } else {
                bombCount = 0;
                makeBomb();
            }

            bombRectangles.clear();
            for (int i = 0; i < bombXs.size(); i++) {
                batch.draw(bomb, bombXs.get(i), bombYs.get(i));
                bombXs.set(i, bombXs.get(i) - 8);
                bombRectangles.add(new Rectangle(bombXs.get(i), 
                bombYs.get(i), 
                bomb.getWidth(), bomb.getHeight()));
            }

            // COINS
            if (coinCount < 100) {
                coinCount++;
            } else {
                coinCount = 0;
                makeCoin();
            }

            coinRectangles.clear();
            for (int i = 0; i < coinXs.size(); i++) {
                batch.draw(coin, coinXs.get(i), coinYs.get(i));
                coinXs.set(i, coinXs.get(i) - 4);
                coinRectangles.add(new Rectangle(coinXs.get(i), 
                coinYs.get(i), 
                coin.getWidth(), coin.getHeight()));
            }

            if (Gdx.input.justTouched()) {
                velocity = -10;
            }

            if (pause < 8) {
                pause++;
            } else {
                pause = 0;
                if (batsmanState < 3) {
                    batsmanState++;
                } else {
                    batsmanState = 0;
                }
            }

            velocity += gravity;
            manY -= velocity;

            if (manY <= 0) {
                manY = 0;
            }
        } else if (gameState == 5 && state5 == null) {
            //leaderboard
            if (Gdx.input.justTouched()){
                ply.submitScore(humanName,score);
                ply.showScore(humanName);
                gameState = 1;
            }
        }else if (gameState == 3 && state3 == null) {
            //name
            listener.whatIsYourName();
            gameState = 1;
        } else if (gameState == 0 && state0 == null) {
            // Waiting to start
                if (humanName == null){
                gameState = 3;
                }else{
                    gameState = 1;
                }
        } else if (gameState == 4 && state4 == null) {
            //final score display
            font3.draw(batch, "Score = " + score,100,1400);
            if (Gdx.input.justTouched()){
                score = 0;
                gameState = 1;
            }
        }else if (gameState == 2 && state2 == null) {
            // GAME OVER
            if (Gdx.input.justTouched()) {
                manY = Gdx.graphics.getHeight() / 2;
                velocity = 0;
                coinXs.clear();
                coinYs.clear();
                coinRectangles.clear();
                coinCount = 0;
                bombXs.clear();
                bombYs.clear();
                bombRectangles.clear();
                bombCount = 0;
                i1 = 0;
                i2 = 0;
            }
        }

        if (gameState == 2) {
            batch.draw(dizzy, Gdx.graphics.getWidth() / 2 - 
            man[batsmanState].getWidth() / 2, manY);
            if (Gdx.input.justTouched()){
                gameState = 4;
            }
        } else {
            batch.draw(man[batsmanState], Gdx.graphics.getWidth() / 2 - 
            man[batsmanState].getWidth() / 2, manY);
        }
        manRectangle = new Rectangle(Gdx.graphics.getWidth() / 2 - 
        man[batsmanState].getWidth() / 2, manY, 
        man[batsmanState].getWidth(), man[batsmanState].getHeight());

        for (int i=0; i < coinRectangles.size();i++) {
            if (Intersector.overlaps(manRectangle, coinRectangles.get(i))) {
                score++;
                i1 = random.nextInt((4 -1) + 1);
                score = score + i1;
                i2 = i1 + 1;

                coinRectangles.remove(i);
                coinXs.remove(i);
                coinYs.remove(i);
                break;
            }
        }

        for (int i=0; i < bombRectangles.size();i++) {
            if (Intersector.overlaps(manRectangle, bombRectangles.get(i))) {
                gameState = 2;
            }
        }

        font1.draw(batch, String.valueOf(score),100,200);
        font2.draw(batch, String.valueOf(i2),900,200);

        batch.end();
    }

    @Override
    public void dispose () {
        batch.dispose();
    }
}

This is my android launcher

package com.epl.game;

import android.content.Intent;
import android.os.Bundle;

import com.badlogic.gdx.backends.android.AndroidApplication;
import com.google.android.gms.games.Games;
import com.google.example.games.basegameutils.GameHelper;

public class AndroidLauncher extends AndroidApplication implements PlayServices {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        gameHelper = new GameHelper(this, GameHelper.CLIENT_GAMES);
        gameHelper.enableDebugLog(true);


        GameHelper.GameHelperListener gameHelperListener = new GameHelper.GameHelperListener() {
            @Override
            public void onSignInFailed() {
            }

            @Override
            public void onSignInSucceeded() {
            }
        };

        gameHelper.setup(gameHelperListener);
    }

    String leaderboard = "CgkI7PuNlqsVEAIQAA";
    private GameHelper gameHelper;


    @Override
    protected void onStart() {
        super.onStart();
        gameHelper.onStart(this); // You will be logged in to google play services as soon as you open app , i,e on start
    }


    @Override
    protected void onStop() {
        super.onStop();
        gameHelper.onStop();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        gameHelper.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public boolean signIn() {
        try {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    gameHelper.beginUserInitiatedSignIn();

                }
            });
        } catch (Exception e) {

        }
        return  true;
    }

    @Override
    public void submitScore(String LeaderBoard, int highScore) {
        if (isSignedIn()) {
            Games.Leaderboards.submitScore(gameHelper.getApiClient(), LeaderBoard, highScore);
        } else {
            System.out.println(" Not signin Yet ");
        }

    }

    @Override
    public void showScore(String leaderboard) {
        if (isSignedIn()) {
            startActivityForResult(Games.Leaderboards.getLeaderboardIntent(gameHelper.getApiClient(), leaderboard), 1);
        } else {
            signIn();
        }
    }

    @Override
    public boolean isSignedIn() {
        return false;
    }

And this is my play services interface

package com.epl.game;

public interface PlayServices
{
    boolean signIn();
    void submitScore(String LeaderBoard, int highScore);
    void showScore(String LeaderBoard);
    boolean isSignedIn();
}

I am new to libgdx and I am trying to create a game with a leaderboard . I created this by importing the BaseGameUtils . Else if you have another way i could create a global leaderboard in my game please let me know.

1 Answers

It is critical that you call the initialize method in onCreate of your AndroidLauncher class. This is what sets up LibGDX's backends for graphics, sound, and input. Since you did not call initialize, the input class (along with graphics, sound, files, etc.) was not set up and assigned, and so is still null when the resume part of the lifecycle is reached. This leads to the NullPointerException.

In your case, your onCreate method should look something like:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); 
        // customize the configuration here
        initialize(new epl(), config);

        // Your other setup code...
    }

Note, class names in Java should always start with a capital letter. It will make it easier to read and understand your code.

Related