Pourquoi mon onResume est appelé deux fois?

en gros, C'est ce que je fais

1) Régler 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 Monactivité à 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 tourner sur l'écran si elle n'est pas sur

@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 juste quand Monactivité est ouverte, c'est le flux qui fait:

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

Je ne sais pas pourquoi il fait une onPause tout de suite. Je remarque que cela se produit uniquement lorsque le dépistage est activé par les drapeaux. Personne ne sait pourquoi cela se produit? Y a-t-il un moyen de prévenir ce comportement?

39
demandé sur Huy T 2013-04-16 04:19:40

13 réponses

juste au cas où quelqu'un d'autre tomberait dans cette situation, je semble remarquer ce comportement seulement quand je gonfle des fragments à l'intérieur d'une activité via XML layout. Je ne sais pas si ce comportement se produit aussi avec la version de la bibliothèque de compatibilité de Fragments (j'utilise android.App.Fragment)

il semble que l'activité appellera Activity#onResume une fois avant d'appeler Fragment#onResume à tout fragment ajouté, puis appellera à nouveau 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
26
répondu ainesophaur 2015-07-06 22:19:21

Si vous avez ES File Explorer puis FORCER l'ARRÊT . D'une manière ou d'une autre, ils interrompent le cycle de vie de votre application (les commentaires suggèrent une sorte de superposition) .

mon problème avec onResume causé deux fois était parce que onPause était en quelque sorte appelé après que l'activité a été créée.. quelque chose interrompait mon application.

et ce seulement arrive après avoir été ouvert pour le première fois après l'installation ou construit à partir du studio .

j'ai eu le indice d'un autre post 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 I force stop ES File Explorer , ce comportement de hoquet ne se produit plus... il est frustrant de savoir après avoir essayé beaucoup d'autres les solutions proposées. Alors méfiez-vous de toute autre application interrompant comme celle-ci.

15
répondu TWL 2018-09-19 17:21:59

j'ai fait des recherches à ce sujet pendant un certain temps parce que sur internet il n'y a aucune mention de ce comportement étrange. Je n'ai pas de solution pour surmonter ce comportement obscur, mais j'ai trouvé un scénario exact quand il se produit.

onPause-onResume-onPause-onResume se produit juste à chaque fois, quand l'application commence la première fois après l'installation. Vous pouvez simplement invoquer ce comportement en faisant n'importe quel changement dans le code et la redirection (qui inclut la recompilation) l'application de votre IDE.

peu importe si vous utilisez AppCompat libs ou non. J'ai testé les deux cas et le comportement continue.

Note: testé sur Android Marshmallow.

j'ai emprunté le code de ce fil sur le cycle de vie des fragments et de l'activité et il est ici (il suffit de copier, coller, déclarer l'activité dans le manifeste et courir 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 String 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 String 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()");
        }
    }

}
6
répondu matusalem 2017-05-23 12:26:14

Je ne sais pas avec certitude ce qui se passe, mais je soupçonne que votre activité est redémarrée parce que la mise en marche de l'écran est traitée par le système comme un changement de configuration. Vous pouvez essayer d'enregistrer la configuration sur chaque appel à onResume pour voir si c'est ce qui se passe et, si c'est le cas, ce qui est en train de changer. Vous pouvez alors modifier le Manifeste pour dire au système que votre activité gérera le changement par elle-même.

protected void onResume() [
    super.onResume();
    Configuration config = new Configuration();
    config.setToDefaults();
    Log.d("Config", config.toString());
    . . .
}
5
répondu Ted Hopp 2013-04-16 00:30:26

j'avais un problème similaire, et mon problème était qu'à la méthode onCreate (), je faisais:

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

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

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

J'espère que ça aidera.

2
répondu Victor Lee 2015-01-31 21:40:27

j'ai le même problème. Ma situation était la suivante activité courante s'étend activité principale CurrentFragment s'étend MainFragment

j'ai été l'ouverture CurrentActivity avec l'intention, comme d'habitude. Dans le numéro CurrentAcitivity , Je remplaçais CurrentFragment.

