我最近从我的应用用户那里获得了一些奇怪的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
答案 0 :(得分: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;
}
答案 1 :(得分:12)
引用Google Group回复:
看起来你正在使用默认构造函数而没有覆盖 getSenderIds()方法。正如构造函数的javadoc所解释的那样:
未设置发件人ID的构造函数,在发件人ID时很有用 是特定于上下文的。使用此构造函数时,子类必须 覆盖getSenderIds(Context),否则方法如 onHandleIntent(Intent)将在运行时抛出IllegalStateException
如果您不需要动态发件人ID,则应使用构造函数 取而代之的是发件人ID。
更新:我想我已经解决了。
查看GCM示例,如果使用带有静态YOUR_GCM_SENDER_ID的超级构造函数,则必须实现此目的(
public GCMIntentService() {
super(YOUR_GCM_SENDER_ID);
}
否则,如果你使用没有params的超级构造函数,你必须覆盖getSenderIds(Context)
中解释的所有内容更新:说明什么是YOUR_GCM_SENDER_ID
在Google API Console页面上配置Google API项目时,您必须创建自己的项目并在其上启用GCM API。
您的项目网址将类似于
https://code.google.com/apis/console/#project:4815162342
#project :(本例中为4815162342)之后的值是您的项目编号,稍后将用作GCM发件人ID。