ViewRootImpl.setPausedForTransition(boolean) 当过早转换到其他 Activity 时,ActivityTransitionCoordinator 中出现 NullPointerException

2024-04-12

在我的 Android 应用程序中,我有一个启动屏幕,我可以在其中进行一些设置和加载。我的应用程序使用默认值explode as a windowEnterTransition and a windowExitTransition and a changeImageTransform plus changeBounds过渡集为windowSharedElementEnterTransition and windowSharedElementExitTransition。为了方便,我开始下一个Activity使用静态方法传递当前的Activity as a Context和一个共享元素。该代码在本文的第二部分中提供。

其中一种情况是没有任何内容可加载,因此应用程序几乎立即触发下一个Activity。问题是,在这种情况下,应用程序莫名其妙地崩溃了ActivityTransitionCoordinator以及本文下一部分中给出的堆栈。内部调试表明ViewRootImpl实现的是 null 并且没有 null 检查,因此调用viewRoot.setPausedForTransition(false)抛出一个NullPointerException。您可以在下面的代码中找到标记的这个不幸的地方。

为了关注这个失败的场景,让我们假设一个逻辑决定没有什么可以加载,并且下一个Activity应该立即开始是如此简单,以至于可以简化为仅开始所提到的活动。

如果第二个开始也没有什么区别Activity被调用于onCreate(), onResume(), or onEnterAnimationComplete()方法。我什至尝试在通过调用获取的 Transition 上添加监听器getWindow().getSharedElementEnterTransition() and getWindow().getEnterTransition()被允许开始下一个Activity当转换完成时。给定的Transitions不为空,但应用程序永远不会进入附加侦听器的方法。

我现在使用的解决方法只是安排一个Runnable调用下一个Activity延迟。

我想知道这是否是一个Android (a 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
    }
}

我在使用爆炸活动转换时也面临同样的问题,我发现此代码在 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());
}}

添加此功能后,在所有版本中都可以正常工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ViewRootImpl.setPausedForTransition(boolean) 当过早转换到其他 Activity 时,ActivityTransitionCoordinator 中出现 NullPointerException 的相关文章

