Nous avons une application Android pour laquelle de nombreuses erreurs ANR ont été signalées dernièrement. Cela ne se produit que sous Android 7.1 et 8.0 (pas sous 4.4, 5.0 ou 6.0, par exemple). L'ANR est :
Broadcast of Intent { act=com.google.firebase.INSTANCE_ID_EVENT flg=0x14 cmp=com.our.package.name/com.google.firebase.iid.FirebaseInstanceIdInternalReceiver (has extras) }
La question est la suivante : Pourquoi avons-nous ce RNA, et que pouvons-nous faire pour l'éviter ? Notez que cela fonctionne très bien sur les versions antérieures d'Android, ce qui, à mon avis, prouve que nous ne commettons pas les erreurs de débutant à l'origine de l'ANR.
J'ai beaucoup de mal à reproduire ce bug. Comme il n'est présent que sur Android 7.1 et 8.0, je pense que cela peut avoir un rapport avec le nouveau mode doze et l'économie de batterie, mais même en utilisant le mode doze, je n'arrive pas à le reproduire. adb shell dumpsys deviceidle force-idle
etc. alors que le test ne reproduit pas ce problème, ni le fait de mettre en SystemClock.sleep(20000);
à plusieurs endroits.
Notre code pour InstanceIdService
est :
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();
}
}
}
Nous utilisons Google Play Services et Firebase version 11.2.0. Notre cibleSdkVersion est 25.
PS : Le code mAnalytics.init(...)
ci-dessus nous donne un avertissement StrictMode, comme ceci initialise Flurry . Mais il s'agit d'accès au disque, pas de trafic réseau. Et mettre en SystemClock.sleep(20000);
à cet endroit ne no déclencher n'importe quel ANR.
Pourquoi obtient-on un ANR, et que peut-on faire pour l'éviter ?
--
Editar: Comme suggéré dans le commentaire de Bob Snyder, j'ai essayé de tester avec adb shell cmd appops set com.our.package.name RUN_IN_BACKGROUND ignore
. Cependant, cela ne produit aucun ANR, mais empêche seulement notre récepteur de diffusion de fonctionner, comme le montre le 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.
Ma conclusion est que ce n'est peut-être pas la bonne façon de reproduire cette erreur ANR.
Pour être complet : Toutes les commandes ADB utilisées lors des tests sont :
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
(En fait, la dernière ligne est exécutée de nombreuses fois en parallèle avec le programme adb install
afin que nous soyons sûrs qu'elle prenne effet avant l'installation et la restauration (des paramètres) et que le jeton d'enregistrement Firebase soit automatiquement rafraîchi après l'installation).
3 votes
En voyant ça, c'est 99,9% Android 8.0 pour moi.
1 votes
Cette commande adb peut être utile pour reproduire le problème :
adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore
. simule les conditions dans lesquelles les diffusions implicites et les services d'arrière-plan sont indisponibles.1 votes
La même chose pour moi, probablement 100% des Android 8.0 ont cet ANR
0 votes
Même chose ici, et j'utilise seulement analytics