Android:与createCircularReveal相关的IllegalStateException

时间:2017-09-08 08:17:12

标签: android

我的应用程序收到了一些崩溃报告,如下所示:

java.lang.IllegalStateException: 
  at android.view.RenderNode.addAnimator (RenderNode.java:817)
  at android.view.RenderNodeAnimator.setTarget (RenderNodeAnimator.java:277)
  at android.view.RenderNodeAnimator.setTarget (RenderNodeAnimator.java:261)
  at android.animation.RevealAnimator.<init> (RevealAnimator.java:37)
  at android.view.ViewAnimationUtils.createCircularReveal (ViewAnimationUtils.java:48)
  at com.example.myapp.MyConfigureActivity$8.run (MyConfigureActivity.java)
  at android.os.Handler.handleCallback (Handler.java:739)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:211)
  at android.app.ActivityThread.main (ActivityThread.java:5335)
  at java.lang.reflect.Method.invoke (Method.java)
  at java.lang.reflect.Method.invoke (Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1016)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:811)

我在我的Activity中使用以下函数来使视图可见(带动画)或使视图消失(再次,使用动画):

public class MyConfigureActivity extends AppCompatActivity {

    static private Integer lastXup;
    static private Integer lastYup;

    void animateView(final View view, final int visibility) {
        final int duration = 250;

        view.post(new Runnable()
        {
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void run()
            {
                // get the center for the clipping circle
                int w = view.getWidth();
                int h = view.getHeight();
                int cx = (lastXup == null) ? w/2 : lastXup;
                int cy = (lastYup == null) ? h/2 : 0;

                // get the final radius for the clipping circle
                float r = Math.max(cx, w-cx);

                Animator anim;

                if (visibility == View.VISIBLE) {
                    // create the animator for this view (the start radius is zero)
                    anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, 0, r);
                    // make the view visible before starting the animation
                    view.setVisibility(View.VISIBLE);
                } else {
                    // create the animation (the final radius is zero)
                    anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, r, 0);

                    // make the view GONE when the animation is finished
                    anim.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            super.onAnimationEnd(animation);
                            view.setVisibility(View.GONE);
                        }
                    });

                }
                anim.setDuration(duration);
                anim.start();
            }
        });
    }

    // https://stackoverflow.com/a/11001443/4070848
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int eventaction = event.getAction();

        switch (eventaction) {
            case MotionEvent.ACTION_UP:
                lastXup = (int) event.getRawX();
                lastYup = (int) event.getRawY();
                break;
            default:
                break;
        }

        return super.dispatchTouchEvent(event);
    }
}

这似乎在绝大多数设备上运行良好,我从来没有能够重现崩溃,但仍有大量的崩溃报告。知道可能是什么原因吗?

1 个答案:

答案 0 :(得分:1)

查看RenderNode的源代码,您可以在addAnimator中找到可能引发异常的内容:

if (mOwningView == null || mOwningView.mAttachInfo == null) {
    throw new IllegalStateException("Cannot start this animator on a detached view!");
}

因此,当应用程序关闭和/或当前活动正在关闭时启动动画时应出现错误,或者出于其他原因删除了视图 - 添加对案例的检查(例如在{{中设置一些变量isAnimationAllowed = false)在onPause中,1}}和isAnimationAllowed = true。