13

我最近从我的应用程序的用户那里得到了一些奇怪的 StackTraces:

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 lib 的第 3 版,并且关于文档,构造函数不再需要传递 senderID(在 C2DM 时代就是这样) - 这也不会在我的设备和设备上崩溃很多其他用户。有人可以了解这些设备上正在发生的事情,并且最好有一些解决方法吗?这些用户的非工作 GCM 对我来说是一个选项,因为设备推送是可选的 - 但我不希望它崩溃..

此处编辑使用的来源: https ://github.com/ligi/gobandroid/blob/master/src/org/ligi/gobandroid_hd/GCMIntentService.java

4

2 回答 2

18

您是否覆盖了getSenderIds(Context context)GCMBaseIntentService 中的方法?从源代码中,它提到如果您没有在构造函数中传入 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;
}
于 2012-08-17T15:07:08.797 回答
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。

于 2012-09-20T12:56:22.073 回答