Android – Interruption de l’activité non reprise

Quand je pousse mon application en arrière-plan et que je fais d’autres choses comme WhatsApp ou SMS, onResume ça marche bien.
Mais j’ai récemment découvert que lorsque j’ouvre / lance l’application Facebook alors que mon application est en arrière-plan, je ne sais pas ce qui se passe …
Mais onResume, l’application se comporte mal …
Ne faites pas ce qu’il faut faire, mais quand je retourne à la page d’accueil et que je reviens, ça marche très bien. Aidez-moi s’il vous plait.

Logcat avec tous les messages (sans filtre)

10-15 12:53:59.899: I/Adreno-EGL(32033): Remote Branch: quic/LNX.LA.3.5.1_RB1.1 10-15 12:53:59.899: I/Adreno-EGL(32033): Local Patches: NONE 10-15 12:53:59.899: I/Adreno-EGL(32033): Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 + NOTHING 10-15 12:53:59.924: D/OpenGLRenderer(32033): Enabling debug mode 0 10-15 12:54:00.000: V/AlarmManager(7677): sending alarm Alarm{42cfa490 type 3 android} 10-15 12:54:00.110: I/ActivityManager(7677): Displayed uk.org.humanfocus.hfi/.EvaluateTrainingActivity: +838ms 10-15 12:54:00.114: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:00.114: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:00.114: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:02.258: V/AlarmManager(7677): sending alarm Alarm{42ebd600 type 1 com.facebook.katana} 10-15 12:54:02.274: V/AlarmManager(7677): sending alarm Alarm{42ec0ff0 type 1 com.android.chrome} 10-15 12:54:02.428: D/hardware_info(7386): hw_info_append_hw_type : device_name = speaker 10-15 12:54:03.011: W/BroadcastQueue(7677): Permission Denial: broadcasting Intent { act=android.net.conn.INET_CONDITION_ACTION flg=0x4000010 (has extras) } from null (pid=-1, uid=-1) requires com.facebook.permission.prod.FB_APP_COMMUNICATION due to registered receiver BroadcastFilter{41fdecd0 u0 ReceiverList{42b2f608 31941 com.facebook.katana/10103/u0 remote:429a17e8}} 10-15 12:54:03.011: W/BroadcastQueue(7677): Permission Denial: broadcasting Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } from null (pid=-1, uid=-1) requires com.facebook.permission.prod.FB_APP_COMMUNICATION due to registered receiver BroadcastFilter{41fdecd0 u0 ReceiverList{42b2f608 31941 com.facebook.katana/10103/u0 remote:429a17e8}} 10-15 12:54:03.118: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:03.118: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:03.118: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:03.140: D/WifiStateMachine(7677): handleMessage: X 10-15 12:54:03.141: D/GCoreFlp(8174): Unknown pending intent to remove. 10-15 12:54:03.145: W/fb4a(:):AbstractMqttPushService(31941): Attempt to start service that is already started 10-15 12:54:03.242: D/WifiStateMachine(7677): handleMessage: E msg.what=131155 10-15 12:54:03.242: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:03.243: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:03.245: D/WifiStateMachine(7677): handleMessage: X 10-15 12:54:03.319: D/dalvikvm(31941): GC_CONCURRENT freed 1833K, 9% free 20190K/22072K, paused 5ms+7ms, total 86ms 10-15 12:54:03.320: D/dalvikvm(31941): WAIT_FOR_CONCURRENT_GC blocked 68ms 10-15 12:54:03.323: W/MediaPlayer-JNI(31941): MediaPlayer finalized without being released 10-15 12:54:03.452: W/BroadcastQueue(7677): Permission Denial: broadcasting Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4000010 (has extras) } from null (pid=-1, uid=-1) requires com.facebook.permission.prod.FB_APP_COMMUNICATION due to registered receiver BroadcastFilter{42b51d68 u0 ReceiverList{429feb50 31941 com.facebook.katana/10103/u0 remote:41fb8788}} 10-15 12:54:03.573: W/fb4a(:):JACKSON_FALLBACK(31941): Using com.fasterxml.jackson.databind.deser.std.EnumDeserializer@42914bc8 to deserialize [simple type, class com.facebook.common.util.TriState] 10-15 12:54:03.587: W/fb4a(:):JACKSON_FALLBACK(31941): Using com.fasterxml.jackson.databind.deser.std.EnumDeserializer@42bb3100 to deserialize [simple type, class com.facebook.contacts.graphql.contactprofiletype.ContactProfileType] 10-15 12:54:03.957: D/dalvikvm(31941): GC_CONCURRENT freed 3400K, 15% free 20455K/23952K, paused 4ms+7ms, total 88ms 10-15 12:54:03.957: D/dalvikvm(31941): WAIT_FOR_CONCURRENT_GC blocked 75ms 10-15 12:54:04.099: W/fb4a(:):JACKSON_FALLBACK(31941): Using BeanSerializer for com.facebook.katana.newbookmark.qe.NewBookmarkConfig to serialize class com.facebook.katana.newbookmark.qe.NewBookmarkConfig 10-15 12:54:04.119: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:04.120: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:04.120: D/WifiStateMachine(7677): processMsg: L2ConnectedState 10-15 12:54:04.124: D/WifiStateMachine(7677): handleMessage: X 10-15 12:54:04.177: W/fb4a(:):JACKSON_FALLBACK(31941): Using com.fasterxml.jackson.databind.deser.std.EnumDeserializer@42a30980 to deserialize [simple type, class com.facebook.platform.webdialogs.PlatformWebViewActionManifest$FetchState] 10-15 12:54:04.197: I/dalvikvm(31941): Could not find method com.android.internal.widget.ILockSettings$Stub.a, referenced from method com.facebook.keyguardtype.LockSettingsServiceKeyguardTypeResolver.b 10-15 12:54:04.197: W/dalvikvm(31941): VFY: unable to resolve static method 5338: Lcom/android/internal/widget/ILockSettings$Stub;.a (Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings; 10-15 12:54:04.197: D/dalvikvm(31941): VFY: replacing opcode 0x71 at 0x0023 10-15 12:54:04.440: I/SBar.NetworkController(7758): onSignalStrengthsChanged SignalStrength: 19 0 -120 -160 -120 -1 -1 99 2147483647 2147483647 2147483647 2147483647 2147483647 gsm|lte 0 -108 -1 false 5 5 0 0 0 99 99 99 5 level=5 10-15 12:54:04.814: V/WebViewChromiumFactoryProvider(31941): Binding Chromium to main looper Looper (main, tid 1) {41f8cbd0} 10-15 12:54:04.815: I/LibraryLoader(31941): Expected native library version number "",actual native library version number "" 10-15 12:54:04.816: I/chromium(31941): [INFO:library_loader_hooks.cc(116)] Chromium logging enabled: level = 0, default verbosity = 0 10-15 12:54:04.817: I/BrowserStartupController(31941): Initializing chromium process, renderers=0 10-15 12:54:04.822: E/AudioManagerAndroid(31941): BLUETOOTH permission is missing! 10-15 12:54:04.864: W/chromium(31941): [WARNING:proxy_service.cc(890)] PAC support disabled because there is no system implementation 10-15 12:54:05.121: D/WifiStateMachine(7677): handleMessage: E msg.what=151572 10-15 12:54:05.121: D/WifiStateMachine(7677): processMsg: ConnectedState 10-15 12:54:05.122: D/WifiStateMachine(7677): processMsg: L2ConnectedState 

Et ceci est onResume ()

 super.onResume(); if (backgroundThreadRunning == true) { backgroundThreadRunning = false; } if (Constants.isVideoEditing) editingProgress.setVisibility(View.VISIBLE); else editingProgress.setVisibility(View.GONE); if (Constants.isAudioProcessing) addAudioProgress.setVisibility(View.VISIBLE); else addAudioProgress.setVisibility(View.GONE); if (isHomeKeyPressed() && !(isRecentActivity)) { isRecentActivity = false; homeKeyPressed(false); AlertDialog.Builder ab = new AlertDialog.Builder( CreateTrainingActivity.this); ab.setMessage( "Due to Other Application Launches, video process will be cancelled!\nAre you sure you want to cancel?") .setPositiveButton("Yes", dialogClickListener) .setNegativeButton("No", dialogClickListener).show(); } }; 

EDIT: COMMENT JE FIXE LE NUMÉRO

J’ai écrit ce code dans la méthode onResume()

 try { // check if any view exists on current view style = ((Button) findViewById(R.id.xyz_button)); } catch (Exception e) { // Button was not found // It means, your button doesn't exist on the "current" view // It was freed from the memory, therefore stop of activity was performed // In this case I restart my app Intent i = new Intent(); i.setClass(getApplicationContext(), MainActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); // Show toast to the user Toast.makeText(getApplicationContext(), "Data lost due to excess use of other apps", Toast.LENGTH_LONG).show(); } 

Juste donner mes 50 cents sur la question. La capture de l’exception est en effet une possibilité, mais la manière correcte de traiter le problème d’une activité tuée par le système pour ses ressources en arrière-plan est un problème courant dans Android et selon Google, la solution est la suivante:

onPause () est l’endroit où vous traitez avec l’utilisateur qui quitte votre activité. Plus important encore, toute modification apscope par l’utilisateur doit à ce stade être validée (généralement pour le ContentProvider détenant les données).

L’accent est sur moi. Mais cela signifie que les cycles de vie d’Android sont conçus de manière à ce que, dans des conditions normales, onPause soit appelé en tant onPause ou Fragment est envoyé en arrière-plan. Ils y font allusion dans plusieurs des pages de documentation Android :

Lorsque votre activité entre en pause, le système appelle la méthode onPause () sur votre activité, ce qui vous permet d’arrêter les actions en cours qui ne doivent pas être interrompues (par exemple, une vidéo) ou de conserver les informations à enregistrer définitivement. l’utilisateur continue à quitter votre application. Si l’utilisateur retourne à votre activité à partir de l’état suspendu, le système le reprend et appelle la méthode onResume ().

Remarque: Lorsque votre activité reçoit un appel à onPause (), cela peut indiquer que l’activité sera interrompue pendant un moment et que l’utilisateur pourra revenir à son activité. Cependant, c’est généralement la première indication que l’utilisateur quitte votre activité.

Mais les ressources les plus susceptibles de vous aider sont les deux suivantes:

http://developer.android.com/training/basics/activity-lifecycle/stopping.html

http://developer.android.com/training/basics/activity-lifecycle/recreating.html

Voici ce qui se passe probablement avec vos ressources perdues:

Lorsque votre activité reçoit un appel à la méthode onStop (), elle n’est plus visible et doit libérer presque toutes les ressources inutiles lorsque l’utilisateur ne l’utilise pas. Une fois votre activité arrêtée, le système risque de détruire l’instance si elle doit récupérer la mémoire système. … Par défaut, le système utilise l’état de l’instance d’offre pour enregistrer des informations sur chaque object View dans la présentation de votre activité (par exemple, la valeur de texte saisie dans un object EditText). Ainsi, si votre instance d’activité est détruite et recréée, l’état de la mise en page est restauré à son état précédent sans aucun code requirejs. Cependant, votre activité peut contenir davantage d’informations d’état que vous souhaitez restaurer, telles que les variables de membre qui suivent la progression de l’utilisateur dans l’activité.

Remarque: Pour que le système Android puisse restaurer l’état des vues de votre activité, chaque vue doit avoir un identifiant unique, fourni par l’atsortingbut android: id.

Pour enregistrer des données supplémentaires sur l’état d’activité, vous devez remplacer la méthode de rappel onSaveInstanceState (). Le système appelle cette méthode lorsque l’utilisateur quitte votre activité et lui transmet l’object Bundle qui sera enregistré en cas de destruction inattendue de votre activité. Si le système doit recréer l’instance d’activité plus tard, il transmet le même object Bundle aux méthodes onRestoreInstanceState () et onCreate ().

La solution correcte consiste à remplacer et à mettre en œuvre les méthodes de cycle de vie de l’activité / du fragment, selon les besoins.

Deux exemples donnés par Google :

  static final Ssortingng STATE_SCORE = "playerScore"; static final Ssortingng STATE_LEVEL = "playerLevel"; ... @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state savedInstanceState.putInt(STATE_SCORE, mCurrentScore); savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); // Always call the superclass so it can save the view hierarchy state super.onSaveInstanceState(savedInstanceState); } Caution: Always call the superclass implementation of onSaveInstanceState() so the default implementation can save the state of the view hierarchy. 

