将脱机数据同步添加到 Xamarin.Android 应用

本教程介绍适用于 Xamarin 的 Azure 移动应用的脱机同步功能。Android快速入门应用。 脱机同步允许最终用户与移动应用交互(查看、添加或修改数据),即使没有网络连接也是如此。 更改存储在本地数据库中。 设备重新联机后,这些更改会与远程后端同步。

在开始本教程之前,应已完成 Xamarin.Android 快速入门教程(其中包括创建合适的后端服务)。 我们还假设你已 向应用程序添加身份验证 。 但是,这是可选的。

更新应用以支持脱机同步

在联机操作中,可以对 IRemoteTable<T> 进行读取和写入。 使用脱机同步时,可以对 IOfflineTable<T> 进行读取和写入。 IOfflineTable 由设备上的 SQLite 数据库提供支持,与后端数据库进行同步。

在 Visual Studio 中:

  1. 右键单击TodoApp解决方案,然后选择“管理解决方案NuGet包...”

  2. 在新选项卡中,选择“ 浏览”,然后在搜索框中输入 Microsoft.Datasync.Client

    Screenshot of adding the offline NuGet in Visual Studio.

  3. 选择 Microsoft.Datasync.Client.SQLiteStore 包。

  4. 在右侧窗格中,选择除项目) 之外 TodoAppService.NET6 的所有客户端项目 (。

  5. 选择“安装” 。

  6. 出现提示时接受许可协议。

在 Visual Studio 中:

  1. 右键单击TodoApp解决方案,然后选择“管理NuGet包...”

  2. 选择 “浏览 ”选项卡,然后在搜索框中输入 Microsoft.Datasync.Client

    Screenshot of adding the offline NuGet in Visual Studio.

  3. 选择 Microsoft.Datasync.Client.SQLiteStore 包。

  4. 选择“添加包”。

  5. “选择项目 ”窗口中,选择除项目 () 以外的 TodoAppService.NET6 所有客户端项目。

  6. 选择“确定” 。

  7. 出现提示时接受许可协议。

更新远程服务客户端

TodoApp.Data打开项目并在目录) 中找到RemoteTodoService.cs类 (Services。 按如下所示更新类:

  1. 将下面的 using 语句添加到文件顶部:

    using Microsoft.Datasync.Client.SQLiteStore;
    
  2. 将定义 _table 更改为 IOfflineTable<TodoItem>

    /// <summary>
    /// Reference to the table used for datasync operations.
    /// </summary>
    private IOfflineTable<TodoItem> _table = null;
    
  3. 添加用于存储脱机数据库位置的新属性:

    /// <summary>
    /// The path to the offline database
    /// </summary>
    public string OfflineDb { get; set; }
    
  4. 更新方法 InitializeAsync 以定义脱机数据库:

    // Create the offline store definition
    var connectionString = new UriBuilder { Scheme = "file", Path = OfflineDb, Query = "?mode=rwc" }.Uri.ToString();
    var store = new OfflineSQLiteStore(connectionString);
    store.DefineTable<TodoItem>();
    var options = new DatasyncClientOptions
    {
        OfflineStore = store,
        HttpPipeline = new HttpMessageHandler[] { new LoggingHandler() }
    };
    
    // Create the datasync client.
    _client = TokenRequestor == null 
        ? new DatasyncClient(Constants.ServiceUri, options)
        : new DatasyncClient(Constants.ServiceUri, new GenericAuthenticationProvider(TokenRequestor), options);
    
    // Initialize the database
    await _client.InitializeOfflineStoreAsync();
    
    // Get a reference to the offline table.
    _table = _client.GetOfflineTable<TodoItem>();
    
    // Set _initialized to true to prevent duplication of locking.
    _initialized = true;
    
  5. RefreshItemsAsync()更新以执行脱机同步:

    /// <summary>
    /// Refreshes the TodoItems list manually.
    /// </summary>
    /// <returns>A task that completes when the refresh is done.</returns>
    public async Task RefreshItemsAsync()
    {
        await InitializeAsync();
    
        // First, push all the items in the table.
        await _table.PushItemsAsync();
    
        // Then, pull all the items in the table.
        await _table.PullItemsAsync();
    
        return;
    }
    

设置脱机数据库位置

TodoApp.Android 项目中,编辑 App.xaml.cs 文件。 按如下所示更改定义 RemoteTodoService

TodoService = new RemoteTodoService(async () => await GetAuthenticationToken())
{
    OfflineDb = Xamarin.Essentials.FileSystem.AppDataDirectory + "/offline.db"
};

如果尚未完成 身份验证教程,则定义应如下所示:

TodoService = new RemoteTodoService()
{
    OfflineDb = Xamarin.Essentials.FileSystem.AppDataDirectory + "/offline.db"
};

测试应用程序

在按下刷新图标之前,应用不会与后端同步。 测试:

  1. 打开 Azure 门户

  2. 打开包含快速入门资源的资源组。

  3. quickstart选择数据库。

  4. 选择 查询编辑器 (预览)

  5. 使用为数据库设置的相同凭据登录SQL服务器身份验证。

    • 如有必要,系统会提示你允许访问 IP 地址。 选择链接以更新允许列表,然后按 “确定 ”重试登录名。
  6. 在查询编辑器中输入 SELECT * FROM [dbo].[TodoItems]。 然后,选择“运行”。

将显示当前 TodoItems 的列表。

Screenshot of the results in the S Q L query editor.

现在,通过应用进行一些更改。 请勿按刷新 (但尚未) 。

重复Azure 门户中的SQL语句,并验证数据库中的数据未做任何更改。

选择应用上的 “刷新 ”图标,将队列中的数据推送到后端服务。 你将在“输出调试”窗口中看到 HTTP 事务发生。

重复Azure 门户中的SQL语句,并验证是否已将更改推送到远程服务。

清理资源

除非正在执行另一个快速入门教程,否则现在可以删除与后端服务关联的资源。

  1. 打开 Azure 门户
  2. 选择包含快速入门资源的资源组。
  3. 选择“删除资源组”
  4. 按照说明确认删除。

也可以使用 Azure CLI:

az group delete -g quickstart

删除需要几分钟才能完成。

后续步骤