【问题标题】:First view not shown properly when Akavache is used before之前使用 Akavache 时未正确显示第一个视图
【发布时间】:2020-04-13 19:58:48
【问题描述】:

如果我在显示第一个视图之前从缓存中获取对象,则应用程序将只显示一个空白页面(在 Android 上,未测试其他平台)。如果我锁定屏幕并解锁它,那么我的视图就会显示出来。重现非常简单:

  • 创建新的 Xamarin.Forms 应用(我为此示例选择了选项卡式布局)。
  • 将 akavache nuget 包添加到所有项目。
  • App.xaml.cs中,初始化akavache并获取一个对象,然后再设置MainPage属性。
  • 启动应用程序 - 将是完全白屏。
  • 锁屏,解锁-界面将显示。这部分似乎只适用于我的实体手机,而不是模拟器。

这是一个示例App.xaml.cs,它将重现该问题。

using System.Reactive.Linq;
using Akavache;
using Xamarin.Forms;
using AkavacheTest.Services;
using AkavacheTest.Views;

namespace AkavacheTest
{
    public partial class App : Application
    {

        public App()
        {
            InitializeComponent();

            DependencyService.Register<MockDataStore>();
        }

        protected override async void OnStart()
        {
            Akavache.Registrations.Start("Test");
            var test = await BlobCache.LocalMachine.GetOrFetchObject("Settings", async () => "New");
            MainPage = new MainPage();
        }
    }
}

那么这里发生了什么,更重要的是 - 是否有解决方法或解决方法?

【问题讨论】:

  • 你有做过什么调试吗?您是否已通过代码查看是否调用了 MainPage?是否有任何错误、异常或日志消息?
  • 我花了一些时间调试。我看不到任何错误。 MainPage 正在构建中,OnAppearing 也在 MainPage 上被调用。

标签: xamarin.forms akavache


【解决方案1】:

就解决方法而言,我设法找到了一个。如果我在从缓存中获取之前设置了MainPage,那么我可以在抓取缓存之后再次设置它,没有问题。

这两个都有效:

    protected override async void OnStart()
    {
        MainPage = new Page();
        Akavache.Registrations.Start("Test");
        var test = await BlobCache.LocalMachine.GetOrFetchObject("Settings", async () => "New");
        MainPage = new MainPage();
    }

    protected override async void OnStart()
    {
        Akavache.Registrations.Start("Test");
        MainPage = new Page();
        var test = await BlobCache.LocalMachine.GetOrFetchObject("Settings", async () => "New");
        MainPage = new MainPage();
    }

不过,我仍然很好奇为什么会这样。请参阅@BenReierson 的评论。

考虑到这些信息,更好的解决方法是:

protected override void OnStart()
{
    Akavache.Registrations.Start("Test");
    var test = BlobCache.LocalMachine.GetOrFetchObject("Settings", async () => "New").GetAwaiter().GetResult();
    MainPage = new MainPage();
}

所以我们实际上在设置 MainPage 之前等待 Akavache 的结果。虽然其他解决方法有效,但设置一个页面(这会导致它被呈现)有点浪费,只是在之后几乎立即设置另一个页面。

【讨论】:

  • 因为 OnStart 没有被等待,因为它通常不是异步方法并且不返回任务。调用者在设置 MainPage 之前看到它返回,这可能是导致问题的原因。
  • @BenReierson 这很有意义。为了测试你的理论,我测试了你的理论,它似乎是正确的。我会用更好的解决方法更新这个答案。
  • 你刚刚救了我的命...花了太多时间在这个没有运气的情况下,但这对我来说终于奏效了。
  • 只是想补充一下,我最终选择了另一个(类似的)解决方法。在我的 App 类中,我导航到“加载”页面。在这个页面上,我写了“加载”之类的东西,并在这里进行了所有的初始化。完成初始化后,我会加载缓存并使用它来决定导航到哪个页面。
猜你喜欢
  • 1970-01-01
  • 2015-10-13
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多