10

我们有一个Android应用程序,最近有很多ANR错误报告。这只发生在Android 7.1和8.0(不在例如4.4,5.0或6.0)。该ANR是:ANR错误“广播意图{act = com.google.firebase.INSTANCE_ID_EVENT”...“FirebaseInstanceIdInternalReceiver”适用于Android 7.1和8.0

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的任何菜鸟错误。

我很难再生这个bug。由于它只适用于Android 7.1和8.0,我认为它可能与新的打盹模式和节省电池有关,但即使使用adb shell dumpsys deviceidle force-idleetc.而测试不会再现此问题,也不会在几个地方放置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(); 
     } 
    } 
} 

我们使用谷歌播放服务和火力地堡版本11.2.0。我们的targetSdkVersion是25.

PS:上面的代码mAnalytics.init(...)给了我们StrictMode警告,因为这个initializes Flurry。但这是磁盘访问,而不是网络流量。并在此位置放入SystemClock.sleep(20000);确实不是触发任何ANR。

为什么我们会得到一个ANR,我们能做些什么来避免这种情况?

-

编辑:按从鲍勃·斯奈德的意见建议,我试图与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注册令牌在安装后自动刷新。)

+1

也看到这个,它对我来说是99.9%的Android 8.0。 –

+1

[This adb command](https://developer.android.com/topic/performance/background-optimization.html#further-optimization)可能有助于重现此问题:'adb shell cmd appops set RUN_IN_BACKGROUND ignore '。 _模拟隐式广播和后台服务不可用的情况_ –

+1

与我一样,大概100%的Android 8.0都有此ANR – ARLabs

回答

1

尝试使用最新版本的FirebasePlay Services SDKs(v。11.4.2)。 同时将您的targetSDKVersion更改为26和BuildToolsVersion更改为26.0.2。

我也在运行Android 8.0的Google Pixel/Nexus设备上收到同样的错误。更新所有库后我还没有收到任何新报告。

为什么我们会得到这个ANR,我们能做些什么来避免这种情况?

不知道为什么会发生这种情况。我联系了Firebase支持人员,以了解原因,但他们要求mcve,因为我不知道是什么原因导致我无法提供mcve。我在我的应用中只使用Firebase身份验证,所以我坚信这个问题与它有关。

+0

感谢您分享适合您的内容。我们可能会尝试更新到'targetSdkVersion 26'并告诉您这是否也适用于我们,但这可能需要我们一些时间,因为我们需要引入通知渠道并执行其他[迁移步骤](https://developer.android.com/about/versions/oreo/android-8.0-migration.html)。 PS:我们没有使用Firebase身份验证,只使用Firebase消息传递和Firebase分析。 –

+1

我已经做到了,但仍然有ANR。 – meh

相关问题