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

我正在玩游戏,玩家可以在屏幕上拖放东西。 我有一个私人的方法,允许我模拟玩家可以移动的任何物品的拖放事件。 对于拖拽,我实际上将视图放在它们所在的位置,然后创build一个新的ImageView,并从触摸的视图中将drawable设置为drawingCache,然后将这个新创build的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(),就会引发exception。 我用try / catch来包围这条线,但是什么也没做。 我知道这是给我麻烦的线,因为如果我注释掉,那么我没有得到一个例外,但显然,我的观点永远不会从屏幕上删除。 我正在摩托罗拉xoom上构build这个应用程序,但我不确定这是否是特定于设备的问题。 有人知道这里可能会发生什么吗?

这是.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从开始位置移动到正在被“删除”的位置的翻译animation。

当您更改animationEnd中的视图层次结构时,Android将会发生exception。

所有你需要做的就是推迟你的电话这样的:

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

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

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

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

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

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

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

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

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