开发者

NullPointerException that doesn't point to any line in my code

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'


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


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


Can you try this, to ensure that simulateMovingImg is present

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


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'


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