Push.getPushKey()返回值是否固定?可否为null?init()更新方案是否合理?
Push.getPushKey()相关问题解答
1. 返回值是否固定,是否推荐在init()中更新服务端存储值?
Push.getPushKey()的返回值不是始终固定的,在以下场景会发生变更:
- 应用卸载重装、用户手动清除应用本地数据
- 厂商推送服务端主动重置设备标识
- 应用签名变更、大版本升级触发推送服务重新注册
因此推荐在应用启动的init()阶段就校验并更新服务端存储的pushKey,避免服务端留存过期失效的标识,导致推送无法正常触达用户。
2. 返回值是否可能为null?
返回值完全可能为null,常见的触发场景包括:
- 推送服务还未完成注册流程,暂未生成有效标识
- 设备无网络,无法和厂商推送服务器完成通信验证
- 设备不支持当前集成的推送服务,或是推送相关权限被用户禁止
调用前必须做空判断,避免触发空指针异常。
3. 提供的定时轮询上报代码是否合理可行?
该逻辑功能上可以跑通,但存在多处可优化的点:
可行的部分
你通过每秒轮询校验Push.getPushKey()和authToken非空后再上报、上报后终止轮询的逻辑,确实可以解决推送服务初始化是异步操作、无法预知拿到有效pushKey时间的问题,只要设备最终能生成有效pushKey,就能完成上报。
可优化的部分
- 缺少轮询超时机制:如果设备一直无法拿到有效pushKey(比如长期断网、设备不支持推送、权限被永久禁止),定时器会持续运行造成不必要的资源浪费,建议增加最大轮询次数(比如最多轮询30次,30秒未拿到就终止,等下次应用启动再重试)
- 上报失败无重试逻辑:当前代码只要发起请求就直接终止定时器,如果上报过程中出现网络波动导致请求失败,服务端就无法拿到最新的pushKey,建议将
timer.cancel()逻辑挪到请求成功的回调中,上报失败的情况下保留定时器继续尝试几次 - 轮询的实现效率偏低:如果你的Push SDK提供了注册成功的回调接口(比如
onRegisterSuccess),优先用回调触发上报,比定时轮询更节省系统资源,响应也更及时。
调整优化后的代码示例:
Timer timer = new Timer(); // 增加最大重试次数计数 int maxRetryCount = 30; AtomicInteger currentRetry = new AtomicInteger(0); timer.schedule(new TimerTask() { @Override public void run() { currentRetry.incrementAndGet(); // 超过最大重试次数直接终止轮询 if (currentRetry.get() > maxRetryCount) { timer.cancel(); return; } if (Push.getPushKey() != null && authToken != null) { Rest.post(Server.getRestServerURL() + "/updatePushKey") .jsonContent() .header("authToken", authToken) .body(Push.getPushKey()) .fetchAsString((Response<String> response) -> { if (isSuccessResponse(response)) { Log.p("PushKey successfully sent to the server", Log.INFO); // 上报成功再终止定时器 timer.cancel(); } }); } } }, 1000, 1000);
内容的提问来源于stack exchange,提问作者Francesco Galgani
相关产品推荐
相关产品推荐

