web-dev-qa-db-fra.com

Android - Exécution d'un arrêt d'activité qui ne reprend pas

Lorsque je pousse mon application en arrière-plan et que je fais d'autres choses comme WhatsApp ou sms, onResume cela fonctionne très 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 surResume, l'application se comporte mal ...
Ne faites pas ce qu'il est nécessaire de faire, mais quand je retourne à la page d'accueil et que je reviens, cela fonctionne très bien. Aidez-moi s'il vous plaît .. comment y remédier ???

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(:<default>):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(:<default>):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(:<default>):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(:<default>):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(:<default>):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 c'est surResume ()

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 J’AI FIXÉ 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();
}
40
Salmaan

Je donne juste mes 50 cents sur la question. Catching l'exception est en effet une possibilité, mais la bonne façon 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 pour cela est:

onPause () est l'endroit où vous traitez avec l'utilisateur qui quitte votre activité. Plus important encore, toutes les modifications apportées par l'utilisateur doivent maintenant être validées (généralement par le fournisseur de contenu qui détient les données).

L'accent est à moi. Mais cela signifie que les cycles de vie Android sont conçus de telle sorte que, dans des conditions normales, onPause devrait être appelé en tant que Activity ou Fragment est Ils y font allusion dans plusieurs des pages de documentation Android :

Lorsque votre activité passe en état de 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 continuer pendant la pause (comme une vidéo) ou de conserver toute information devant être enregistrée de manière permanente au cas où l'utilisateur continue à quitter votre application. Si l'utilisateur revient à votre activité à partir de l'état de pause, 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 suspendue pendant un moment et que l'utilisateur peut se concentrer à nouveau sur votre activité. Cependant, il s’agit généralement de la première indication que l’utilisateur quitte votre activité.

Mais la ressource qui pourrait probablement vous aider est la suivante:

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

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

Ce qui se passe probablement avec vos ressources perdues est la suivante:

Lorsque votre activité reçoit un appel de la méthode onStop (), elle n'est plus visible et devrait libérer presque toutes les ressources inutiles lorsque l'utilisateur ne l'utilise pas. Une fois votre activité arrêtée, le système peut détruire l’instance s’il doit récupérer la mémoire système. ... Par défaut, le système utilise l'état de l'instance Bundle pour enregistrer les informations relatives à chaque objet View de votre présentation d'activité (telle que la valeur de texte entrée dans un objet EditText). Ainsi, si votre instance d'activité est détruite et recréée, l'état de la présentation est rétabli à son état précédent sans code requis par vous. Cependant, votre activité peut contenir davantage d'informations d'état que vous souhaitez restaurer, telles que des variables de membre qui suivent l'évolution de l'utilisateur.

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'attribut 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'objet Bundle qui sera enregistré dans le cas où votre activité serait détruite de manière inattendue. Si le système doit recréer l'instance d'activité ultérieurement, il transmet le même objet Bundle aux méthodes onRestoreInstanceState () et onCreate ().

La solution appropriée 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 String STATE_SCORE = "playerScore";
static final String 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 inverse:

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);
}
15
HenriqueMS

ne ligne: Il semble que certaines de vos variables d’activité aient été libérées de la mémoire en tant que Android Le système d’exploitation avait besoin de mémoire pour l’application Facebook.

Explication: lorsqu'une application au premier plan a besoin de plus de mémoire que ce qui est disponible, Android libère de la mémoire des applications s'exécutant en arrière-plan. Les tâches de premier plan ont toujours une priorité plus élevée que les applications en arrière-plan.

Ainsi, ce qui aurait pu arriver à votre application alors qu’elle était en arrière-plan, c’est que certaines de ses variables ont perdu leurs valeurs que vous utilisez dans votre onResume (). Pour cette raison, ils contiennent des valeurs incorrectes ou des valeurs par défaut (vous pouvez vérifier en utilisant Sysout), car ils sont recréés lorsque vous amenez à nouveau votre application au premier plan, ce qui fait que certains de vos codes ne fonctionnent pas correctement.

28
Whisky

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 assignez au lieu de comparer dans l'instruction "if". Devrait être:

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

ou

if (backgroundThreadRunning) {
    backgroundThreadRunning = false;
}
7
Diarrhio