• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Null Object Reference

Jaggywaggy

Lurker
Mar 13, 2019
4
0
I've been having a problem with a null object reference in one of my constructors that calls on a get method from another class. If anyone has any idea how it could be happening it would be a great help.

Heres my Logcat:


Code:
2019-03-13 18:39:14.553 11395-11426/uk.ac.qub.eeecs.gage E/Gage Error:: Attempt to invoke virtual method 'android.graphics.Bitmap uk.ac.qub.eeecs.game.cardDemo.PlayerInfo.getPlayerImage()' on a null object reference
2019-03-13 18:39:14.555 11395-11426/uk.ac.qub.eeecs.gage E/AndroidRuntime: FATAL EXCEPTION: Thread-4
    Process: uk.ac.qub.eeecs.gage, PID: 11395
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Bitmap uk.ac.qub.eeecs.game.cardDemo.PlayerInfo.getPlayerImage()' on a null object reference
        at uk.ac.qub.eeecs.game.cardDemo.Player.<init>(Player.java:22)
        at uk.ac.qub.eeecs.game.cardDemo.PlayerObject.<init>(PlayerObject.java:73)
        at uk.ac.qub.eeecs.game.cardDemo.CardDemoScreen.<init>(CardDemoScreen.java:261)
        at uk.ac.qub.eeecs.game.cardDemo.CardDemoMenuScreen.updateButtons(CardDemoMenuScreen.java:170)
        at uk.ac.qub.eeecs.game.cardDemo.CardDemoMenuScreen.update(CardDemoMenuScreen.java:143)
        at uk.ac.qub.eeecs.gage.Game.doUpdate(Game.java:363)
        at uk.ac.qub.eeecs.gage.Game.access$200(Game.java:27)
        at uk.ac.qub.eeecs.gage.Game$GameLoop.run(Game.java:557)
        at java.lang.Thread.run(Thread.java:764)

And the code in the Player class :

Code:
   private int playerHealth;
    private int playerCoins;
    private int cardCost;
    private Bitmap mPlayerImage;

    private Bitmap mPlayer;

    public Player(float startX, float startY, float width, float height, GameScreen gameScreen, PlayerInfo playerInfo) {
 22       super(startX, startY, width, height, playerInfo.getPlayerImage(), gameScreen);

        playerHealth = playerInfo.getHealth();
        playerCoins = playerInfo.getPlayerCoins();
        mPlayerImage = playerInfo.getPlayerImage();
        mPlayer = mPlayerImage;

    }

    public void draw(ElapsedTime elapsedTime, IGraphics2D graphics2D,
                     LayerViewport layerViewport, ScreenViewport screenViewport) {

        // Draw the player
        mBitmap = mPlayer;
        super.draw(elapsedTime, graphics2D, layerViewport, screenViewport);

    }

    public float getX(){
        return position.x;
    }

    public float getY(){
        return position.y;
    }

    public Bitmap getBitmap() {
        return mPlayer;
    }

And here is the class with the getPlayerImage method:

Code:
public class PlayerInfo {

    private Bitmap mPlayerImage;
    private int mHealth;
    private int mPlayerCoins;


    /**
     * Create a CardInfo object
     * [USER=315340]@param[/USER] playerImage
     * [USER=315340]@param[/USER] health
     * [USER=315340]@param[/USER] playerCoins
     */
    public PlayerInfo(Bitmap playerImage, int health, int playerCoins) {

        mPlayerImage = playerImage;
        mHealth = health;
        mPlayerCoins = playerCoins;
    }

