5

私のAndroidアプリでは、セットアップと読み込みを行うスプラッシュ画面があります。私のアプリはwindowEnterTransitionととwindowSharedElementExitTransitionとしてとchangeImageTransformchangeBoundsの遷移を設定してデフォルトのexplodeを使用しています。便宜上、私は次のActivityを静的メソッドを使って開始します。ここではActivityContextと共有要素として渡します。コードはこのポストの第2部で提供されています。ViewRootImpl.setPausedForTransition(boolean)他のアクティビティへの遷移が早すぎるとActivityTransitionCoordinatorのNullPointerExceptionが発生しました

シナリオの1つは、ロードするものがないということです。そのため、アプリケーションはすぐ次のActivityを起動します。問題は、この場合、アプリはActivityTransitionCoordinatorの中で何とか謎めいてクラッシュし、このポストの次の部分で与えられたスタックであるということです。内部のデバッグは、そこに達成されたViewRootImplがヌルでヌルチェックがないことを示しているので、viewRoot.setPausedForTransition(false)を呼び出すとNullPointerExceptionがスローされます。あなたは、この不都合な点を以下のコードで見つけることができます。

この失敗シナリオに焦点を当てて、ロードするものがないと判断し、次のActivityをすぐに開始するロジックを単純化して、前述のアクティビティを開始するだけで簡単に行うことができると仮定しましょう。

Activityの開始がonCreate()onResume()、又はonEnterAnimationComplete()方法で呼び出された場合には違いはありません。私は、遷移が終了したときにとgetWindow().getEnterTransition()を呼び出すことによって取得された遷移でリスナーを追加して、次のActivityの開始を許可しようとしました。与えられたTransitionsはnullではありませんが、appは接続されたリスナーのメソッドに決して行きません。

私が今使用している回避策は、次のActivityの呼び出しを遅らせるようにRunnableをスケジュールすることです。

これが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 
    } 
} 
+0

同様の質問に対する私のコメントを参照してください[http://stackoverflow.com/questions/36557479/...](http://stackoverflow.com/questions/36557479/conent-transition-npe-with-empty-共有要素#comment66253761_36557479) – Olumide

+0

@Olumide実際には、あなたの提案を適用すると私のアニメーションは動作しません。私の回避策はそれらを延期するが、少なくとも彼らは働く。申し訳ありません:( – mkoslacz

+0

それは私のために働くのでidk – Olumide

答えて

2

私はExplodeアクティビティの移行作業中にも同じ問題に直面しています。このコードはLollipopバージョンで正常に動作していますが、Lollipopの上でクラッシュしました。 私はクラッシュの理由を見つけることができません。しかし、私はそれを別の方法で解決します。ちょうどアクティビティの遷移が遅れてくる。私は以下のコードを与えました

public class SplashActivity extends AppCompatActivity { 

final Handler handler = new Handler(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_splash); 
    handler.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      navigate(); 
     } 
    },500); 
} 

private void navigate() { 
    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this); 
    Intent intent = new Intent(SplashActivity.this, MainActivity.class); 
    startActivity(intent, options.toBundle()); 
}} 

これをすべてのバージョンで正常に追加した後。

+0

まあ、それは私の質問で説明した回避策です。 – mkoslacz

関連する問題