web-dev-qa-db-fra.com

Android Blocage de ViewGroup: tentative de lecture à partir du champ 'int Android.view.View.mViewFlags' sur une référence d'objet null

Nous avons trouvé plusieurs cas pour ce type de plantages signalés par la surveillance de la journalisation du backend. Il semble que les plantages ne soient pas liés à une défaillance UX particulière. Et à partir des rapports, il n'y a aucun signe de la façon dont nos propres classes sont impliquées (aucun signe de l'un des noms de nos classes). Voici un exemple de plantages typiques:

Java.lang.NullPointerException: Attempt to read from field 'int Android.view.View.mViewFlags' on a null object reference 
at Android.view.ViewGroup.dispatchDraw(ViewGroup.Java:3357) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14288) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ViewGroup.recreateChildDisplayList(ViewGroup.Java:3549) 
at Android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.Java:3528) 
at Android.view.View.updateDisplayListIfDirty(View.Java:14253) 
at Android.view.View.getDisplayList(View.Java:14315) 
at Android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.Java:273) 
at Android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.Java:279) 
at Android.view.ThreadedRenderer.draw(ThreadedRenderer.Java:318) 
at Android.view.ViewRootImpl.draw(ViewRootImpl.Java:2561) 
at Android.view.ViewRootImpl.performDraw(ViewRootImpl.Java:2377) 
at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:2007) 
at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:1086) 
at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:6453) 
at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:846) 
at Android.view.Choreographer.doCallbacks(Choreographer.Java:647) 
at Android.view.Choreographer.doFrame(Choreographer.Java:601) 
at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:829) 
at Android.os.Handler.handleCallback(Handler.Java:739) 
at Android.os.Handler.dispatchMessage(Handler.Java:95) 
at Android.os.Looper.loop(Looper.Java:135) 
at Android.app.ActivityThread.main(ActivityThread.Java:5254) 
at Java.lang.reflect.Method.invoke(Native Method) 
at Java.lang.reflect.Method.invoke(Method.Java:372) 
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:927) 
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:713) 

Est-ce que quelqu'un sait s'il y a un bogue connexe contre Android code?

59
M2014

Solution possible

J'ai eu ce même problème. J'ai installé un animation et dans onAnimationEnd je supprimais l'objet qui avait été animé, c'est à ce moment que les problèmes ont commencé. Ce que j'ai fait a été de configurer un asynchrone Runnable pour attendre 100 millisecondes après l'arrêt de l'animation avant de supprimer l'objet animé:

l'objet précédemment animé est this._loader

private void removeLoader() {
    final ContentContainer self = this; // "CustomContainer" needs to match the type of `this`
    Handler h = new Handler();
    h.postAtTime(new Runnable() {
        @Override
        public void run() {
            MainActivity.instance.runOnUiThread(new Runnable() { 
                @Override
                public void run() {
                    try {
                        if(self._loader == null) {
                            // there is no loader. quit now while you still have the chance!!
                            return;
                        }
                        while(self._loader.getParent() != null) {
                            removeView(self._loader);
                        }
                    } catch(Exception e) {
                        Crashlytics.logException(e);
                        e.printStackTrace();
                    }

                    self._loader = null;
                }
            });
        }
    }, 100);
}

Acclamations

25
Jacksonkr

J'étais confronté au même problème. J'ai résolu avec Handler.

new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                   // remove fragment from here
                }
            });
11
Pawan Chaurasiya

Le problème vient de la méthode dispatchDraw() de ViewGroup. Cette méthode essaie de dessiner tous les enfants de ViewGroup. Quand un enfant est null, vous obtenez une exception, qui vient très probablement de cette ligne : if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) { (notez le mViewFlags).

Le problème est donc que l'un de vos points de vue, quelque part, n'est pas correctement initialisé. J'ai bien peur que ce soit le mieux que je puisse faire.

9
kevinpelgrims

Nous avons également commencé à obtenir cette erreur de manière inattendue. Il a été retrouvé pour fragmenter les animations étant le problème. Plus spécifiquement, utiliser des animations personnalisées avec replace() dans une transaction de fragment lorsque l'application est construite sur Local Maven repository for Support Libraries rev> 26.

Solution possible

Rétrograder Local Maven repository for Support Libraries à rev 26. Voir ici

4
veritas1

Cause possible: J'avais exactement le même problème. Il s'est avéré que cela a commencé à se produire lorsque j'ai ajouté du code pour modifier l'arborescence d'affichage dans l'appel onDraw (). Pour être précis, j'ai supprimé une vue avec des enfants dans mon onDraw () dérivé lorsque certaines conditions étaient remplies. Je pense maintenant que c'est une mauvaise chose à faire, probablement parce que la plate-forme essaie de dessiner des vues que j'ai maintenant supprimées de l'arborescence des vues. J'ai résolu le problème en publiant la suppression avec Runnable pour se produire après la fin de l'appel à onDraw ().

2
Teemu Lätti

Même si l'exception est courante, la source causale est rare et se produit lorsque vous avez autant de vues dynamiques. Parfois, le défilement dans la page Instagram provoque cette exception. Cependant, si vous regardez en profondeur, le problème matériel peut devenir un problème . Il suffit donc de gérer (catch) le problème.

0
Pradeep

Remplacez la méthode dispatchDraw et mettez-y un bloc try/catch, comme ceci:

public void dispatchDraw(Canvas c)
    {
        try
        {
            super.dispatchDraw(c);
            return;

        }
        catch(Exception exception)
        {
            return;
        }
    }
0