Et l’opération de restauration inversée:

 public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy super.onRestoreInstanceState(savedInstanceState); // Restore state members from saved instance mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } 

One Line : Il semble que certaines de vos variables d’activité aient été libérées de la mémoire, car Android OS avait besoin de mémoire pour l’application Facebook.

Explication : Lorsqu’une application au premier plan a besoin de plus de mémoire que celle disponible, Android libère de la mémoire des applications exécutées en arrière-plan. Les tâches en avant-plan ont toujours une priorité plus élevée que les applications en arrière-plan.

Donc, ce qui est arrivé à votre application en arrière-plan, c’est que certaines de ses variables ont perdu leurs valeurs que vous utilisez dans votre onResume (). De ce fait, ils détiennent des valeurs erronées ou des valeurs par défaut (vous pouvez les vérifier à l’aide de Sysout) car ils sont recréés lorsque vous transférez à nouveau votre application au premier plan et qu’une partie de votre code ne fonctionne pas correctement.

J’espère que vous avez déjà résolu le problème, mais il y a une erreur dans votre code, peut-être liée:

 if (backgroundThreadRunning = true) { backgroundThreadRunning = false; } 

vous atsortingbuez au lieu de comparer dans l’instruction “if”. Devrait être:

 if (backgroundThreadRunning == true) { backgroundThreadRunning = false; } 

ou

 if (backgroundThreadRunning) { backgroundThreadRunning = false; }