我们有一个Android应用,最近报告了许多ANR错误。这仅发生在Android 7.1和8.0上(例如4.4、5.0或6.0)。ANR是:
Broadcast of Intent { act=com.google.firebase.INSTANCE_ID_EVENT flg=0x14 cmp=com.our.package.name/com.google.firebase.iid.FirebaseInstanceIdInternalReceiver (has extras) }
问题是:我们为什么要获得此ANR,我们该怎么做?执行任何新秀 - 穆斯塔克斯,导致ANR。
我很难再现此错误。由于它仅在Android 7.1和8.0上,我认为这可能与新的DOZE模式和节省电池有关,但是即使使用adb shell dumpsys deviceidle force-idle
等。在测试并不能重现此问题时,也不会将其放置在SystemClock.sleep(20000);
几个地方。
我们的InstanceIdService
代码是:
public class InstanceIdService extends FirebaseInstanceIdService {
private Analytics mAnalytics;
@Override
public void onCreate() {
super.onCreate();
mAnalytics = new AnalyticsImpl();
boolean isFullVersion = getApplicationContext().getPackageName().endsWith("full");
mAnalytics.init(getApplicationContext(), isFullVersion);
}
@Override
public void onTokenRefresh() {
boolean initialLoginSucceeded = OurAppNameApplication.getInstance().getSettings().getInitialLoginSucceeded();
mAnalytics.logEvent("FCM_Token_Refresh_Triggered", "initialLoginSucceeded", String.valueOf(initialLoginSucceeded));
if (initialLoginSucceeded) { // We only report the FCM token to our server if the user has logged in at least once
OurAppNameApplication.getInstance().getOurAppNameService().registerDeviceWithRetry();
}
}
}
我们使用Google Play服务和Firebase版本11.2.0。我们的TargetsDkversion是25。
ps:上面的代码mAnalytics.init(...)
给了我们严格的警告,因为这初始化了Flurry。但这是磁盘访问,而不是网络流量。并在此位置放入SystemClock.sleep(20000);
确实不是触发任何ANR。
我们为什么要获得ANR,我们该怎么做才能避免这种情况?
-
编辑:根据鲍勃·斯奈德(Bob Snyder)的评论中的建议,我试图使用adb shell cmd appops set com.our.package.name RUN_IN_BACKGROUND ignore
进行测试。但是,这不会产生任何ANR,它只会阻止我们的广播接收器运行,如LogCat:
09-21 10:39:25.314 943-6730/? W/ActivityManager: Background start not allowed: service Intent { act=com.google.firebase.INSTANCE_ID_EVENT pkg=com.our.package.name cmp=com.our.package.name/com.our.package.service.notifications.InstanceIdService (has extras) } to com.our.package.name/com.our.package.service.notifications.InstanceIdService from pid=4062 uid=10139 pkg=com.our.package.name
09-21 10:39:25.314 4062-4062/com.our.package.name E/FirebaseInstanceId: Error while delivering the message: ServiceIntent not found.
我的结论是,这可能不是重现此ANR错误的正确方法。
出于完整性的清酒:测试时使用的所有ADB命令:
adb shell dumpsys deviceidle force-idle
adb shell dumpsys battery unplug
adb shell am set-inactive com.our.package.name true
adb install -r our-app.apk
adb shell cmd appops set com.our.package.name RUN_IN_BACKGROUND ignore
(实际上 - 最后一行与adb install
并行运行多次,以便我们确定在安装和还原(设置)完成并在安装后自动刷新Firebase注册令牌。)<)
这是一个错误,该错误已在9月18日的FCM SDK发行版中固定:
修复了一个问题,该问题偶尔会导致应用程序在收到消息时不响应(ANR)错误崩溃。
更新到com.google.firebase:firebase-messaging:17.3.2
或以后应解决此问题。如果没有,请联系支持。
尝试Firebase
和Play Services SDKs
的最新版本(v。11.4.2)。还将您的targetSDKVersion
更改为26和BuildToolsVersion
至26.0.2。
我还收到了在Android 8.0上运行的Google Pixel/Nexus设备的相同错误。更新所有库后,我没有收到任何新报告。
我们为什么要得到这个ANR,我们该怎么做才能避免这种情况?
不太确定为什么会发生这种情况。我也联系了Firebase支持以了解原因,但他们要求MCVE,因为我不知道是什么原因导致了我无法提供MCVE的问题。我在应用程序中仅使用Firebase身份验证,因此我坚信该问题与此有关。