适配项目的GMS/GCM版本选择及GCM注销崩溃问题求助
嘿,我来帮你梳理下这个问题——你现在用的是Firebase之前的旧版GCM,还在维护对应的Web服务器,碰到了版本适配困惑+注销崩溃的问题,咱们一步步来解决:
一、先搞定GMS/GCM版本适配
你的项目compileSdkVersion和targetSdkVersion都是25,对应的旧版GCM依赖必须选和API 25兼容的Play Services版本,也就是11.0.4——这是Google Play Services支持API 25的最后几个稳定版本,也是旧GCM能正常工作的上限版本(更高版本的Play Services已经把GCM整合进FCM,旧API会出现兼容性问题)。
你可以把Gradle的依赖部分改成这样:
dependencies { // 适配API 25的旧版GCM依赖 implementation 'com.google.android.gms:play-services-gcm:11.0.4' // 其他项目依赖... }
二、解决GCM注销崩溃的常见问题
注销崩溃大概率是调用时机不对、依赖冲突或者资源未释放导致的,给你几个排查和修复方向:
1. 确保注销操作在异步线程执行
旧版GCM的InstanceID.getInstance(context).deleteInstanceID()或者GCMRegistrar.unregister(context)都是耗时操作,如果在主线程同步调用,很容易触发ANR甚至崩溃。
解决:把注销逻辑放到异步线程,比如用AsyncTask(适合旧项目):new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { try { InstanceID.getInstance(getApplicationContext()).deleteInstanceID(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void aVoid) { // 注销完成后的逻辑,比如提示用户 } }.execute();另外,尽量用Application Context来调用,避免Activity销毁后上下文失效导致的崩溃。
2. 检查GoogleApiClient的状态(如果用了的话)
如果你是通过GoogleApiClient来管理GCM的,注销前必须确保GoogleApiClient已经连接成功,否则会抛出IllegalStateException。
解决:在注销前加判断:if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { // 执行注销操作 }3. 注销后释放相关资源
如果注销后还持有GCM广播接收器、服务的引用,或者继续调用GCM相关API,容易引发空指针或内存泄漏。
解决:注销完成后,取消所有动态注册的GCM广播接收器,并且不再调用任何GCM相关方法。4. 一定要看崩溃栈日志
你只提到崩溃,但没给出具体的错误信息——比如是NullPointerException、NoClassDefFoundError还是其他?这是定位问题的核心。如果是NoClassDefFoundError,那大概率是依赖版本不兼容;如果是IllegalStateException,就是调用时机不对。
额外建议
虽然你现在还在维护旧GCM的Web服务器,但Google早就停止了旧GCM的服务支持,后续可能会出现更多兼容性问题。其实FCM完全兼容旧GCM的API,你只需要:
- 客户端换成FCM依赖(
com.google.firebase:firebase-messaging:xx.x.x) - 服务器端把发送地址从
https://android.googleapis.com/gcm/send改成https://fcm.googleapis.com/fcm/send
就能无缝切换,还能获得更好的稳定性和新功能。
内容的提问来源于stack exchange,提问作者JYL

