带有 Room 数据库的 Google play 游戏服务

Posted

技术标签:

【中文标题】带有 Room 数据库的 Google play 游戏服务【英文标题】:Google play game services with Room database 【发布时间】:2021-05-09 11:46:24 【问题描述】:

我们有一个简单的问答游戏,目前正在使用 Room 数据库来存储包括用户进度在内的所有数据。我们现在想要集成 Google play 游戏服务来将进度存储在云端,以便用户在更换设备或重新安装游戏时可以了解他们的进度。

目前我们在 xml 文件中包含游戏类别和关卡详细信息,然后在第一次运行应用程序时对其进行解析并将数据存储在 Room 数据库中。

我们查看了游戏服务的文档,知道有这种方法可以保存游戏。

private Task<SnapshotMetadata> writeSnapshot(Snapshot snapshot,
                                         byte[] data, Bitmap coverImage, String desc) 

  // Set the data payload for the snapshot
  snapshot.getSnapshotContents().writeBytes(data);

  // Create the change operation
  SnapshotMetadataChange metadataChange = new SnapshotMetadataChange.Builder()
      .setCoverImage(coverImage)
      .setDescription(desc)
      .build();

  SnapshotsClient snapshotsClient =
      Games.getSnapshotsClient(this, GoogleSignIn.getLastSignedInAccount(this));

  // Commit the operation
  return snapshotsClient.commitAndClose(snapshot, metadataChange);

但问题是,这种方法需要字节来写入快照,并且我们在 Room 数据库中有数据,我们可以从 Room db 传递数据还是必须更改本地数据库?

【问题讨论】:

【参考方案1】:

正如问题所写,完全不清楚byte[] data 是什么。 将SnapshotsClientSnapshotMetadata 一起使用(如文档所示,还有更多属性需要设置)。 String 可以轻松转换为 byte[]。首先,您需要某种SaveGame 的模型——它可能是@Entity 的房间;那么String & GSON 可以提供byte[] getters/setters:

@Entity(tableName = "savegames")
public class SaveGame 

    @PrimaryKey
    public int id;
    ...

    /** return a byte-array representation (this is probably what you're asking for). */
    public byte[] toByteArray() 
        return new Gson().toJson(this).getBytes();
    

    /** TODO: initialize instance of @link SaveGame from a byte-array representation - so that it will work both ways. */
    public void fromByteArray(byte[] bytes) 
        SaveGame data = new Gson().fromJson(new String(bytes, StandardCharsets.UTF_8), SaveGame.class);
        ...
    

或者将byte[] 传递给构造函数:

@Entity(tableName = "savegames")
public class SaveGame 

    @PrimaryKey
    public int id;
    ...

    public SaveGame() 

    @Ignore
    public SaveGame(byte[] bytes) 
        SaveGame data = new Gson().fromJson(new String(bytes, StandardCharsets.UTF_8), SaveGame.class);
        ...
    
    ...

与此类似,从RoomSnapshotsClient 有效负载加载SaveGame 没有问题。即使不使用 Room,仍然需要对快照的有效负载进行编码/解码的方法——无论保存游戏的参数或格式如何。相反,可以只定义一个byte[],其中每个数字都可以代表另一个保存游戏参数;这可能取决于要保存和恢复的有效负载的复杂程度。

【讨论】:

以上是关于带有 Room 数据库的 Google play 游戏服务的主要内容,如果未能解决你的问题,请参考以下文章

Google Play 服务实时多人游戏的共享种子?

带有 Google Play 服务的 Android Studio

带有 Google Play 服务的 Android Studio“仅限设备”位置不起作用

带有 Google Play 游戏服务的 OAuth 令牌

带有 Play2.4 和 scala 的 Google Guice 的循环依赖错误

带有活动切换的 Google Play 游戏服务多人游戏