在Android 5.0中,EnterTransitionCoordinator导致NPE。

15
在将退出和进入Activity的转换添加到应用程序之后,我收到如下崩溃报告:

致命异常:java.lang.NullPointerException: 尝试调用 'android.view.View.getParent()' 的虚拟方法 在空对象引用上 at android.view.ViewOverlay$OverlayViewGroup.add(ViewOverlay.java:164) at android.view.ViewGroupOverlay.add(ViewGroupOverlay.java:63) at android.app.EnterTransitionCoordinator.startRejectedAnimations(EnterTransitionCoordinator.java:598) at android.app.EnterTransitionCoordinator.startSharedElementTransition(EnterTransitionCoordinator.java:325) at android.app.EnterTransitionCoordinator.access$200(EnterTransitionCoordinator.java:42) at android.app.EnterTransitionCoordinator$5$1.run(EnterTransitionCoordinator.java:389) at android.app.ActivityTransitionCoordinator.startTransition(ActivityTransitionCoordinator.java:698) at android.app.EnterTransitionCoordinator$5.onPreDraw(EnterTransitionCoordinator.java:386) at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1985) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1077) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5845) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 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:5272) 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:909) at 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 的内部问题(堆栈中所有的系统类)?


2
我认为Play商店对于5.1版本有相同的检查。 - vRallev
这种情况是所有手机都会出现吗?我无法在版本为5.0.x的模拟器(genymotion)中复现它。 - ignacio_gs
这个问题不太容易重现。如果它适用于您的应用程序,请密切关注崩溃报告。 - Markus Junginger
3个回答

8

在要求转换的API级别为22(Android 5.1)后,崩溃问题已经解决。因此,这是最简单的解决方案。如果需要支持Android 5.0,请查看Nikola的答案(我们没有尝试过它,以避免额外的代码)。


5
这个 Android 操作系统的 bug 与共享元素过渡期间“被拒绝”的元素处理有关。如果共享元素未附加到窗口,可能会因其可见性设置为“GONE”而被拒绝(从过渡中排除)。
我使用的解决方法是在调用 makeSceneTransitionAnimation() 之前检查每个潜在的共享元素视图,并仅在其可见性设置为“VISIBLE”时将其包含在列表中。

不仅仅是可见的视图。你应该只将在第一个和第二个活动中呈现的视图放入makeSceneTransitionAnimation方法中。我放了一些只在第一个活动中的视图,这导致了崩溃。 - Deni Erdyneev

4

对于低于API 5.1的版本,请使用postponeEnterTransition()延迟共享元素转换。在装饰视图(也许是内容视图android.R.id.content)或者内容视图的ViewTreeObserver上注册一个OnDrawListener监听器,一旦调用了onDraw()方法就开始执行转换。别忘了在开始转换后取消注册该监听器。


3
当我执行这个操作时,OnDraw() 没有被调用。 - Boy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接