简体   繁体   English

当我在活动开始时点击垃圾邮件时,为什么我的 Android Studio 应用程序会崩溃?

[英]Why does my Android studio App crash when I spam click at the beginning of an activity?

The app works fine if I wait a bit after clicking play, but if I want click on anything clickable right away, the app crashes.如果我在点击播放后稍等片刻,该应用程序运行良好,但如果我想立即点击任何可点击的内容,应用程序就会崩溃。

Here is the error message:这是错误消息:

E/InputEventReceiver: Exception dispatching input event.
D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION:
main
    Process: com.example.combatcats, PID: 13769
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
        at com.example.combatcats.Joystick.getIsPressed(Joystick.java:86)
        at com.example.combatcats.GameView.onTouchEvent(GameView.java:187)
        at android.view.View.dispatchTouchEvent(View.java:14540)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:502)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1890)
        at android.app.Activity.dispatchTouchEvent(Activity.java:4196)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:460)
        at android.view.View.dispatchPointerEvent(View.java:14799)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6347)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6148)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5626)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5683)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5649)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5814)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5657)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5871)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5630)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5683)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5649)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5657)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5630)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8562)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8513)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8482)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8685)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:259)
        at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native
Method)
        at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:239)
        at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:8642)
        at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:8771)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037)
        at android.view.Choreographer.doCallbacks(Choreographer.java:845)
        at android.view.Choreographer.doFrame(Choreographer.java:772)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7839)
        at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime:     at
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

Here is my GameView class:这是我的GameView类:

package com.example.combatcats;

import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;


public class GameView extends SurfaceView implements Runnable {

    private final Joystick joystick;
    private Thread thread;
    private boolean isPlaying;
    private int screenX, screenY;
    public static float screenRatioX, screenRatioY;
    private Paint paint;
    private Cat cat;
    private Background background1, background2;
    private int InAirCounter;
    private final MainMenuButton mainMenuButton;
    private GameScreen activity;

    public GameView(GameScreen activity, int screenX, int screenY) {
        super(activity);

        this.activity = activity;

        this.screenX = screenX;
        this.screenY = screenY;
        screenRatioX = 1920f / screenX;
        screenRatioY = 1080f / screenY;


        background1 = new Background(screenX, screenY, getResources());
        background2 = new Background(screenX, screenY, getResources());

        cat = new Cat(screenY, getResources());

        background2.x = screenX;

        paint = new Paint();

        joystick = new Joystick(190,900,90,55);

        mainMenuButton = new MainMenuButton(60,60,250,158);
    }

    @Override
    public void run() {

        while (isPlaying) {

            update ();
            draw ();
            sleep ();
        }
    }

    private void update () {

        background1.x -= 10 * screenRatioX;
        background2.x -= 10 * screenRatioX;



        InAirCounter -= 1;

        if (background1.x + background1.background.getWidth() < 0) {
            background1.x = screenX;
        }
        if (background2.x + background2.background.getWidth() < 0) {
            background2.x = screenX;
        }

        if (cat.y == (screenY - cat.height) && cat.isJumping) {
            InAirCounter = 7;
        }

        if (InAirCounter > 0)
            cat.y -= 30 * screenRatioY;
        else
            cat.y += 30 * screenRatioY;

        if (cat.y < 0)
            cat.y = 0;
        if (cat.y > screenY - cat.height)
            cat.y = screenY - cat.height;
        if (cat.x < 0)
            cat.x = 0;
        if (cat.x > screenX - cat.width)
            cat.x = screenX - cat.width;

        //Log.d("","var_name = "+var);

        cat.update(joystick);

        joystick.update();
    }

    private void draw () {

        if (getHolder().getSurface().isValid()) {

            Canvas canvas = getHolder().lockCanvas();
            canvas.drawBitmap(background1.background, background1.x, background1.y, paint);
            canvas.drawBitmap(background2.background, background2.x, background2.y, paint);


            canvas.drawBitmap(cat.getBlink(), cat.x, cat.y, paint);
            joystick.draw(canvas);




            mainMenuButton.draw(canvas);


            getHolder().unlockCanvasAndPost(canvas);


        }

    }

    private void sleep () {
        try {
            Thread.sleep(17);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void resume () {

        isPlaying = true;
        thread = new Thread(this);
        thread.start();

    }

    public void pause () {

        try {
            isPlaying = false;
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (event.getX() > screenX / 2 && event.getY() > screenY / 2) {
                    cat.isJumping = true;
                }
                if(joystick.isPressed((double) event.getX(), (double) event.getY())){
                    joystick.setIsPressed(true);
                }

                if(event.getX() >= mainMenuButton.getValue(1) &&
                        event.getX() <= mainMenuButton.getValue(3) &&
                            event.getY() >= mainMenuButton.getValue(2) &&
                                event.getY() <= mainMenuButton.getValue(4)) {
                    isPlaying = false;
                    activity.startActivity(new Intent(activity, MainActivity.class));
                    activity.finish();

                }
                break;

            case MotionEvent.ACTION_MOVE:
                if(joystick.getIsPressed()) {
                    joystick.setActuator((double) event.getX(), (double) event.getY());
                }
                break;

            case MotionEvent.ACTION_UP:
                joystick.setIsPressed(false);
                joystick.resetActuator();
                cat.isJumping = false;
                break;
        }
        return true;
    }
}

The call stack调用栈

virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference at com.example.combatcats.Joystick.getIsPressed(Joystick.java:86) at com.example.combatcats.GameView.onTouchEvent(GameView.java:187) at

tells you that in the method Joystick.getIsPressed you are trying to convert a Boolean object to a boolean by invoking booleanValue() on it, but that object is null .告诉您,在Joystick.getIsPressed方法中,您试图通过调用booleanValue()Boolean对象转换为boolean ,但该对象为null

You didn't show the code for Joystick but I suspect it looks something like this:您没有显示Joystick的代码,但我怀疑它看起来像这样:

class Joystick {
    Boolean pressed;

    void setIsPressed(boolean pressed){
       this.pressed = pressed;
    }

    boolean isPressed() {
        return pressed.getBooleanValue();
    }

The important part is that pressed doesn't get initialised on construction.重要的部分是pressed不会在构造时初始化。

If we inspect your GameView.onTouchEvent method you'll note that setIsPressed is invoked on ACTION_DOWN and ACTION_UP , while isPressed is invoked on ACTION_MOVE .如果我们检查您的GameView.onTouchEvent方法,您会注意到setIsPressedACTION_DOWNACTION_UP上调用,而isPressedACTION_MOVE上调用。

When you wait a little until the UI is fully initialized ACTION_MOVE will probably always happen after ACTION_DOWN and therefore everything is fine.当您等待 UI 完全初始化ACTION_MOVE可能总是在ACTION_DOWN之后发生,因此一切都很好。 But when spam clicking it might happen that the ACTION_DOWN event doesn't get forwarded to your view, because it is not ready yet. But但是当垃圾邮件点击时,可能会发生ACTION_DOWN event doesn't get forwarded to your view, because it is not ready yet. But ACTION_DOWN event doesn't get forwarded to your view, because it is not ready yet. But ACTION_MOVE is. Now this is the first event you process, ACTION_DOWN event doesn't get forwarded to your view, because it is not ready yet. But ACTION_MOVE is. Now this is the first event you process, is. Now this is the first event you process, pressed` is not yet initialized and you get the NPE you are seeing. is. Now this is the first event you process, pressed` 尚未初始化,您将获得您所看到的 NPE。

The solution is to either initialize pressed on construction of Joystick or even better: make it a primitive boolean in the first place.解决方案是在pressed的构造上初始化Joystick甚至更好:首先将其设为原始boolean

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么单击按钮后我的应用程序崩溃? - Why does my app crash when i click the button? 为什么开始新活动时我的android应用程序崩溃? - Why does my android application crash when starting a new activity? 尝试获取电话号码时,为什么我的活动崩溃了? - Why does my activity crash when I try to get a number? 当我单击片段 class 中的项目时,为什么我的应用程序会崩溃? - Why does my app crash when I click items in a Fragment class? Android教程-为什么当我尝试访问现有的文本视图时我的应用程序崩溃 - Android Tutorials — Why does my app crash when I try to access an existing Text View 为什么我的应用在第二次打开时会崩溃? - Why does my app crash when I open it for the second time? 单击运行时,Android Studio 模拟器未运行我的应用程序 - Android studio emulator is not running my app when I click run Android:为什么我尝试从网站检索信息时,我的Android应用程序为什么显示空白布局,然后崩溃? - Android: Why does my android app displays an empty layout then crash when I am trying to retrieve information from a website? 当我单击 go 此活动时,应用程序崩溃并出现 NullPointerException 致命异常 - App crash with FATAL EXCEPTION with NullPointerException when I click go this activity 当我尝试从Java桥接设备侦听模块时,为什么我的Android会立即响应本机应用程序崩溃 - Why does my Android react native app crash instantly when I try to bridge device listening modules from Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM