美文网首页
Attempt to read from field 'int

Attempt to read from field 'int

作者: thomasyoungs | 来源:发表于2020-06-23 15:01 被阅读0次

    前言

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

    问题代码:

        在动画结束回调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<View> 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

          本文链接:https://www.haomeiwen.com/subject/wikhfktx.html