随机推荐

  • 从 Delphi 将列表导出到 OpenOffice Calc

    我正在使用 Delphi 7 我想使用自动化而不是使用文件将列表内容从我的程序导出到 OpenOffice Calc 任务很简单 创建新文档 迭代行 列并更改单元格数据 我找到了一些代码 但它并不完整 我希望有人有一些示例代码可以完成这个非
  • 将 Python 安装到自托管 Windows 构建代理

    我已经安装了 Windows 代理 并且需要能够运行 Python 脚本 我知道我需要安装Python 但我不知道如何安装 我将标准安装中的 Python 文件添加到 AGENT TOOLSDIRECTORY Python 3 8 2 x6
  • Swift 的 Facebook 登录按钮

    在 Xcode 中 如果我创建一个UIView然后将自定义类添加为FBSDKLoginButton 当我单击时 它会引导我完成 Facebook 登录 然后返回到与FBSDKLoginButton但不是说登录按钮 而是说现在注销 当单击登录
  • 使用装饰器恢复生成器

    让我们有一个类 它的功能有时会失败 但经过一些操作后它就可以完美地工作 现实生活中的例子是 Mysql 查询 它会引发 mysql exceptions OperationalError 2006 MySQL server has gone
  • 终止递归调用

    据我所知 terminate 当异常处理出现问题时被调用 通常只是没有被捕获 我得到的只是一个错误行terminate called recursively 经过一段时间的谷歌搜索后 我发现了很多例子 terminate called af
  • 如何在 Visual Studio 中将 .NET Framework 更改为 .NET Standard/Core?

    我在 Visual Studio 中有一个 C 解决方案 它最初是在 NET Framework 中创建的 我想将项目转换为 NET Standard Core 如果我进入项目 gt 属性 我会看到附加的屏幕 其中目标框架是 NET Fra
  • 我应该如何解释 ghc 堆分析器的输出?

    我有一个在 haskell 中实现的服务器进程 它充当一个简单的内存数据库 客户端进程可以连接然后添加和检索数据 该服务使用的内存比我预期的要多 我正在尝试找出原因 我拥有的最粗略的指标是linux top 当我启动该过程时 我看到一个大小
  • SeekBar minHeight 和 maxHeight 通过代码

    有谁知道如何设置最小值和最大值SeekBar代码的高度 我想重现与以下 XML 摘录相同的行为
  • 在地图上显示线串的方向 - 自动缩放地图

    我有这段代码 它在地图上绘制一个线串 它是用户提供的 2 个坐标点的轨迹 public class Quickstart public static void main String args throws Exception displa
  • 使用 std 算法将容器分区/批量/分块为大小相等的块

    我遇到过一种情况 我必须将一组记录批量处理到数据库中 我想知道如何才能做到这一点标准算法 给定 10002 条记录 我希望将其划分为 100 条记录的 bin 进行处理 其余为 2 条记录的 bin 希望下面的代码能够更好地说明我想要完成的
  • 强制浏览器将下载的文件保存在特定位置

    我的项目是一个Asp Net MVC4Web应用程序 目前它有一个方法来生成文本文件并将其发送到客户端的浏览器进行下载 我需要修改它以强制浏览器将文件保存在客户端计算机上的自定义 预定义 位置 这是不可能的 因为这会带来严重的安全问题 用户
  • 根据 URL 参数选择下拉菜单 - PHP 还是 jQuery?

    根据 URL 参数为我的表单选择输出 选定 的最佳方法是什么 在我的 URL 中 我可能有这个参数 term retail 我如何告诉下面的代码选择零售选项
  • 从 HDFS 到 Amazon S3 的 Hadoop distcp 问题

    我正在尝试使用以下方法将数据从 HDFS 移动到 S3distcp The distcp作业似乎成功了 但在 S3 上 文件未正确创建 有两个问题 文件名和路径不会被复制 所有文件最终都为block
  • 启用和禁用延迟扩展,它有什么作用?

    我见过SETLOCAL ENABLEDELAYEDEXPANSION SETLOCAL DISABLEDELAYEDEXPANSION在许多批处理文件中 但命令实际上是做什么的 enabledelayeexpansion指示cmd识别语法
  • 使用 Github API 是否可以确定某个分支是否位于默认分支之前?

    使用 Github API 无本地 git 命令 是否可以比较分支以查看它在默认分支之前是否有任何更改 我正在构建一个审核工具 并希望确定要关闭的候选分支 因为它们的所有更改都存在于默认分支中 I want the same informa
  • JavaFX 2 中的组合框键值对

    我刚刚开始学习 JavaFX 2 现在我正在尝试构建一个示例应用程序 然后我就陷入了组合框 我在 JavaFX 中没有找到任何对组合框键值对的引用 组合框 javadoc 位于http docs oracle com javafx 2 ap
  • 如何使用注解配置的 MyBatis 指定 IN param 类型

    如果我希望能够传递空值 我似乎需要明确告诉 MyBatis java util Date IN 参数使用什么数据库类型 但我找不到办法做到这一点 我尝试了以下不同的变体 但没有成功 Select List
  • Agda 中的递归方案

    不用说 Haskell 中的标准构造 newtype Fix f Fix getFix f Fix f cata Functor f gt f a gt a gt Fix f gt a cata f f fmap cata f getFix
  • 重新加载 Disqus 的评论计数

    我正在使用 AJAX 加载文章 当我想显示他们的评论数时 我使用 DISQUSWIDGETS getCount 这有效 但是 当我加载更多文章并再次调用该函数时 它不会显示文章的评论计数 它也不会给出任何错误 Javascript 有没有办
  • ViewRootImpl.setPausedForTransition(boolean) 当过早转换到其他 Activity 时,ActivityTransitionCoordinator 中出现 NullPointerException

    在我的 Android 应用程序中 我有一个启动屏幕 我可以在其中进行一些设置和加载 我的应用程序使用默认值explode as a windowEnterTransition and a windowExitTransition and