首页 > 解决方案 > NullPointerException 不在我的代码中,但在 LibGDX And​​roidInput 的 onResume() 中

问题描述

这是堆栈跟踪:

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) 

这是我的主要项目

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();
    }
}

这是我的安卓启动器

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;
    }

这是我的播放服务界面

package com.epl.game;

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

我是 libgdx 的新手,我正在尝试创建一个带有排行榜的游戏。我通过导入 BaseGameUtils 创建了它。否则,如果您有其他方法可以在我的游戏中创建全球排行榜,请告诉我。

标签: android-studiolibgdx

解决方案


调用类中的方法initialize至关重要。这就是为图形、声音和输入设置 LibGDX 后端的原因。由于您没有调用,因此未设置和分配输入类(以及图形、声音、文件等),因此在达到生命周期的恢复部分时仍然为空。这会导致 NullPointerException。onCreateAndroidLauncherinitialize

在您的情况下,您的onCreate方法应类似于:

    @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...
    }

请注意,Java 中的类名应始终以大写字母开头。这将使您更容易阅读和理解您的代码。


推荐阅读