【问题标题】:Xamarin Splash screen example does not work in landscape mode on a phone. How to fix it?Xamarin 启动画面示例在手机的横向模式下不起作用。如何解决?
【发布时间】:2015-05-02 17:09:31
【问题描述】:

我从 Xamarin 网站下载了启动画面示例: http://developer.xamarin.com/guides/android/user_interface/creating_a_splash_screen/

我编译它并在我的手机上运行它: http://www.gsmarena.com/samsung_galaxy_fresh_s7390-5841.php

以纵向模式(垂直)握住我的手机时效果很好。启动画面变得直接可见,几秒钟后,带有按钮的视图变得可见。关闭并重新启动应用程序时,它仍然可以正常工作。

之后,我再次将其关闭并将手机保持在横向(水平)模式。现在,我再次启动了应用程序。我的手机冻结了几秒钟,飞溅没有变得可见。之后,我用按钮看到了我的视图。

当您尝试重现此问题时,请确保您:

  • 不要尝试在虚拟设备上重现它(行为不同)。
  • 确保睡眠至少需要 10 秒,然后您才能真正看到问题所在:应用程序冻结而不是启动画面。
  • 如果您没有 Samsung Trend Lite,您可以在另一部小型智能手机上试用。我很难想象这可能是“仅限三星 Trend Lite”的问题。

我该如何解决这个问题?

【问题讨论】:

    标签: android xamarin splash-screen


    【解决方案1】:

    你链接的Xamarin sample里面有大问题:

    [Activity(Theme = "@style/Theme.Splash", MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            Thread.Sleep(10000); // Simulate a long loading process on app startup.
            StartActivity(typeof(Activity1));
        }
    }
    

    ActivityOnCreate() 方法在 UI 线程上执行,因此在其中调用 Thread.Sleep() 将锁定主线程,可能会生成应用程序无响应 (ANR) 以显示给用户。

    这是 Xamarin 文档中的错误,您不应在 UI 线程上运行 Thread.Sleep(),尤其是在活动的核心生命周期回调之一中。

    通过使用后台线程执行睡眠然后回调到启动活动以启动下一个活动来解决此问题:

    [Activity(Theme = "@style/Theme.Splash", MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            System.Threading.Tasks.Task.Run( () => {
                Thread.Sleep(10000); // Simulate a long loading process on app startup.
                StartActivity(typeof(Activity1));
            });
        }
    }
    

    【讨论】:

    • 你确定,它不应该在 UI 线程上完成吗?这也解决了我设备上的问题(我刚刚发现): base.OnCreate(bundle); System.Timers.Timer t = 新的 System.Timers.Timer(1); t.Elapsed += (o, e) => { t.Stop();线程.睡眠(10000); // 模拟应用启动时的长时间加载过程。 StartActivity(typeof(Activity1)); }; t.Start();
    • 这或多或少与使用后台线程做同样的事情。这也是一个不错的解决方案!
    • 为了响应将睡眠放入后台线程,请尝试按照 Xamarin 文档建议的方式保持它,并在启动时按下后退按钮退出应用程序。因为它在 UI 线程上,它会锁定用户交互并可能生成 ANR。因此,为什么要将延迟转移到后台。
    【解决方案2】:

    我刚刚发现了另一个解决方案。使用计时器有点奇怪,但它解决了问题。

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            System.Timers.Timer t = new System.Timers.Timer(1);
            t.Elapsed += (o, e) =>
            {
                t.Stop();
                Thread.Sleep(10000); // Simulate a long loading process on app startup.
                StartActivity(typeof(Activity1));
            };
            t.Start();
        }
    

    【讨论】:

      猜你喜欢
      • 2012-06-29
      • 1970-01-01
      • 2020-04-01
      • 2012-04-06
      • 1970-01-01
      • 2018-10-06
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      相关资源
      最近更新 更多