    public Bitmap getPlayerImage() {
        return mPlayerImage;
    }


(Sorry about the formatting of this post, Im new to using forums and didn't know how to sort it properly}
 
Last edited by a moderator:
I added [code][/code] tags to format your code

The reason you're getting this exception is because the Player class constructor receives a parameter (playerInfo) with a null value.

I haven't applied a null value to it though. There's another class in the project that works in a very similar way to the Player class and it doesn't give this exception.

Code:
public class Card extends Sprite {
    // /////////////////////////////////////////////////////////////////////////
    // Variables
    // /////////////////////////////////////////////////////////////////////////


    //Card dimensions
    private static final float cardWidth = 195;
    private static final float cardHeight = 320;

    //Card parameters from CardInfo
    private int mID;                // Unique identification number of the card
    private Bitmap mCardImage;      // The image representing the card on the game board
    private String mName;           // The name of the hero presented on the card
    private Bitmap mDescription;    // The image containing the card's description
    private int mCost;              // The card's summon cost value
    private int mAttack;            // The card's attack value
    private int mHealth;            // The card's health value

    //Card's current bitmap
    private Bitmap mCardBase;

    //Card flipped status
    private boolean flipped;

    // Target for drag and drop
    private Vector2 moveTarget = new Vector2();
    // /////////////////////////////////////////////////////////////////////////
    // Constructors
    // /////////////////////////////////////////////////////////////////////////

    /**
     * Create a card
     *
     * @param startX     x location of the card
     * @param startY     y location of the card
     * @param width      Wdith of the card
     * @param height     Height of the card
     * @param gameScreen Gamescreen to which card belongs
     */
    public Card(float startX, float startY, float width, float height,  GameScreen gameScreen, CardInfo cardInfo) {
        super(startX, startY, width, height, cardInfo.getCardImage(), gameScreen);

        //AssetManager assetManager = gameScreen.getGame().getAssetManager();

        //Fill in parameters from cardInfo
        mID = cardInfo.getID();
        mCardImage = cardInfo.getCardImage();
        mName = cardInfo.getName();
        mDescription = cardInfo.getDescription();
        mCost = cardInfo.getCost();
        mAttack = cardInfo.getAttack();
        mHealth = cardInfo.getHealth();

        mCardBase = mCardImage;

        
        flipped = false;
    }

    // /////////////////////////////////////////////////////////////////////////
    // Methods
    // /////////////////////////////////////////////////////////////////////////


    /**
     * Draw the card
     *
     * @param elapsedTime    Elapsed time information
     * @param graphics2D     Graphics instance
     * @param layerViewport  Game layer viewport
     * @param screenViewport Screen viewport
     */
    @Override
    public void draw(ElapsedTime elapsedTime, IGraphics2D graphics2D,
                     LayerViewport layerViewport, ScreenViewport screenViewport) {

        // Draw the card base
        mBitmap = mCardBase;
        super.draw(elapsedTime, graphics2D, layerViewport, screenViewport);

    }

and heres the CardInfo class:

Code:
 // /////////////////////////////////////////////////////////////////////////
    // Variables
    // /////////////////////////////////////////////////////////////////////////

    private int mID;                // Unique identification number of the card
    private Bitmap mCardImage;      // The image representing the card on the game board
    private String mName;           // The name of the hero presented on the card
    private Bitmap mDescription;    // The image containing the card's description
    private int mCost;              // The card's summon cost value
    private int mAttack;            // The card's attack value
    private int mHealth;            // The card's health value

    // /////////////////////////////////////////////////////////////////////////
    // Constructors
    // /////////////////////////////////////////////////////////////////////////

    /**
     * Create a CardInfo object
     * @param ID
     * @param cardImage
     * @param name
     * @param description
     * @param cost
     * @param attack
     * @param health
     */
    public CardInfo(int ID, Bitmap cardImage, String name, Bitmap description, int cost, int attack, int health){

        // Fill in member variables based on the arguments passed in
        mID = ID;
        mCardImage = cardImage;
        mName = name;
        mDescription = description;
        mCost = cost;
        mAttack = attack;
        mHealth = health;

    }

    // /////////////////////////////////////////////////////////////////////////
    // Methods
    // /////////////////////////////////////////////////////////////////////////

    //Accessors

    public int getID(){
        return mID;
    }

    public Bitmap getCardImage(){
        return mCardImage;
    }

    public String getName(){
        return mName;
    }

    public Bitmap getDescription(){
        return mDescription;
    }

    public int getCost(){
        return mCost;
    }

    public int getAttack(){
        return mAttack;
    }

    public int getHealth(){
        return mHealth;
    }
}

I'm really struggling to get my head around this. would you know why the getPlayerImage calls a null value, but the getCardImage doesn't?
 
Upvote 0
I haven't applied a null value to it though

A NullPointerException occurs when your code tries to de-reference an object which is null. Unless you assign a new object instance to a variable, it gets a default value of null.
So if you write

Code:
PlayerInfo playerInfo;
playerInfo.getPlayerImage();

then that will generate a NullPointerException
To avoid this, use the new keyword to create a new instance of an object

Code:
PlayerInfo playerInfo = new PlayerInfo();
playerInfo.getPlayerImage();

The next thing you should do is take time to understand a stack trace. This shows the sequence of method calls which led to the exception. In your case it's

Code:
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Bitmap uk.ac.qub.eeecs.game.cardDemo.PlayerInfo.getPlayerImage()' on a null object reference
        at uk.ac.qub.eeecs.game.cardDemo.Player.<init>(Player.java:22)
        at uk.ac.qub.eeecs.game.cardDemo.PlayerObject.<init>(PlayerObject.java:73)
        at uk.ac.qub.eeecs.game.cardDemo.CardDemoScreen.<init>(CardDemoScreen.java:261)
        at uk.ac.qub.eeecs.game.cardDemo.CardDemoMenuScreen.updateButtons(CardDemoMenuScreen.java:170)
        at uk.ac.qub.eeecs.game.cardDemo.CardDemoMenuScreen.update(CardDemoMenuScreen.java:143)
        at uk.ac.qub.eeecs.gage.Game.doUpdate(Game.java:363)
        at uk.ac.qub.eeecs.gage.Game.access$200(Game.java:27)
        at uk.ac.qub.eeecs.gage.Game$GameLoop.run(Game.java:557)
        at java.lang.Thread.run(Thread.java:764)

Your first action should be to examine each line mentioned in this trace, and figure out where the null value parameter was passed down to Player.
To answer your question properly, we'd need to see the code for all the java classes that are in this trace. One of these method calls was made using a parameter which had a null value.
 
  • Like
Reactions: GameTheory
Upvote 0

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones