NullPointerException 不指向我的代码中的任何行

发布于 2024-10-31 08:48:08 字数 4626 浏览 1 评论 0原文

我正在开发一款游戏,玩家可以在屏幕上拖放东西。我有一个私有方法,它允许我模拟玩家可以移动的任何项目的拖/放事件。对于拖动,我实际上将他们触摸的视图留在原处,并创建一个新的 ImageView,并将可绘制对象设置为触摸视图中的绘图缓存,然后按照他们的手指在屏幕上移动这个新创建的 ImageView。当您松开手指(放下视图)时,我将调用 myLayout.remove(movingImg); 来将其从屏幕上移开。我遇到一个问题,如果我启动模拟拖动事件,然后手动拾取其他项目之一,我会在 myLayout.remove() 调用上得到一个空指针,这是来自 Log 的跟踪:

04-06 10:37:43.610: ERROR/AndroidRuntime(23203): java.lang.NullPointerException
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2122)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.View.draw(View.java:9032)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.widget.FrameLayout.draw(FrameLayout.java:419)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1910)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.draw(ViewRoot.java:1608)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1329)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1944)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.os.Looper.loop(Looper.java:126)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.app.ActivityThread.main(ActivityThread.java:3997)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at java.lang.reflect.Method.invokeNative(Native Method)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at java.lang.reflect.Method.invoke(Method.java:491)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at dalvik.system.NativeStart.main(Native Method)

跟踪不指向我活动中的任何位置。每当它尝试在模拟拖动视图上调用 myLayout.remove() 时,都会引发异常。我用 try / catch 包围了这条线,但什么也没做。我知道这一行给我带来了麻烦,因为如果我将其注释掉,那么我不会得到异常,但显然我的视图永远不会从屏幕上删除。我正在 Motorola xoom 上构建此应用程序,但我不确定这是否是设备特定的问题。有谁知道这里会发生什么?

这是 .removeView() 被调用的地方:

        @Override
        public void onAnimationEnd(Animation animation) {
            // TODO Auto-generated method stub
            Log.i(myTag, "Animation End");

            try {
                //myLayout.removeView(simulateMovingImg); //This is the line that is throwing a null pointer
                simulateMovingImg.setVisibility(View.GONE); //This is how I am currently getting around the issue
                params = new LayoutParams(oneImg.getWidth(),oneImg.getHeight()); // While its moving it appears larger than normal
                 simulateMovingImg.setLayoutParams(params);                     //  so I set it back to the normal size
                 if(whichTarget == true){
                     targetImg.setImageDrawable(simulateMovingImg.getDrawable()); //targetImg is one of the 'drop zones' so I set its 
                                                                                //  drawable to make it seem like the view was 'dropped' into this zone
                 }else{
                     target1Img.setImageDrawable(simulateMovingImg.getDrawable()); // same with target1Img. 
                 }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

             iAmDone = true;
        }
    });

它位于翻译动画的 AnimationListener 内,该动画将我的 ImageView 从开始的位置移动到“丢弃”的位置

I am working on a game where the player can drag and drop things around the screen. I've got a private method which allows me to simulate a drag/drop event for any of the items that the player can move around. For the dragging I am actually leaving the view that they touched where it is and creating a new ImageView with and setting the drawable to the drawingCache from the touched view, then moving this newly created ImageView around the screen following their finger. When you release your finger (drop the view) I am calling myLayout.remove(movingImg); to get it off of the screen. I am having an issue where if I start a simulated drag event and then manually pick up one of the other items I am getting a null pointer on the myLayout.remove() call, here is the trace from Log:

04-06 10:37:43.610: ERROR/AndroidRuntime(23203): java.lang.NullPointerException
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2122)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.View.draw(View.java:9032)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.widget.FrameLayout.draw(FrameLayout.java:419)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1910)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.draw(ViewRoot.java:1608)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1329)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1944)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.os.Looper.loop(Looper.java:126)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.app.ActivityThread.main(ActivityThread.java:3997)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at java.lang.reflect.Method.invokeNative(Native Method)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at java.lang.reflect.Method.invoke(Method.java:491)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at dalvik.system.NativeStart.main(Native Method)

