1

我们在项目中使用 Akavache,在 Android 中一切正常,但在 iOS 上,我们遇到了一些问题,即如果我们将键值保存在缓存中,如下所示:

public async void Salvar(Login login)
{
    await BlobCache.LocalMachine.InsertObject("login", login);
}

如果我停止调试会话,然后重新开始调试并尝试使用以下方法获取值,BlobCache 将毫无错误地保存:

public async Task<Login> Recuperar()
{
            try
            {
                var dados = await BlobCache.LocalMachine.GetObject<Login>("login");

                return dados;
            }
            catch (KeyNotFoundException)
            {
                return null;
            }
}

我会得到 KeyNotFoundException,我不知道为什么在 Android 中运行良好,但在 iOS 上似乎数据库在重新启动应用程序后消失了。

在我在 Visual Studio 上的 Xamarin 配置中检查 Preserve application data/cache on device between deploys 是 true 并且我的

BlobCache.ApplicationName = "AppName"; 

在 OnStar 方法

有谁知道发生了什么?谢谢

4

5 回答 5

3

我最近遇到了这个问题,对我来说这是因为我错过了这个文件 https://github.com/akavache/Akavache/blob/master/src/Akavache.Sqlite3/content/AkavacheSqliteLinkerOverride.cs.pp

如果其他人遇到这个问题,我首先建议只做 OP 所做的事情并创建自己的。最后那会更好,但如果你想使用静态的,那么请确保有一个看起来像的类

using System;
using Akavache.Sqlite3;

// Note: This class file is *required* for iOS to work correctly, and is 
// also a good idea for Android if you enable "Link All Assemblies".
namespace SomeNameSpace
{
    [Preserve]
    public static class LinkerPreserve
    {
        static LinkerPreserve()
        {
            throw new Exception(typeof(SQLitePersistentBlobCache).FullName);
        }
    }


    public class PreserveAttribute : Attribute
    {
    }
}

发生的情况是弹性缓存永远不会被换入,默认情况下它只使用 InMemory 缓存。这就是为什么数据在重新启动时消失的原因

于 2017-10-07T20:41:14.957 回答
1

终于解决了!问题是 Akavache 正在使用的路径,在创建我自己的路径后,问题就解决了。

1 - 创建一个 DependencyService 来获取您的运行时平台路径,例如 iOS:

var documentsPath =Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var libraryPath = Path.Combine(documentsPath, "..", "Library");
var path = Path.Combine(libraryPath, "cache.db");

在你的 PCL 初始化中你这样做:

BlobCache.ApplicationName = "AppName";
BlobCache.EnsureInitialized();

var local = DependencyService.Get<ILocalCache>();
var pathToCacheDbFile = local.GetPath();
CacheConfig.NormalCache = new SQLitePersistentBlobCache(pathToCacheDbFile);

我的缓存配置:

public class CacheConfig
    {
        public static bool Initialised { get; set; }

        public static IBlobCache NormalCache { get; set; }
    }

然后你像这样使用所有的缓存:

public async Task<bool> Salvar(Login login)
        {
            try
            {
                await CacheConfig.NormalCache.InsertObject("login", login);
            }
            catch (Exception ex)
            {
                //todo
            }

            return true;
        }

此解决方案基于此处的其他线程。

问候

于 2017-01-14T13:31:11.107 回答
0

您的问题是使用“本地机器”

Xamarin.iOS可能会删除存储在 BlobCache.LocalMachine 中的数据,以释放磁盘空间(仅当您的应用未运行时)。BlobCache.UserAccount 和 BlobCache.Secure 位置将备份到 iCloud 和 iTunes。

如果系统磁盘空间不足, Xamarin.Android也可能开始删除存储在 BlobCache.LocalMachine 中的数据。没有明确指定您的应用程序是否可以在系统清理它时运行。

有四个内置位置在某些系统上应用了一些魔法:

BlobCache.LocalMachine - 缓存数据。此数据可能会在不通知的情况下被删除。

BlobCache.UserAccount - 用户设置。一些系统将此数据备份到云中。

BlobCache.Secure - 用于保存敏感数据 - 例如凭据。

BlobCache.InMemory - 保存在内存中的数据库。数据会在应用程序的整个生命周期内存储。

你应该使用

public async void Salvar(Login login)
{
  await BlobCache.UserAccount.InsertObject("login", login);
}

[参考:Akavache 文档]

于 2020-12-03T02:28:03.220 回答
0

我的猜测是,由于您在中间停止进程“如果我停止调试会话”,您不会关闭缓存然后丢失一些数据。

看看这里:https ://github.com/akavache/Akavache#shutting-down

于 2017-01-13T10:37:36.250 回答
0

只是猜测,但也许您的Salvar方法正在抛出(可能login无法序列化)?你不会真的知道这是因为你没有在等待它。你不能是因为它正在返回void而不是Task. 这是一种不好的做法,应尽可能避免。

更改Salvar返回Task并确保await保存。

于 2017-01-13T23:43:49.787 回答