GCM FC / 构造函数未设置 sender id

13

最近我收到了一些用户反馈的奇怪的堆栈跟踪:

Android Version: 2.3.5
Phone Model: GT-I9001
Stacktrace:
java.lang.IllegalStateException: sender id not set on constructor
at com.google.android.gcm.GCMBaseIntentService.getSenderIds(GCMBaseIntentService.java:125)
at com.google.android.gcm.GCMBaseIntentService.onHandleIntent(GCMBaseIntentService.java:237)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:59)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.os.HandlerThread.run(HandlerThread.java:60)

我正在使用GCM库的Rev.3版本,根据文档,构造函数不再需要传递senderID(在C2DM时期是这样的)-同时,在我的设备和许多其他用户的设备上都没有崩溃。有人能够解释一下这些设备上发生了什么,并最好提供一些解决方案吗?对于这些用户来说,一个无法工作的GCM可能是一个选择,因为设备推送是可选的,但我不希望它崩溃...

编辑这里是使用的源代码: https://github.com/ligi/gobandroid/blob/master/src/org/ligi/gobandroid_hd/GCMIntentService.java

2个回答

18

您是否覆盖了GCMBaseIntentService中的getSenderIds(Context context)方法?从源代码中可以看出,如果在构造函数中没有传递SenderID,则需要覆盖getSenderIds(Context context)方法提供SenderID。

这是来自构造函数的注释:

/**
 * Constructor that does not set a sender id, useful when the sender id
 * is context-specific.
 * <p>
 * When using this constructor, the subclass <strong>must</strong>
 * override {@link #getSenderIds(Context)}, otherwise methods such as
 * {@link #onHandleIntent(Intent)} will throw an
 * {@link IllegalStateException} on runtime.
 */
protected GCMBaseIntentService() {
    this(getName("DynamicSenderIds"), null);
}

而 getSenderIds() 的注释为:

/**
 * Gets the sender ids.
 *
 * <p>By default, it returns the sender ids passed in the constructor, but
 * it could be overridden to provide a dynamic sender id.
 *
 * @throws IllegalStateException if sender id was not set on constructor.
 */
protected String[] getSenderIds(Context context) {
    if (mSenderIds == null) {
        throw new IllegalStateException("sender id not set on constructor");
    }
    return mSenderIds;
}

谢谢您的回答,但我没有覆盖这个构造函数。这里是源代码:https://github.com/ligi/gobandroid/blob/master/src/org/ligi/gobandroid_hd/GCMIntentService.java此外,这里的文档:http://developer.android.com/guide/google/gcm/gs.html 没有提到覆盖getSenderIds。 - ligi
如果您安装了GCM附加组件,则可以访问GCMBaseIntentService.java的源代码,请查看该文件,其中提到了源代码。 - azgolfer
我对这整件事情还不是100%确定,但我接受并点赞你的回答,因为我很感激! - ligi
@vipsy 是的,这似乎有效 - 我再也没有收到那些错误消息了。 - ligi
现在在此处的第2步的结尾也在GCM文档中提到: http://developer.android.com/guide/google/gcm/gs.html#android-app - Till - Appviewer.io

12

引用自Google Group的回复:

看起来你正在使用默认构造函数而没有重写getSenderIds()方法。正如构造函数的javadoc所解释的那样:

当发送者ID是上下文特定的时,不设置发送者ID的构造函数非常有用。当使用此构造函数时,子类必须重写getSenderIds(Context),否则像onHandleIntent(Intent)这样的方法将在运行时抛出IllegalStateException异常。

如果您不需要动态发送者ID,则应该使用带有发送者ID的构造函数。

更新:我想我解决了。

查看GCM示例,如果您使用静态YOUR_GCM_SENDER_ID的supert构造函数,则必须实现此功能。

public GCMIntentService() {
        super(YOUR_GCM_SENDER_ID);
}

否则,如果您使用没有参数的超级构造函数,则必须重写getSenderIds(Context)。
所有内容都在JavaDoc文档中解释。
更新:解释什么是YOUR_GCM_SENDER_ID
当您在Google API控制台页面配置Google API项目时,您必须创建自己的项目并在其中启用GCM API。
您的项目网址将类似于。
https://code.google.com/apis/console/#project:4815162342

#project后面的值(在本例中为4815162342)是您的项目编号,稍后将作为GCM发送者ID使用。


4
这里的“Global.GCM_SENDER_ID”是类似于2372498294这样的值,是@StErMi通过与Google的GCM设置而获得,并将其作为常量放入他的应用程序中。该值是在GCMRegistrar.register(this, SENDER_ID)中使用的相同发送者ID。 - larham1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接