Cycle de vie a été: 1. onResume MainActivity 2. onsume CurrentActivity 3. onResume MainFragment 4. onResume CurrentFragment

fait appel Àpause automatiquement, et ensuite à nouveau

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

je décide de tester à nouveau le tout et après quelques heures passées à essayer et en jouant j'ai trouvé le problème de racine. Dans MainFragment onStart j'appelaisstartactivityforresult à chaque fois (dans mon cas, android popup pour allumer le Wifi) qui était appelé onPause sur MainFragment. Et nous savons tous qu'après onPause suivant est onResume.

donc ce n'est pas un bug Android, c'est seulement le mien: -)

Heureux cycle de vie de debuging!

2
répondu msamardzic 2017-04-20 23:07:38

j'ai aussi rencontré cette séquence onresume-onpause-onresume (sur 4.1.2 et ci-dessus, mais je ne l'ai pas fait sur 2.3). Mon problème était lié à la manipulation de wakelock: j'ai accidentellement oublié de libérer un wakelock et sa réacquisition a causé une erreur avec un message "wakelock finalisé alors qu'il est encore détenu". Ce problème a conduit à onPause étant appelé immédiatement après onResume et a entraîné un comportement défectueux.

ma suggestion est: vérifiez les erreurs dans le journal, ceux pourraient être liés à cette question.

un autre indice: allumer l'écran peut être un peu plus délicat que d'utiliser simplement des indicateurs de fenêtre. Vous pouvez vérifier cette réponse ici - il vous suggère de configurer un récepteur pour vérifier si l'écran a déjà été activé et de lancer l'activité désirée seulement après: https://stackoverflow.com/a/16346369/875442

0
répondu Levente Dobson 2017-05-23 11:54:39

il semble que l'utilisation de Activity de la bibliothèque de support sauve et restaure l'instance automatiquement. Par conséquent, ne faites votre travail que si savedInstanceState est null .

0
répondu yazjisuhail 2014-05-14 19:43:50

je viens de tomber sur ceci, et il semble que getWindow().addFlags() et modifier Window propriétés en général pourrait être un coupable.

quand mon code est comme ceci

@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 quand je supprime requestWindowFeature() , il est appelé seulement une fois.

0
répondu Actine 2016-01-08 20:48:52

je pense que vous devriez jeter un oeil à cette question: Nexus 5 d'aller dormir, le mode d'activité du cycle de vie buggy Vous devriez trouver des fils

0
répondu Mathias Seguy Android2ee 2017-05-23 12:02:23

Fondamentalement, beaucoup de choses peuvent déclencher cette. Certains processus de CV qui perd la concentration peut le faire. Quelques applications vont provoquer ça aussi. La seule façon de faire face est de bloquer la double course. Notez qu'il y aura aussi une pause errante pour faire 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 solide moyen de prévenir de telles choses. Ça bloquera les doubles CV. Mais, il bloquera aussi deux CV qui préservent la mémoire. Donc, si vous avez juste perdu la concentration et il n'a pas besoin de reconstruis tes affaires. Il bloque aussi. Ce qui pourrait être un avantage clairement, puisque si vous utilisez le CV pour contrôler certains changements sur la mise au point, vous seulement se soucient réellement si vous avez besoin de reconstruire ce truc à cause de la mise au point. Puisque les pré-draw listeners ne peuvent être appelés que par un seul thread et qu'ils doivent être appelés en séquence, le code ici ne sera lancé qu'une seule fois. Jusqu'à ce que quelque chose détruise toute l'activité et renvoie le resumeblock à false.

0
répondu Tatarize 2017-06-14 15:58:33

j'ai également fait face à cette question c'est à cause de fragments.. le nombre de fragments que vous avez dans l'activité onResume() appellent le nombre de fois. pour surmonter j'ai utilisé des variables de drapeau dans SharedPrefrences

0
répondu Sanju Baghla 2017-07-14 09:20:48

si vous essayez de demander des permissions à chaque fois qu'il peut causer de tels problèmes, il suffit de vérifier si vous les avez déjà accordées

requestPermissions peut causer:

onCreate
onStart
onResume
onPause
onResume
0
répondu user924 2018-04-05 18:54:30