Domanda NullPointerException che non punta a nessuna riga nel mio codice


Sto lavorando a un gioco in cui il giocatore può trascinare e rilasciare oggetti sullo schermo. Ho un metodo privato che mi permette di simulare un evento drag / drop per qualsiasi oggetto che il giocatore può spostare. Per il trascinamento in realtà sto lasciando la vista che hanno toccato dov'è e creando un nuovo ImageView con e impostando il drawable alla drawingCache dalla vista toccata, quindi spostando questo ImageView appena creato sullo schermo seguendo il loro dito. Quando rilasci il dito (rilascia la vista) sto chiamando myLayout.remove(movingImg); per rimuoverlo dallo schermo. Sto riscontrando un problema in cui se avvio un evento di trascinamento simulato e poi prendo a mano uno degli altri oggetti che ottengo un puntatore nullo sulla chiamata myLayout.remove (), ecco la traccia di 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)

La traccia non punta in alcun punto all'interno della mia attività. L'eccezione viene generata ogni volta che tenta di chiamare myLayout.remove () nella vista di trascinamento simulata. Ho circondato questa linea con un try / catch ma non ha fatto nulla. So che questa è la linea che mi dà problemi perché se commento fuori non ho un'eccezione, ma ovviamente la mia vista non viene mai rimossa dallo schermo. Sto costruendo questa app su Motorola xoom, non sono sicuro che si tratti di un problema specifico del dispositivo. Qualcuno sa cosa potrebbe succedere qui?

Questo è il punto da cui viene chiamato .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;
        }
    });

Questo è all'interno di AnimationListener per l'animazione di traduzione che sta spostando il mio ImageView da dove inizia a dove viene "rilasciato"


44
2018-04-06 15:49


origine


risposte:


Android farà un'eccezione quando cambi la gerarchia della vista in animationEnd.

Tutto quello che devi fare è posticipare la tua chiamata in questo modo:

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

97
2017-09-16 13:38



La mia ipotesi è che si tratta di un problema multi-threading. Sembra che il ciclo di rendering Android interno stia incontrando un puntatore nullo a causa del fatto che hai rimosso l'immagine da un altro thread. La struttura dell'interfaccia utente Android è a thread singolo e tutte le modifiche all'interfaccia utente devono avvenire nel thread dell'interfaccia utente. Se questo è il problema che stai incontrando, puoi semplicemente delegare la tua chiamata al thread dell'interfaccia utente.

Ci sono alcune informazioni correlate qui: threading Android


0
2018-04-06 15:56



Puoi provare questo, per garantire che sia presente simulateMovingImg

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

0
2018-04-06 16:32



Ho incontrato questo problema dopo aver aggiornato l'appcompat-v7. L'ultima versione stabile della dipendenza sopra menzionata è ora:

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

0
2018-04-05 08:45



Ho leggermente modificato una risposta accettata (funziona anche) per evitare i gestori.

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

0
2017-12-07 07:54