The trace doesn't point to anywhere inside my activity. The exception gets thrown whenever the it tries to call myLayout.remove() on the simulated dragging view. I surrounded this line with a try / catch but that did nothing. I know that this is the line thats giving me trouble because if I comment it out then I don't get an exception but obviously then my view never gets removed from the screen. I am building this app on a Motorola xoom, I am not sure if this is a device specific issue or not though. Does anyone know what might be going on here?

This is the where the .removeView() is getting called from:

        @Override
        public void onAnimationEnd(Animation animation) {
            // TODO Auto-generated method stub
            Log.i(myTag, "Animation End");

            try {
                //myLayout.removeView(simulateMovingImg); //This is the line that is throwing a null pointer
                simulateMovingImg.setVisibility(View.GONE); //This is how I am currently getting around the issue
                params = new LayoutParams(oneImg.getWidth(),oneImg.getHeight()); // While its moving it appears larger than normal
                 simulateMovingImg.setLayoutParams(params);                     //  so I set it back to the normal size
                 if(whichTarget == true){
                     targetImg.setImageDrawable(simulateMovingImg.getDrawable()); //targetImg is one of the 'drop zones' so I set its 
                                                                                //  drawable to make it seem like the view was 'dropped' into this zone
                 }else{
                     target1Img.setImageDrawable(simulateMovingImg.getDrawable()); // same with target1Img. 
                 }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

             iAmDone = true;
        }
    });

That is inside an AnimationListener for the translate animation that is moving my ImageView from where it starts to where it is getting 'dropped'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

少跟Wǒ拽 2024-11-07 08:48:08

当您在animationEnd中更改视图层次结构时,Android会抛出异常。

您所要做的就是像这样推迟您的通话:

@Override
public void onAnimationEnd(Animation animation) {
    new Handler().post(new Runnable() {
        public void run() {
            myLayout.removeView(simulateMovingImg);
        }
    });
}

Android will make an exception when you change the view hierarchy in animationEnd.

All you have to do is to postpone your call like this :

@Override
public void onAnimationEnd(Animation animation) {
    new Handler().post(new Runnable() {
        public void run() {
            myLayout.removeView(simulateMovingImg);
        }
    });
}
若水微香 2024-11-07 08:48:08

我的猜测是这是一个多线程问题。由于您从另一个线程中删除了图像,内部 Android 渲染循环似乎遇到了空指针。 Android UI 框架是单线程的,对 UI 的所有修改都必须在 UI 线程中进行。如果这是您遇到的问题,那么您可以将调用委托给 UI 线程。

这里有一些相关信息: android 线程

My guess is that it is a multi threading problem. It looks like the internal android render loop is encountering a null pointer due to the fact that you removed the image from another thread. The Android UI framework is single threaded and all modifications to the UI must happen in the UI thread. If this is the problem you are encountering then you can just delegate your call to the UI thread.

There is some related information here: android threading

茶底世界 2024-11-07 08:48:08

您可以尝试一下,以确保存在simulateMovingImg

    if (myLayout.indexOfChild() >= 0)
    {
        myLayout.removeView(simulateMovingImg);
    }

Can you try this, to ensure that simulateMovingImg is present

    if (myLayout.indexOfChild() >= 0)
    {
        myLayout.removeView(simulateMovingImg);
    }
十秒萌定你 2024-11-07 08:48:08

我更新appcompat-v7后遇到了这个问题。上述依赖项目前最新的稳定版本是:

  compile 'com.android.support:appcompat-v7:23.2.1'

I met this issue after I updated the appcompat-v7. The latest stable version of the above-mentioned dependency to now is:

  compile 'com.android.support:appcompat-v7:23.2.1'
岛歌少女 2024-11-07 08:48:08

我稍微改变了接受的答案(它也有效)以避免处理程序。

@Override
public void onAnimationEnd(Animation animation) {
    imageView.post(new Runnable() {
        @Override
        public void run() {
            layout.removeView(imageView);
        }
    });
}

I slightly changed an accepted answer (it also works) to avoid handlers.

@Override
public void onAnimationEnd(Animation animation) {
    imageView.post(new Runnable() {
        @Override
        public void run() {
            layout.removeView(imageView);
        }
    });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文