简体   繁体   中英

Android NullpointerException. Syntax Error

I have been debugging the following code, which is for a game. My game is a maze game which uses a dragging. My game works fine till I get a line of code from other project to implement a timer .

Here's my full code of gameview:

public class GameView extends View {

private TimeCounter timeCounter;

private boolean paused;

public boolean isPaused() {
    return paused;
}

public void setPaused(boolean paused) {
    this.paused = paused;
}    
public void setTimeCounter(TimeCounter timeCounter) {
    this.timeCounter = timeCounter;
}
// width and height of the whole maze and width of lines which
// make the walls
private int width, height, lineWidth;
// size of the maze i.e. number of cells in it
private int mazeSizeX, mazeSizeY;
// width and height of cells in the maze
float cellWidth, cellHeight;
// the following store result of cellWidth+lineWidth
// and cellHeight+lineWidth respectively
float totalCellWidth, totalCellHeight;
// the finishing point of the maze
private int mazeFinishX, mazeFinishY;
private Maze maze;
private Activity context;
private Paint line, red, background;
private String text;

public GameView(Context context, Maze maze) {
    super(context);

    this.context = (Activity) context;
    this.maze = maze;
    mazeFinishX = maze.getFinalX();
    mazeFinishY = maze.getFinalY();
    mazeSizeX = maze.getMazeWidth();
    mazeSizeY = maze.getMazeHeight();
    line = new Paint();
    line.setColor(getResources().getColor(R.color.line));
    red = new Paint();
    red.setColor(getResources().getColor(R.color.position));
    background = new Paint();
    background.setColor(getResources().getColor(R.color.game_bg));
    setFocusable(true);
    this.setFocusableInTouchMode(true);
}

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    width = (w < h) ? w : h;
    height = width; // for now square mazes
    lineWidth = 1; // for now 1 pixel wide walls
    cellWidth = (width - ((float) mazeSizeX * lineWidth)) / mazeSizeX;
    totalCellWidth = cellWidth + lineWidth;
    cellHeight = (height - ((float) mazeSizeY * lineWidth)) / mazeSizeY;
    totalCellHeight = cellHeight + lineWidth;
    red.setTextSize(cellHeight * 0.75f);
    super.onSizeChanged(w, h, oldw, oldh);
}

protected void onDraw(Canvas canvas) {
    canvas.drawRect(0, 0, width, height, background);

    boolean[][] hLines = maze.getHorizontalLines();
    boolean[][] vLines = maze.getVerticalLines();
    // iterate over the boolean arrays to draw walls
    for (int i = 0; i < mazeSizeX; i++) {
        for (int j = 0; j < mazeSizeY; j++) {
            float x = j * totalCellWidth;
            float y = i * totalCellHeight;
            if (j < mazeSizeX - 1 && vLines[i][j]) {
                // we'll draw a vertical line
                canvas.drawLine(x + cellWidth,y,x + cellWidth,y + cellHeight,
                        line);
            }
            if (i < mazeSizeY - 1 && hLines[i][j]) {
                // we'll draw a horizontal line
                canvas.drawLine(x,y + cellHeight,x + cellWidth,y + cellHeight,
                        line);
            }
        }
    }
    int currentX = maze.getCurrentX(), currentY = maze.getCurrentY();
    canvas.drawCircle((currentX * totalCellWidth) + (cellWidth / 2),
            (currentY * totalCellHeight) + (cellWidth / 2),
            (cellWidth * 0.45f), // radius
            red);

    int secondss = timeCounter.getTimeSeconds(); // THIS IS WHERE THE ERROR.

    text = String.format("%02d:%02d", secondss/60, secondss%60);
    canvas.drawText(text, (mazeFinishX * totalCellWidth)
            + (cellWidth * 0.25f), (mazeFinishY * totalCellHeight)
            + (cellHeight * 0.75f), red); 
    }
}

and on my TimeCounter Class which I copy from other project to make use the getTimeSeconds() method

public class TimeCounter {
    public int getTimeSeconds() {
        return (int) (getTime() / 1000);
    }
}

and the logcat:

08-26 16:10:02.516: E/AndroidRuntime(27100): FATAL EXCEPTION: main
08-26 16:10:02.516: E/AndroidRuntime(27100): java.lang.NullPointerException
08-26 16:10:02.516: E/AndroidRuntime(27100):    at com.jforeach.mazegame.GameView.onDraw(GameView.java:129)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.View.draw(View.java:13877)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.View.draw(View.java:13761)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewGroup.drawChild(ViewGroup.java:3039)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2903)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.View.draw(View.java:13759)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewGroup.drawChild(ViewGroup.java:3039)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2903)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.View.draw(View.java:13759)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewGroup.drawChild(ViewGroup.java:3039)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2903)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.View.draw(View.java:13880)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2226)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2719)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewRootImpl.draw(ViewRootImpl.java:2564)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2371)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2172)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1166)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5013)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.Choreographer.doCallbacks(Choreographer.java:579)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.Choreographer.doFrame(Choreographer.java:548)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.os.Handler.handleCallback(Handler.java:725)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.os.Looper.loop(Looper.java:153)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at android.app.ActivityThread.main(ActivityThread.java:5299)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at java.lang.reflect.Method.invokeNative(Native Method)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at java.lang.reflect.Method.invoke(Method.java:511)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
08-26 16:10:02.516: E/AndroidRuntime(27100):    at dalvik.system.NativeStart.main(Native Method)

Update : on my menu when the start button was click it will go on the Game Class then GameView Class.

Here's my Game Class :

public class Game extends Activity {
public void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    Maze maze = (Maze)extras.get("maze");
    GameView view = new GameView(this,maze);    
    setContentView(view);

is this where I will call the setTimeCounter ?

When you call

int secondss = timeCounter.getTimeSeconds();

you're getting a NullPointerException because you're trying to invoke the getTimeSeconds() method of timeCounter when timeCounter is null . If an object is null then any attempt to access its methods or fields will result in such an exception.

This is just because you forgot to set the timeCounter field.

(Note that you could also get a NullPointerException out of a line like this if timeCounter were set but its getTimeSeconds() method caused an exception. But if that were the case, there would be an extra line in your logcat, telling you the line of code of TimeCounter that was causing the trouble.)

By the time you inflate this view it will display the view in your screen which will call onDraw method and on this line of code:

timeCounter.getTimeSeconds();

It will be called and will throw exception because you haven't even instantiate the object.

solution:

you need to add an if block to check if timeCounter is not null

sample:

canvas.drawCircle((currentX * totalCellWidth) + (cellWidth / 2),
        (currentY * totalCellHeight) + (cellWidth / 2),
        (cellWidth * 0.45f), // radius
        red);

if(timeCounter != null) {
int secondss = timeCounter.getTimeSeconds(); // THIS IS WHERE THE ERROR.

text = String.format("%02d:%02d", secondss/60, secondss%60);

Remember that if you use this view it will call onDraw directly by which you need to check for object if it is null or not(object that are instantiated by method call )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM