Pourquoi mon onResume est-il appelé deux fois?

Fondamentalement, c’est ce que je fais

1) Configurez AlarmManager pour exécuter BroadcastReceiver (BCR)

Intent intent = new Intent(m_Context, BCR.class); intent.putExtras(extras); PendingIntent pendingIntent = PendingIntent.getBroadcast(m_Context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, StartTime, pendingIntent) 

2) Démarrer MyActivity à partir de BCR

 @Override public void onReceive(Context context, Intent intent) { Intent newIntent = new Intent(context, MyActivity.class); newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); context.startActivity(newIntent); } 

3) Avoir MyActivity allume l’écran s’il n’est pas allumé

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(LayoutParams.FLAG_DISMISS_KEYGUARD); getWindow().addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED); getWindow().addFlags(LayoutParams.FLAG_TURN_SCREEN_ON); setContentView(R.layout.myactivity); } @Overide protected void onNewIntent(Intent intent) { super.onNewIntent(intent); } 

Pour une raison quelconque, je remarque que lorsque MyActivity est ouvert, son stream va comme suit:

onCreate / onNewIntent -> onResume -> onPause -> onResume

Je ne sais pas pourquoi il fait une onPause tout de suite. Je remarque que cela ne se produit que lorsque la sélection est activée par les drapeaux. Est-ce que quelqu’un sait pourquoi cela se produit? Y a-t-il un moyen d’éviter ce comportement?

    Juste au cas où quelqu’un d’autre se heurterait à cela, je semble remarquer ce comportement uniquement lorsque je gonfle des fragments à l’intérieur d’une activité via la disposition XML. Je ne sais pas si ce comportement se produit également avec la version de bibliothèque de compatibilité de Fragments (j’utilise android.app.Fragment)

    Il semble que l’activité appellera l’ Activity#onResume une fois avant d’appeler le Fragment#onResume sur les fragments ajoutés, puis appellera à nouveau l’ Activity#onResume .

    1. Activité: onCreate
    2. Fragment: onAttach
    3. Activité: onAttachFragments
    4. Fragment: onCreate
    5. Activité: onStart
    6. Activité: onResume
    7. Fragment: onResume
    8. Activité: onResume

    Si vous avez l’explorateur de fichiers ES, arrêtez-le. D’une manière ou d’une autre, ils interrompent le cycle de vie de votre application.

    Mon problème avec onResume étant causé deux fois, c’est que onPause était en quelque sorte appelé après la création de l’activité, quelque chose interrompait mon application.

    Et cela ne se produit qu’après avoir été ouvert pour la première fois après l’installation ou construit à partir du studio.

    J’ai eu le CLUE d’un autre poste et j’ai découvert que c’était à cause de ES File Explorer. Pourquoi onResume () semble-t-il être appelé deux fois?

    Dès que j’interromps l’ES File Explorer, ce problème ne se produit plus … C’est très frustrant de savoir après avoir essayé tant d’autres solutions proposées.

    J’ai fait des recherches à ce sujet pendant un moment parce que sur Internet, il n’y a aucune mention de ce comportement bizarre. Je n’ai pas de solution pour surmonter ce comportement obscur, mais j’ai trouvé un scénario exact quand cela se produit certainement.

    onPause-onResume-onPause-onResume se produit à chaque fois que l’application démarre la première fois après l’installation. Vous pouvez simplement invoquer ce comportement en modifiant le code et en réexécutant (ce qui inclut la recompilation) de l’application depuis votre EDI.

    Peu importe si vous utilisez les librairies AppCompat ou non. J’ai testé les deux cas et le comportement continue.

    Note: Testé sur Android Marshmallow.

    J’ai emprunté le code de ce thread au sujet du cycle de vie des fragments et des activités et le voici (il suffit de copier, coller, déclarer une activité dans manifeste et exécuter Forest run):

     import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; import android.content.Context; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class TestActivity extends Activity { private static final Ssortingng TAG = "ACTIVITY"; public TestActivity() { super(); Log.d(TAG, this + ": this()"); } protected void finalize() throws Throwable { super.finalize(); Log.d(TAG, this + ": finalize()"); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, this + ": onCreate()"); TextView tv = new TextView(this); tv.setText("Hello world"); setContentView(tv); if (getFragmentManager().findFragmentByTag("test_fragment") == null) { Log.d(TAG, this + ": Existing fragment not found."); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.add(new TestFragment(), "test_fragment").commit(); } else { Log.d(TAG, this + ": Existing fragment found."); } } @Override public void onStart() { super.onStart(); Log.d(TAG, this + ": onStart()"); } @Override public void onResume() { super.onResume(); Log.d(TAG, this + ": onResume()"); } @Override public void onPause() { super.onPause(); Log.d(TAG, this + ": onPause()"); } @Override public void onStop() { super.onStop(); Log.d(TAG, this + ": onStop()"); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, this + ": onDestroy()"); } public static class TestFragment extends Fragment { private static final Ssortingng TAG = "FRAGMENT"; public TestFragment() { super(); Log.d(TAG, this + ": this() " + this); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, this + ": onCreate()"); } @Override public void onAttach(final Context context) { super.onAttach(context); Log.d(TAG, this + ": onAttach(" + context + ")"); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Log.d(TAG, this + ": onActivityCreated()"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG, this + ": onCreateView()"); return null; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Log.d(TAG, this + ": onViewCreated()"); } @Override public void onDestroyView() { super.onDestroyView(); Log.d(TAG, this + ": onDestroyView()"); } @Override public void onDetach() { super.onDetach(); Log.d(TAG, this + ": onDetach()"); } @Override public void onStart() { super.onStart(); Log.d(TAG, this + ": onStart()"); } @Override public void onResume() { super.onResume(); Log.d(TAG, this + ": onResume()"); } @Override public void onPause() { super.onPause(); Log.d(TAG, this + ": onPause()"); } @Override public void onStop() { super.onStop(); Log.d(TAG, this + ": onStop()"); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, this + ": onDestroy()"); } } } 

    Je ne sais pas avec certitude ce qui se passe, mais je soupçonne que votre activité est en cours de redémarrage car la configuration de l’écran est traitée par le système comme une modification de la configuration. Vous pouvez essayer de connecter la configuration à chaque appel à onResume pour voir si c’est ce qui se passe et, le cas échéant, ce qui change réellement. Vous pouvez ensuite modifier le manifeste pour indiquer au système que votre activité va gérer elle-même le changement.

     protected void onResume() [ super.onResume(); Configuration config = new Configuration(); config.setToDefaults(); Log.d("Config", config.toSsortingng()); . . . } 

    J’ai eu un problème similaire, et mon problème était que, à la méthode onCreate (), je faisais:

     @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.friends); <-- problem } 

    Mon appel à "super" déclenchait le onResume () deux fois. Cela a fonctionné comme prévu après que je l'ai changé pour juste:

     @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.friends); <-- 'super.' removed } 

    J'espère que cela aide.

    J’ai un problème similaire. Ma situation était la suivante. CurrentActivity étend MainActivity CurrentFragment étend MainFragment

    J’ouvrais CurrentActivity avec intention comme d’habitude. Dans onCreate CurrentAcitivity, je remplaçais CurrentFragment.

    Cycle de vie était: 1. onResume MainActivity 2. onResume CurrentActivity 3. onResume MainFragment 4. onResume CurrentFragment

    appelé onPause Automatiquement, et après encore

    1. onResume MainActivity
    2. onResume CurrentActivity
    3. onResume MainFragment
    4. onResume CurrentFragment

    Je décide de tout tester à nouveau et après quelques heures passées à essayer et à jouer, j’ai trouvé le problème fondamental. Dans MainFragment onStart, j’appelais startActivityForResult à chaque fois (dans mon cas, popup pour Android pour activer Wifi) qui était appelé onPause sur MainFragment. Et nous soaps tous qu’après onPause, la prochaine est surResume.

    Donc ce n’est pas un bug Android, c’est seulement le mien 🙂

    Bonne mise au point du cycle de vie!

    J’ai aussi couru dans cette séquence onresume-onpause-onresume (sur 4.1.2 et supérieur, mais je n’ai pas expérimenté cela sur 2.3). Mon problème était lié à la manipulation de wakelock: j’ai accidentellement oublié de sortir un wakelock et le réacquérir a provoqué une erreur avec un message “WakeLock finalisé pendant qu’il est toujours en attente”. Ce problème a provoqué l’appel à onPause immédiatement après onResume et a entraîné un comportement défectueux.

    Ma suggestion est la suivante: vérifiez les erreurs dans le journal, celles-ci peuvent être liées à ce problème.

    Un autre conseil: activer l’écran peut être un peu plus compliqué que d’utiliser simplement des drapeaux de fenêtre. Vous voudrez peut-être vérifier cette réponse ici – cela vous suggère de configurer un récepteur pour vérifier si l’écran a déjà été allumé et de lancer l’activité souhaitée uniquement après: https://stackoverflow.com/a/16346369/875442

    Il semble que l’utilisation d’ Activity partir de la bibliothèque de support enregistre et restaure automatiquement l’instance. Par conséquent, faites votre travail savedInstanceState si savedInstanceState est null .

    Je viens juste de le rencontrer, et il semble que getWindow().addFlags() et les propriétés de réglage des Window en général pourraient être un coupable.

    Quand mon code est comme ça

     @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); setContentView(R.layout.activity_generic_fragment_host); // performing fragment transaction when instance state is null... 

    onResume() est déclenché deux fois, mais lorsque je supprime requestWindowFeature() , il n’est appelé qu’une seule fois.

    Je pense que vous devriez jeter un oeil à cette question: Nexus 5 passer en mode veille rend l’activité buggy cycle de vie Vous devriez trouver des pistes

    Fondamentalement, beaucoup de choses peuvent déclencher cela. Certains processus de reprise qui perdent le focus peuvent le faire. Quelques applications le provoqueront également. La seule façon de faire face est de bloquer le double fonctionnement. Notez que cela aura également une pause errante pour une bonne mesure.

      boolean resumeblock = false; @Override protected void onResume() { super.onResume(); sceneView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { sceneView.getViewTreeObserver().removeOnPreDrawListener(this); if (resumeblock) return false; resumeblock = true; //Some code. return false; } }); } 

    C’est un moyen solide de prévenir de telles choses. Il bloquera les doubles CV. Mais, il bloquera également deux CV qui préservent la mémoire. Donc, si vous venez de perdre le focus et qu’il n’est pas nécessaire de reconstruire vos données. Cela va bloquer ça aussi. Ce qui pourrait être un avantage évident, car si vous utilisez le CV pour contrôler certains changements sur le focus, vous ne vous souciez que de reconstruire ce contenu à cause du focus. Comme les écouteurs de pré-dessin ne peuvent être appelés que par un seul thread et qu’ils doivent être appelés en séquence, le code ne sera exécuté qu’une seule fois. Jusqu’à ce que quelque chose détruit correctement l’activité entière et ramène resumeblock à false.

    J’ai également rencontré ce problème à cause de fragments. Le nombre de fragments que vous avez dans l’activité onResume() appellera ce nombre de fois. pour surmonter j’ai utilisé des variables de drapeau dans SharedPrefrences

    si vous essayez de demander des permissions à chaque fois que cela peut causer de tels problèmes, vérifiez simplement si vous les avez déjà accordées

    requestPermissions peut le provoquer:

     onCreate onStart onResume onPause onResume