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

时间:2011-04-06 15:49:13

标签: android layout view nullpointerexception

我正在开发一款游戏,玩家可以在屏幕上拖放东西。我有一个私有方法,允许我为玩家可以移动的任何项目模拟拖放事件。对于拖动,我实际上离开视图他们触摸它的位置并创建一个新的ImageView,并从触摸的视图中将drawable设置为drawingCache,然后在他们的手指上围绕屏幕移动这个新创建的ImageView。当你松开手指(放下视图)时,我正在呼叫myLayout.remove(movingImg);以使其脱离屏幕。我有一个问题,如果我开始一个模拟的拖动事件,然后手动拿起其他一个项目,我在myLayout.remove()调用上得到一个空指针,这里是来自日志的跟踪:

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包围了这一行,但没有做任何事情。我知道这是给我带来麻烦的线路,因为如果我发表评论然后我没有得到例外,但显然我的观点永远不会从屏幕上删除。我正在摩托罗拉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从它开始的位置移动到它被“删除”的位置

5 个答案:

答案 0 :(得分:98)

Android会在animationEnd中更改视图层次结构时出现异常。

您所要做的就是推迟拨打电话:

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

答案 1 :(得分:0)

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

此处有一些相关信息:android threading

答案 2 :(得分:0)

你可以尝试这个,以确保存在simulateMovingImg

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

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