ViewRootImpl.setPausedForTransition (boolean) NullPointerException в ActivityTransitionCoordinator при переходе на другую активность, вызванную слишком рано

В моем приложении для Android у меня есть заставка, где я делаю некоторые настройки и загрузку. Мое приложение использует по умолчанию windowEnterTransition как windowEnterTransition и windowExitTransition а changeImageTransform плюс changeBounds переход, заданный как windowSharedElementEnterTransition и windowSharedElementExitTransition . Для удобства я запускаю следующее действие, используя статический метод, в котором передаю текущую Activity как Context и общий элемент. Код представлен во второй части этого сообщения.

Один из сценариев заключается в том, что загружать нечего, поэтому приложение почти сразу запускает следующее действие. Проблема в том, что в этом случае приложение каким-то образом загадочно сбой в ActivityTransitionCoordinator со стеком, указанным в следующей части этого сообщения. Отладка внутренних ViewRootImpl показывает, что ViewRootImpl который был достигнут, имеет значение null и нет нулевой проверки, поэтому viewRoot.setPausedForTransition(false) NullPointerException . Вы можете найти это несчастливое пятно, отмеченное в коде ниже.

Чтобы сосредоточиться на этом неудачном сценарии, давайте сделаем предположение, что логика, решающая, что загружать нечего, и следующее действие должно быть начато сразу, настолько просто, что можно упростить только начало указанной деятельности.

Не имеет значения, запускается ли вторая onCreate() в onCreate() , onResume() или onEnterAnimationComplete() . Я даже попробовал добавить слушателя на переход, полученный вызовом getWindow().getSharedElementEnterTransition() и getWindow().getEnterTransition() разрешено запускать следующее действие при завершении переходов. Данные Transitions не ноль, но приложение никогда не переходит в методы подключенных слушателей.

Обходной путь, который я использую сейчас, – это просто запланировать Runnable чтобы вызвать последующее Activity .

Мне интересно, не проблема ли это в Android (проблема с поддержкой SupportLibrary ), или я что-то пропустил. Кто-нибудь сталкивался с подобной проблемой?

Столбец:

 08-12 00:35:32.550 26453-26453/com.faver.mkoslacz.faverdemo E/AndroidRuntime: FATAL EXCEPTION: main Process: com.faver.mkoslacz.faverdemo, PID: 26453 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.ViewRootImpl.setPausedForTransition(boolean)' on a null object reference at android.app.ActivityTransitionCoordinator.startInputWhenTransitionsComplete(ActivityTransitionCoordinator.java:897) at android.app.ActivityTransitionCoordinator.viewsTransitionComplete(ActivityTransitionCoordinator.java:885) at android.app.ExitTransitionCoordinator.getExitTransition(ExitTransitionCoordinator.java:318) at android.app.ExitTransitionCoordinator.beginTransitions(ExitTransitionCoordinator.java:365) at android.app.ExitTransitionCoordinator.-wrap0(ExitTransitionCoordinator.java) at android.app.ExitTransitionCoordinator$4.run(ExitTransitionCoordinator.java:216) at android.app.ActivityTransitionCoordinator.startTransition(ActivityTransitionCoordinator.java:773) at android.app.ExitTransitionCoordinator.startExit(ExitTransitionCoordinator.java:213) at android.app.ActivityTransitionState.startExitOutTransition(ActivityTransitionState.java:317) at android.app.Activity.cancelInputsAndStartExitTransition(Activity.java:3960) at android.app.Activity.startActivityForResult(Activity.java:3936) at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48) at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:75) at android.app.Activity.startActivity(Activity.java:4196) at com.faver.mkoslacz.faverdemo.activity.AuthorizationActivity.startWithTransiton(AuthorizationActivity.java:45) at com.faver.mkoslacz.faverdemo.activity.SplashActivity.onEnterAnimationComplete(SplashActivity.java:27) at android.app.Activity.dispatchEnterAnimationComplete(Activity.java:5852) at android.app.ActivityThread.handleEnterAnimationComplete(ActivityThread.java:2668) at android.app.ActivityThread.-wrap10(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1558) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Ошибка кода в ActivityTransitionAnimator :

 private void startInputWhenTransitionsComplete() { if (mViewsTransitionComplete && mSharedElementTransitionComplete) { final View decor = getDecor(); if (decor != null) { final ViewRootImpl viewRoot = decor.getViewRootImpl(); // it's null viewRoot.setPausedForTransition(false); // crashes here } onTransitionsComplete(); } } 

Способ, начинающийся с следующего Activity :

 public static void startWithTransiton(Activity activity, android.view.View logo) { Intent intent = new Intent(activity, AuthorizationActivity.class); ActivityOptionsCompat options = ActivityOptionsCompat .makeSceneTransitionAnimation( activity, logo, activity.getString(R.string.logoTransfer)); activity.startActivity(intent, options.toBundle()); } 

Элемент Activity всплеска (упрощенный):

 public class SplashActivity extends AppCompatActivity { private static final String TAG = "SplashActivity"; private View logo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); logo = findViewById(R.id.logo); // AuthorizationActivity.startWithTransiton(this, logo); // will fail new Handler().postDelayed(() -> { AuthorizationActivity.startWithTransiton(this, logo); // executes flawlessly }, 300); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition(); if (sharedElementEnterTransition != null) { sharedElementEnterTransition.addListener(new Transition.TransitionListener() { @Override public void onTransitionStart(Transition transition) { Log.d(TAG, "onTransitionStart: never executes"); } @Override public void onTransitionEnd(Transition transition) { Log.d(TAG, "onTransitionEnd: never executes"); } @Override public void onTransitionCancel(Transition transition) { Log.d(TAG, "onTransitionCancel: never executes"); } @Override public void onTransitionPause(Transition transition) { Log.d(TAG, "onTransitionPause: never executes"); } @Override public void onTransitionResume(Transition transition) { Log.d(TAG, "onTransitionResume: never executes"); } }); } Transition enterTransition = getWindow().getEnterTransition(); if (enterTransition != null) { enterTransition.addListener(new Transition.TransitionListener() { @Override public void onTransitionStart(Transition transition) { Log.d(TAG, "onTransitionStart: never executes"); } @Override public void onTransitionEnd(Transition transition) { Log.d(TAG, "onTransitionEnd: never executes"); } @Override public void onTransitionCancel(Transition transition) { Log.d(TAG, "onTransitionCancel: never executes"); } @Override public void onTransitionPause(Transition transition) { Log.d(TAG, "onTransitionPause: never executes"); } @Override public void onTransitionResume(Transition transition) { Log.d(TAG, "onTransitionResume: never executes"); } }); } } } @Override protected void onResume() { super.onResume(); // AuthorizationActivity.startWithTransiton(this, logo); // will fail } @Override public void onEnterAnimationComplete() { super.onEnterAnimationComplete(); // AuthorizationActivity.startWithTransiton(this, logo); // will fail } }