최근에보고 된 ANR 오류가 많은 Android 앱이 있습니다. Android 7.1 및 8.0에서만 발생합니다 (예 : 4.4, 5.0 또는 6.0이 아님). ANR은 다음과 같습니다 왜 우리가이 ANR을받을 수 있나요, 우리는이를 방지하기 위해 무엇을 할 수ANR 오류 "의도 공개 (act = com.google.firebase.INSTANCE_ID_EVENT"... Android 7.1 및 8.0 용 "FirebaseInstanceIdInternalReceiver"
Broadcast of Intent { act=com.google.firebase.INSTANCE_ID_EVENT flg=0x14 cmp=com.our.package.name/com.google.firebase.iid.FirebaseInstanceIdInternalReceiver (has extras) }
질문은?이 점은 이전 Android 버전에서 잘 작동합니다. 제 생각에는 ANR을 야기한 루키 실수를하지 않는다는 것이 증명되었습니다.
이 버그를 재생하는 데 어려움을 겪고 있습니다. 안드로이드 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();
}
}
}
우리는 구글 서비스 및 중포 기지 버전 11.2.0 재생 사용합니다. 우리의 targetSdkVersion은 25입니다.
추신 : 위의 mAnalytics.init(...)
코드는 StrictMode 경고를 제공합니다.이 코드는 initializes Flurry입니다. 그러나 이것은 네트워크 액세스가 아니라 디스크 액세스입니다. 이 위치에 SystemClock.sleep(20000);
을 넣으면 이 아니며은 ANR을 트리거합니다.
왜 우리는 ANR을 얻습니까? 이것을 피하려면 어떻게해야합니까?
-
편집 : 밥 스나이더에서 주석의 제안으로 당는, 나는 adb shell cmd appops set com.our.package.name RUN_IN_BACKGROUND ignore
과 테스트 노력했다. 그러나,이 모든 ANR을 생성하지 않습니다, 그것은 단지 로그 캣과 같이 실행에서 우리의 방송 수신기를 중지 :
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 install
와 병렬로 여러 번 실행하고 - 사실 (
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 명령은 (설정 중) 복원이 완료되고 설치 후 Firebase 등록 토큰이 자동으로 새로 고쳐집니다.)
또 이걸 보면 99.9 %의 Android 8.0이 필요합니다. –
[이 adb 명령] (https://developer.android.com/topic/performance/background-optimization.html#further-optimization)이 문제를 재현하는 데 도움이 될 수 있습니다 :'adb shell cmd appops set RUN_IN_BACKGROUND ignore '. _ 암시 적 브로드 캐스트 및 백그라운드 서비스를 사용할 수없는 상태를 _ 함합니다 ._ –
안드로이드 8.0의 100 %가이 ANR을 가지고 있습니다. – ARLabs