Attempt to read from field 'int android.view.View.mViewFlags' on a null object reference

前言

      我在做收到礼物 显示 动画,并在指定时间内自动划走的需求中,莫名其妙的遇到了如下异常,并没有定位到具体哪行出了问题,于是排除业务逻辑,查源码定位到问题所在。

问题代码:

    在动画结束回调onAnimationEnd()中remove view触发invalidate(),然后再dispatchDraw方法中的child.mViewFlag获取中抛出NullPointerException,继续寻找,函数getAndVerifyPreorderedView 来获取child,具体的参数情况,是 children 里的个数是1,但是childIndex是1,得到的结果肯定null。

@Override

    protected void dispatchDraw(Canvas canvas) {

        ...省略若干代码.....

        final int childrenCount = mChildrenCount;

        final View[] children = mChildren;

      ...省略若干代码.....

        // Only use the preordered list if not HW accelerated, since the HW pipeline will do the

        // draw reordering internally

        final ArrayList preorderedList = usingRenderNodeProperties

                ? null : buildOrderedChildList();

        final boolean customOrder = preorderedList == null

                && isChildrenDrawingOrderEnabled();

        for (int i = 0; i < childrenCount; i++) {

            while (transientIndex >= 0 && mTransientIndices.get(transientIndex) == i) {

                final View transientChild = mTransientViews.get(transientIndex);

                if ((transientChild.mViewFlags & VISIBILITY_MASK) == VISIBLE ||

                        transientChild.getAnimation() != null) {

                    more |= drawChild(canvas, transientChild, drawingTime);

                }

                transientIndex++;

                if (transientIndex >= transientCount) {

                    transientIndex = -1;

                }

            }

            final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);

            final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);

            //这里发生了空指针异常,child为null

            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {

                more |= drawChild(canvas, child, drawingTime);

            }

        }

        ...省略若干代码.....

  }   

解决办法:

知道了原因,再来解决就很简单了。以最开始的核心问题代码,来演示如何解决。问题出现remove view的时候,在dispatchDraw 中改变了viewGroup已有的子view的数量,导致只有N个view,最大索引是N-1,想要获取第N个view,出现了异常。那么我们可以考虑不在本次执行中,remove view。在下一次的loop消息中执行remove 操作,那么就通过post 或 handler 发送消息来操作view。


你可能感兴趣的:(Attempt to read from field 'int android.view.View.mViewFlags' on a null object reference)