EnterTransitionCoordinator 在 Android 5.0 中导致 NPE
Posted
技术标签:
【中文标题】EnterTransitionCoordinator 在 Android 5.0 中导致 NPE【英文标题】:EnterTransitionCoordinator causes NPE in Android 5.0 【发布时间】:2016-04-12 01:34:14 【问题描述】:向应用添加退出和进入 Activity 转换后,我收到如下崩溃报告:
致命异常:java.lang.NullPointerException:尝试调用 虚拟方法'android.view.ViewParent android.view.View.getParent()' 在空对象引用上 在 android.view.ViewOverlay$OverlayViewGroup.add(ViewOverlay.java:164) 在 android.view.ViewGroupOverlay.add(ViewGroupOverlay.java:63) 在 android.app.EnterTransitionCoordinator.startRejectedAnimations(EnterTransitionCoordinator.java:598) 在 android.app.EnterTransitionCoordinator.startSharedElementTransition(EnterTransitionCoordinator.java:325) 在 android.app.EnterTransitionCoordinator.access$200(EnterTransitionCoordinator.java:42) 在 android.app.EnterTransitionCoordinator$5$1.run(EnterTransitionCoordinator.java:389) 在 android.app.ActivityTransitionCoordinator.startTransition(ActivityTransitionCoordinator.java:698) 在 android.app.EnterTransitionCoordinator$5.onPreDraw(EnterTransitionCoordinator.java:386) 在 android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847) 在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1985) 在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1077) 在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5845) 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) 在 android.view.Choreographer.doCallbacks(Choreographer.java:580) 在 android.view.Choreographer.doFrame(Choreographer.java:550) 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:135) 在 android.app.ActivityThread.main(ActivityThread.java:5272) 在 java.lang.reflect.Method.invoke(Method.java) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
这是不可重现的,但崩溃计数很重要。
做了一些研究,我发现这个提交表明它是(实际上是)Android 中的一个内部错误: https://android.googlesource.com/platform/frameworks/base/+/83c692efd3c53050fce132dfd2ef21763d3cf010%5E%21/#F0
所有崩溃报告都是 5.0、5.0.1 或 5.0.2。由于 5.1 传播范围更广,但不显示崩溃,看来 EnterTransitionCoordinator 在 5.1 中已修复。
因此,一种可能的解决方案是检查 API 级别 22 或更高级别,然后仅执行转换。但是我想知道是否有更好的方法;可能有一些解决方法,尽管这似乎是 Android 的内部问题(堆栈中的所有系统类)?
【问题讨论】:
我认为 Play 商店对 5.1 有相同的检查。 所有移动设备都会出现这种情况吗?我无法使用 5.0.x 版的模拟器 (genymotion) 重现它 这不是真正可重现的。如果它适用于您的应用,请密切关注您的崩溃报告。 【参考方案1】:在要求 API 级别 22 (Android 5.1) 进行转换后,崩溃消失了。所以这是最简单的解决方案。如果您需要在 Android 5.0 中支持此功能,请查看 Nikola 的回答(我们自己没有尝试过以避免额外的代码)。
【讨论】:
【参考方案2】:此 Android 操作系统错误与共享元素转换期间“被拒绝”元素的处理有关。如果共享元素未附加到窗口,将被拒绝(从过渡中排除),这可能是因为它的可见性设置为GONE
。
我正在使用的解决方法是在调用 makeSceneTransitionAnimation()
之前检查每个潜在的共享元素视图,并且仅在其可见性设置为 VISIBLE
时将其包含在列表中。
【讨论】:
不仅可见。您应该只将这些视图放入makeSceneTransitionAnimation
方法中,该方法在第一个和第二个活动中呈现。我放置了仅在第一个活动中的视图,它会导致崩溃【参考方案3】:
对于低于 5.1 的 API,使用 postponeEnterTransition()
推迟共享元素转换。将侦听器OnDrawListener
注册到装饰视图(可能)或内容视图(android.R.id.content
)的ViewTreeObserver
,并在调用onDraw()
后开始转换。开始转换后,不要忘记取消注册侦听器。
【讨论】:
当我这样做时,OnDdraw()
永远不会被调用。以上是关于EnterTransitionCoordinator 在 Android 5.0 中导致 NPE的主要内容,如果未能解决你的问题,请参考以下文章