这是我自己使用在 Nexus 7 平板电脑上运行的应用程序购买商品,然后使用在 Nexus One 手机上运行的相同应用程序检测到该购买的经验。下面描述的测试是使用测试帐户对以草稿模式上传(尚未发布)的应用程序执行的。测试帐户已在草稿应用程序的开发者控制台上声明,并且是两个测试设备的主帐户。
购买的是非消耗品。购买是使用随 TrivialDrive 示例应用程序提供的 IabHelper 类的变体进行的。为进行购买而调用的 IabHelper 方法是 launchPurchaseFlow()。
购买后,当随后使用 IabHelper 的 queryInventoryAsync() 方法时,该项目被添加到返回到同一设备的购买项目列表中。
但是,同一帐户拥有的另一台 Nexus One 设备在启动时执行了对 queryInventoryAsync() 的调用,但未收到使用该方法返回的已购买商品库存中的已购买商品。
但是,如果使用 Nexus One 设备使用 launchPurchaseFlow() 启动购买同一商品,则会返回一条消息(在用于购买的显示屏前弹出的对话框中),表示无法购买该项目,因为它已经拥有。这发生在从 Nexus 7 开始购买后不到 15 分钟,这表明数据在 Google Play 服务器上相当迅速地可用,但在 Nexus One 上不会自动可用,直到尝试从Nexus One 设备已启动。
在这次购买已拥有物品的失败尝试之后,该物品确实出现在 Nexus One 上的 queryInventoryAsync() 后续调用中。这表明购买该项目的尝试触发了 Nexus One Google Play 应用程序的缓冲数据与 Google Play 服务器上可用数据的同步。这不是由 queryInventoryAsync() 本身触发的。
我测试了第二种情况,在这种情况下,我没有尝试从 Nexus One 购买已经拥有的物品,而是删除了 Google Play 应用程序中的缓存。这没有启动对 queryInventoryAsync() 返回的数据的更新;该数据保持不变。
我测试了第三种情况,在这种情况下,我没有尝试从 Nexus One 购买已经拥有的物品,而是简单地关闭了 Nexus One,然后再次打开它。此后,当我运行同一个应用程序并执行 queryInventoryAsync() 请求时,从 Nexus 7 购买的商品实际上在返回的购买商品列表中可见。
我从上面得出的结论是,Google Play 应用程序试图通过在本地缓冲购买并仅在发生特定触发器时更新自身来减少它对 Google Play 服务器进行的往返次数。我已经确定了两个触发因素,即 1) 尝试购买已拥有的物品和 2) 重新启动运行 Google Play 应用程序的设备。特别是,queryInventoryAsync() 不会启动这样的更新,因此可能会返回过时的数据,如上所述。
了解上述内容可以使测试更高效且更少混乱,因为它允许人们故意触发从 Google Play 服务器上可用的数据更新缓冲数据。