Activity转换中使用SharedElement时崩溃问题

49

我正在使用ViewPager中的Activity转场(在调用的Activity中)与共享元素和内容转场。当重新返回到调用的Activity时,出现了以下崩溃:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.ResultReceiver.send(int, android.os.Bundle)' on a null object reference
  at android.app.EnterTransitionCoordinator.sendSharedElementDestination(EnterTransitionCoordinator.java:199)
  at android.app.EnterTransitionCoordinator.viewsReady(EnterTransitionCoordinator.java:123)
  at android.app.EnterTransitionCoordinator$2.onPreDraw(EnterTransitionCoordinator.java:148)
  at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:895)
  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2153)
  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1180)
  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6558)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
  at android.view.Choreographer.doCallbacks(Choreographer.java:590)
  at android.view.Choreographer.doFrame(Choreographer.java:560)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:145)
  at android.app.ActivityThread.main(ActivityThread.java:5832)
  at java.lang.reflect.Method.invoke(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)

另外,一旦返回,屏幕就开始持续闪烁,白屏不停地闪现。

以下是我的转场标志:

<item name="android:windowContentTransitions">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowAllowReturnTransitionOverlap">false</item>

我尝试在调用和被调用的活动上都设置进入/退出转换,但没有成功。


哇,这是一个新的问题。最好使用可以重现它的应用程序将其作为错误提交。似乎现有的活动以某种方式将ResultReceiver设置为null。如果您无法通过其他方式解决此问题,可以使用finish()而不是finishAfterTransition()来避免活动转换,但这非常奇怪。是否可能在重新启动活动时退出活动被杀死了? - George Mount
@GeorgeMount 不这么认为。如果 A 是调用的活动,B 是被调用的活动,那么当进入 B 时,我的日志如下所示:A: onPause B: onCreate B: onStart B: onResume B: onSaveInstanceState A: onStop - OferM
然后,当重新进入时,最好的情况是:A: onStart(崩溃在此处)B: onPause A: onResume B: onStop B: onDestroy。 - OferM
看起来像是一个奇怪的时间问题。虽然我没有复现它,但你可以尝试在Activity A的onActivityReenter方法中调用postponeEnterTransition(),然后等待ViewPager完成加载其内容(即所有片段均已加载)后再调用startPostponedEnterTransition()。我真的很希望有一个可重现的测试用例,这样我才能在框架中修复它。 - George Mount
1
在我的应用程序中,当从具有ViewPager的详细屏幕向后转换到显示过渡动画的共享ImageView的集合屏幕时,有时会出现相同的问题。 - Ankur
显示剩余3条评论
2个回答

1

尝试从FragmentManager获取片段:

fragmentManager.findFragmentByTag("android:switcher:" + R.id.viewPager + ":" + position)

如果片段为null,则尝试创建一个新的片段。

0

使用共享元素的活动转换有时会由于各种原因而导致崩溃。以下是一些常见的崩溃原因以及如何避免它们:

时间问题: 确保在转换开始之前,共享元素已经被正确地调整大小和布局。延迟转换的开始直到共享元素完全初始化可以防止崩溃。

名称不一致: 如果您正在使用活动之间的共享元素转换,请确保两个活动中共享元素的名称相同。名称不匹配可能会导致崩溃。

View.setTransitionName()的不当使用: 在使用共享元素转换时,为每个共享元素设置唯一的转换名称非常重要。如果两个共享元素具有相同的转换名称,则可能会发生崩溃。

OutOfMemoryErrors: 作为共享元素使用的大型图像或位图可能会导致OutOfMemoryErrors,从而导致崩溃。为了避免这种情况,请确保在将它们用作共享元素之前将图像或位图调整为较小的尺寸。

XML中缺少转换: 如果两个活动之间的转换没有在XML中定义,则可能会发生崩溃。请确保在XML中正确定义了转换,并且对于共享元素使用了正确的转换。

以下是一个避免时间问题的最佳示例:

private void startActivityWithSharedElement(Intent intent) {
    final ImageView sharedImageView = findViewById(R.id.shared_image_view);

    sharedImageView.getViewTreeObserver().addOnPreDrawListener(

        new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {

         sharedImageView.getViewTreeObserver().removeOnPreDrawListener(this);
         startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(
                                MainActivity.this, sharedImageView, "shared_image").toBundle());
                return true;
            }
        });
}

你是从ChatGPT上得到这个的吗?https://meta.stackoverflow.com/q/421831/11107541 - starball

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