应用程序是不是应该每 7 天调用一次 gcm.register() 以确保注册 ID 有效?

Posted

技术标签:

【中文标题】应用程序是不是应该每 7 天调用一次 gcm.register() 以确保注册 ID 有效?【英文标题】:Should applications call gcm.register() every seven days to ensure valid registration IDs?应用程序是否应该每 7 天调用一次 gcm.register() 以确保注册 ID 有效? 【发布时间】:2013-07-26 21:33:53 【问题描述】:

GCM example on the android dev site 中的客户端代码默认每隔 7 天调用一次gcm.register(SENDER_ID);,方法是使用以下函数检查注册是否过期:

public static final long REGISTRATION_EXPIRY_TIME_MS = 1000 * 3600 * 24 * 7;

/**
 * Checks if the registration has expired.
 *
 * To avoid the scenario where the device sends the registration to the
 * server but the server loses it, the app developer may choose to re-register
 * after REGISTRATION_EXPIRY_TIME_MS.
 *
 * @return true if the registration has expired.
 */
private boolean isRegistrationExpired() 
    final SharedPreferences prefs = getGCMPreferences(context);
    // checks if the information is not stale
    long expirationTime =
            prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
    return System.currentTimeMillis() > expirationTime;

函数上面的注释暗示这用于“避免设备将注册发送到服务器但服务器丢失它的情况。这是否暗示我们的服务器(而不是GCM服务器)可能会丢失注册 ID?或者这是因为注册 ID 可能在 GCM 方面变得无效?根据the GCM Advanced Topics Page 中的以下段落,这似乎是可能的:

同样,申请时也不应保存注册ID 已备份。这是因为注册 ID 可能无效 到应用程序恢复时,这将把 应用程序处于无效状态(即应用程序认为它是 已注册,但服务器和 CM 不存储该注册 ID 不再——因此应用程序不会收到更多消息)。

提前谢谢你!

【问题讨论】:

【参考方案1】:

    你说:

    函数上面的注释暗示这是用来“避免设备发送 注册到服务器,但服务器丢失了它。这是 暗示我们的服务器(不是 GCM 服务器)可能会丢失 注册号?或者这是因为注册 ID 可能变成 在 GCM 方面无效?

    我认为他们在谈论我们的服务器(第 3 方服务器) 而不是 GCM 服务器。第二点会更清楚一点。

    另外,您提到文档说:

    备份应用程序时不应保存注册 ID。这是 因为注册 ID 可能会在 应用程序被恢复,这会将应用程序置于 无效状态。

    我想如果你仔细阅读标题下的第二点 在Architectural Overview 页面上启用 GCM,上面写着:

    请注意,Google 可能会定期刷新注册 ID,因此 你应该在理解的情况下设计你的 Android 应用程序 com.google.android.c2dm.intent.REGISTRATION 意图可能是 多次调用。您的 Android 应用程序需要能够 做出相应的回应。

    因此,Google 可能会定期刷新他的注册 ID。这就是为什么 申请时注册 ID 可能会失效 已恢复。

    因此,为了处理这个问题,您应该有一个可以处理 com.google.android.c2dm.intent.REGISTRATION 意图的广播侦听器,当 Google 必须刷新注册 ID 时,它会发送给应用程序。

    这也可以清除第一点。由于本案例处理的是来自 Google 端的 ID 刷新,本地 7 天有效期将处理在第 3 部分服务器上丢失 ID 的另一种情况(因为它每 7 天后定期刷新)。

这是我对您的问题的看法。希望这可以帮助。

【讨论】:

好的。这很清楚。该架构概述段落确实提供了丰富的信息。看起来如果我的清单中有一个接收器来过滤com.google.android.c2dm.intent.RECEIVEcom.google.android.c2dm.intent.REGISTRATION 事件,我可以通过检查“registration_id”作为意图中的额外字符串来处理接收器onReceive 方法中的差异根据the advanced info document,然后在定期 ID 刷新时保存 google 提供的新 ID。 你说的对,老办法,onReceive方法里面的ID刷新的情况可以直接处理。虽然onReceive 的推送方式已经被贬低了。新方法建议为此设置广播侦听器。此外,在这种新方式中,对gcm.register()(注册推送)的调用是一种阻塞方法,这与之前的推送注册方式不同,在这种方式中,应用程序用于在onRegistered 方法中接收回调。 我的意思是BroadcastReceiver的onReceive方法developer.android.com/reference/android/content/… 关于更新:当BroadcastReceiver 收到事件时,您不需要调用gcm.register()。即使该事件是注册事件,GCM 也会向您发送新的注册 ID,因此客户端的责任是将这个新 ID 发送到第 3 方服务器并将其保存到共享首选项,而不是重新注册 GCM(如这已经发生了——如果这还没有发生,应用程序的接收者将不会收到消息)。 你是对的。愚弄我!我忘了它有一个与onReceive 方法关联的Intent。我会相应地更新答案。感谢您的更正:)【参考方案2】:

澄清“备份/恢复”案例:注册 ID 与特定设备相关联。如果应用在其他设备上恢复 - 之前的注册 ID 仍指向旧设备,则在恢复的设备上获取消息的唯一方法是获取新的注册 ID。

【讨论】:

以上是关于应用程序是不是应该每 7 天调用一次 gcm.register() 以确保注册 ID 有效?的主要内容,如果未能解决你的问题,请参考以下文章

Haskell ▏缺的不是座位 而是将资源还给自然 还有7天诠释不凡办公家具品味

我需要一个允许以不同间隔执行任务的 Nodejs 调度程序 [关闭]

python全栈脱产第12天

巴厘岛7天6晚人均3000(不含机票)实用型游记

每三天进行一次 Cron 作业

第一次调用后,幂等服务是不是应该以错误响应?