NullPointerException, которая не указывает ни на одну строку в моем коде - PullRequest
45 голосов
/ 06 апреля 2011

Я работаю над игрой, в которой игрок может перетаскивать предметы по экрану. У меня есть приватный метод, который позволяет мне моделировать событие перетаскивания для любого из предметов, которые игрок может перемещать. Для перетаскивания я фактически оставляю вид, к которому они прикоснулись, и создаю новый 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 () в режиме имитации перетаскивания. Я окружил эту строку попыткой / уловом, но это ничего не сделало. Я знаю, что это линия, которая доставляет мне неприятности, потому что, если я закомментирую это, я не получу исключения, но, очевидно, тогда мой взгляд никогда не будет удален с экрана. Я создаю это приложение на 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 от того места, где он начинает, куда он «падает»

Ответы [ 5 ]

98 голосов
/ 16 сентября 2011

Android сделает исключение при изменении иерархии представления в animationEnd.

Все, что вам нужно сделать, это отложить ваш звонок следующим образом:

@Override
public void onAnimationEnd(Animation animation) {
    new Handler().post(new Runnable() {
        public void run() {
            myLayout.removeView(simulateMovingImg);
        }
    });
}
0 голосов
/ 07 декабря 2016

Я немного изменил принятый ответ (он также работает), чтобы избежать обработчиков.

@Override
public void onAnimationEnd(Animation animation) {
    imageView.post(new Runnable() {
        @Override
        public void run() {
            layout.removeView(imageView);
        }
    });
}
0 голосов
/ 05 апреля 2016

Я столкнулся с этой проблемой после обновления appcompat-v7. Последняя стабильная версия вышеупомянутой зависимости на данный момент:

  compile 'com.android.support:appcompat-v7:23.2.1'
0 голосов
/ 06 апреля 2011

Можете ли вы попробовать это, чтобы убедиться в наличии simulateMovingImg

    if (myLayout.indexOfChild() >= 0)
    {
        myLayout.removeView(simulateMovingImg);
    }
0 голосов
/ 06 апреля 2011

Я предполагаю, что это проблема многопоточности.Похоже, что внутренний цикл рендеринга Android сталкивается с нулевым указателем из-за того, что вы удалили изображение из другого потока.Структура пользовательского интерфейса Android является однопоточной, и все изменения в пользовательском интерфейсе должны происходить в потоке пользовательского интерфейса.Если это проблема, с которой вы столкнулись, тогда вы можете просто делегировать свой вызов потоку пользовательского интерфейса.

Здесь есть некоторая связанная информация: Threading для Android

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...