首页 > 解决方案 > 我的应用程序不断崩溃并抛出空对象引用,我不明白为什么?

问题描述

当我layout.setVisibilty(VISIBLE)输入我的checkExit()方法时,我的应用程序崩溃了。我的FATAL EXCEPTION崩溃日志告诉我这是因为null object reference. 我不明白为什么,我不知道如何解决它。

我已经尝试在我的 MainActivity 中将布局设为静态,我已经尝试在我的 GameView 中将其设为静态。我试过改变它的初始化位置,但我仍然不明白为什么它被抛出。

我的 MainActivity 代码:

package com.example.practicingandroidwithsean.mazeone;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {


    boolean gameIsActive = true;

    public void playAgain(View view){

        View gameView = findViewById(R.id.gameView);
        LinearLayout layout = findViewById(R.id.playAgainLayout);
        Animation slideDown = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_down);
        Animation slideUp = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_up);

        if(gameView.getVisibility() == View.INVISIBLE){

            gameIsActive = false;
            layout.startAnimation(slideUp);
            layout.setVisibility(View.VISIBLE);


        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LinearLayout layout = findViewById(R.id.playAgainLayout);
        layout.setVisibility(View.INVISIBLE);


    }
}

我的 GameView 代码......这是一切主要发生的地方:

public class GameView extends View {

    public GameView(Context context) {
        super(context);
    }

    private enum Direction{ //data type of self defined constants
        UP, DOWN, LEFT, RIGHT
    }

    private static Cell[][] cells;
    public static Cell player, exit, trail;
    private static final int COLS = 12, ROWS = 18;
    private static final float WALL_THICKNESS = 4;
    private static ArrayList<Cell> trailList = new ArrayList<>();
    private float cellSize, hMargin, vMargin;
    private int counter = 0;
    private Paint wallPaint, playerPaint, exitPaint, trailPaint;
    private static Random random;
    private TextView TextViewTime;
    private int seconds, minutes;
    private boolean gameIsActive = true;

    LinearLayout layout;
    View gameView;


    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);

        wallPaint = new Paint();
        wallPaint.setColor(Color.WHITE);
        wallPaint.setStrokeWidth(WALL_THICKNESS);

        playerPaint = new Paint();
        playerPaint.setColor(Color.RED);

        exitPaint = new Paint();
        exitPaint.setColor(Color.BLUE);

        //   trailPaint = new Paint();
        //   trailPaint.setColor(Color.YELLOW);

        random = new Random();

        this.seconds = 0;
        this.minutes = 0;

        layout = findViewById(R.id.playAgainLayout);
        gameView = findViewById(R.id.gameView);

//        timer(findViewById(R.id.Timer));

        createMaze();
    }

public void createMaze(){

        Stack<Cell> stack = new Stack<>();
        Cell current, next;

        cells = new Cell[COLS][ROWS];

        for(int x=0; x<COLS; x++){
            for(int y=0; y<ROWS; y++){
                cells[x][y] = new Cell(x, y); //2 Dimensional array of cell objects for the whole msze
            }
        }

        player = cells[0][0]; //This is where the player starts
        exit = cells[COLS-1][ROWS-1]; //This is the exit


        current = cells[0][0];
        current.visited = true;

        do {
            next = getNeighbour(current);
            if (next != null) {
                removeWall(current, next);
                stack.push(current);
                current = next;
                current.visited = true;
            } else
                current = stack.pop(); //gives us the top element of the stack and removes it from the
        }while(!stack.empty());

        Animation slideUp = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
        gameView.startAnimation(slideUp);

    }

public void checkExit() {
        if (player == exit && counter < 3) {
            counter++;

            Animation slideDown = AnimationUtils.loadAnimation(getContext(), R.anim.mazeslidedown);
            gameView.startAnimation(slideDown);
            gameView.setVisibility(INVISIBLE);

            layout.setVisibility(VISIBLE);

        }
    }

当 时player == exit,视图滑开。这没有问题,但是当我尝试使layout.setVisibility(Visible)to 工作时player==exit,游戏崩溃了。下面是错误。

Process: com.example.practicingandroidwithsean.mazeone, PID: 4295
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.LinearLayout.setVisibility(int)' on a null object reference
        at com.example.practicingandroidwithsean.mazeone.GameView.checkExit(GameView.java:285)
        at com.example.practicingandroidwithsean.mazeone.GameView.movePlayer(GameView.java:273)
        at com.example.practicingandroidwithsean.mazeone.GameView.onTouchEvent(GameView.java:349)
        at android.view.View.dispatchTouchEvent(View.java:12540)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:601)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1871)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3384)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:563)
        at android.view.View.dispatchPointerEvent(View.java:12788)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5670)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5465)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5011)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4977)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5114)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4985)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5171)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5011)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4977)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4985)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7736)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7676)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7637)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7847)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:197)
        at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
        at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:186)
        at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:7810)
        at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:7874)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:652)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Application terminated.

预期的结果是 View 像它一样滑开,然后 playAgainLayout 向上滑动。然后这允许我的 playAgain 按钮工作(我将在 MainActivity.class 中创建它)。如果有帮助的话,activity_main.xml 包含一个链接到 gameView 的视图。

我的activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    tools:context=".MainActivity">

    <Chronometer
        android:id="@+id/chronometer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:textColor="@android:color/white"
        android:textSize="45sp"
        app:layout_constraintBottom_toTopOf="@+id/gameView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <view
        android:id="@+id/gameView"
        class="com.example.practicingandroidwithsean.mazeone.GameView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="140dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:background="@drawable/border"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:id="@+id/playAgainLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:background="@drawable/border"
        android:orientation="vertical"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/wellDoneTV"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="Well Done!"
            android:textAlignment="center"
            android:textColor="@android:color/white"
            android:textSize="50sp" />

        <TextView
            android:id="@+id/gameTime"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="0:00"
            android:textAlignment="center"
            android:textColor="@android:color/white"
            android:textSize="30sp" />

        <Button
            android:id="@+id/playAgain"
            style="@style/Widget.AppCompat.Button.Colored"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/button_border"
            android:onClick="playAgain"
            android:text="Button"
            android:textColor="@android:color/white"
            android:textSize="25sp" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

标签: javaandroidnullpointerexception

解决方案


推荐阅读