【发布时间】:2018-03-01 05:54:38
【问题描述】:
我们有一个 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,我们可以做些什么来避免这种情况?请注意,这在早期的 Android 版本上运行良好,我认为这证明我们没有做任何导致 ANR 的新手错误。
我很难重现这个错误。由于它仅在 Android 7.1 和 8.0 上,我认为它可能与新的打盹模式和电池节省有关,但即使使用 adb shell dumpsys deviceidle force-idle etc. 在测试时也不会重现此问题,也不会放入 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(...) 给了我们一个StrictMode 警告,就像这个initializes 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 注册令牌。 )
【问题讨论】:
-
我也看到了,99.9% Android 8.0。
-
This adb command 可能有助于重现问题:
adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore。 模拟隐式广播和后台服务不可用的情况 -
对我来说也是这样,可能 100% 的 Android 8.0 都有这个 ANR
-
这里也一样,我只使用分析
标签: android firebase firebase-cloud-messaging android-7.1-nougat android-8.0-oreo