15

After adding exit and enter Activity transitions to an app, I am getting crash reports like the following:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewParent android.view.View.getParent()' on a null object reference 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)

It's not reproducible, but the crash count is significant.

Doing some research, I came across this commit suggesting it is (was actually) an internal error in Android: https://android.googlesource.com/platform/frameworks/base/+/83c692efd3c53050fce132dfd2ef21763d3cf010%5E%21/#F0

All crash reports are either 5.0, 5.0.1, or 5.0.2. Because 5.1 has wider spread, but does not show crashes, it seems like EnterTransitionCoordinator was fixed in 5.1.

So, a possible solution would be to check for API level 22 or higher, and only do the transitions then. However I wonder if there's a better way; some workaround maybe, despite this seems to be an internal matter of Android (all system classes in the stack)?

Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
Markus Junginger
  • 6,950
  • 31
  • 52

3 Answers3

8

After requiring API level 22 (Android 5.1) for transition, the crashes are gone. So this is the most simple solution. If you need to support this with Android 5.0, check Nikola's answer (we did not try it ourselves to avoid additional code).

Markus Junginger
  • 6,950
  • 31
  • 52
5

This Android OS bug relates to the handling of 'rejected' elements during the shared element transition. A shared element will be rejected (excluded from the transition) if it isn't attached to the window, which could happen because its visibility is set to GONE.

The workaround I'm using is to check each potential shared element view before calling makeSceneTransitionAnimation(), and only include it in the list if it's visibility is set to VISIBLE.

Glenn Schmidt
  • 623
  • 8
  • 9
  • Not only visible. You should put only that views into `makeSceneTransitionAnimation` method, which presented in first and second activity. I put views that were only in first activity and it causes the crash – Deni Erdyneev Jul 03 '18 at 06:50
4

For lower than API than 5.1, postpone shared element transition using postponeEnterTransition(). Register a listener OnDrawListener to the ViewTreeObserver of the decor view (perhaps) or content view (android.R.id.content) and start the transition once onDraw() is called. Don't forget to unregister the listener, once you start the transition.

Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148