wake-up-neo.net

Warum wird mein onResume zweimal aufgerufen?

Im Grunde mache ich das

1) Stellen Sie AlarmManager ein, um BroadcastReceiver (BCR) auszuführen.

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) Starten Sie MyActivity über 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) Lassen Sie MyActivity den Bildschirm einschalten, wenn er nicht eingeschaltet ist

@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);  
}  

Aus irgendeinem Grund stelle ich fest, dass, wenn MyActivity geöffnet wird, der Ablauf folgendermaßen abläuft: 

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

Ich bin mir nicht sicher, warum es sofort eine onPause macht. Mir fällt auf, dass dies nur passiert, wenn der Schirm durch die Flaggen aktiviert wird. Weiß jemand, warum das passiert? Gibt es eine Möglichkeit, dieses Verhalten zu verhindern?

40
Huy T

Nur für den Fall, dass jemand anderes auf dieses Thema stößt, merke ich dieses Verhalten nur, wenn ich Fragmente innerhalb einer Aktivität per XML-Layout aufblase. Ich weiß nicht, ob dieses Verhalten auch bei der Kompatibilitätsbibliothek-Version von Fragments auftritt (ich verwende Android.app.Fragment) 

Anscheinend ruft die Aktivität einmal Activity#onResume auf, bevor Fragment#onResume für alle hinzugefügten Fragmente aufgerufen wird, und dann wird Activity#onResume erneut aufgerufen.

  1. Aktivität: onCreate
  2. Fragment: onAttach
  3. Aktivität: onAttachFragments
  4. Fragment: onCreate
  5. Aktivität: onStart
  6. Aktivität: onResume
  7. Fragment: onResume
  8. Aktivität: onResume
27
ainesophaur

Wenn Sie haben ES File Explorer dann FORCE STOP . Irgendwie unterbrechen sie den Lebenszyklus Ihrer App (Kommentare deuten auf eine Art Überlagerung hin).

Mein Problem mit dem zweimaligen Auftreten von onResume war, dass onPause irgendwie aufgerufen wurde, nachdem die Aktivität erstellt wurde. Meine App wurde unterbrochen.

Und dies nur geschieht nach dem Öffnen erstmalig nach der Installation oder aus dem Studio gebaut.

Ich habe den Hinweis von einem anderen Beitrag erhalten und herausgefunden, dass es an ES File Explorer liegt. Warum scheint onResume () zweimal aufgerufen zu werden?

Sobald ich ES File Explorer beenden erzwinge, tritt dieses Schluckauf-Verhalten nicht mehr auf ... es ist frustrierend zu wissen, nachdem ich viele andere Lösungsvorschläge ausprobiert habe. Also hüte dich vor anderen unterbrechenden Apps wie dieser.

16
TWL

Ich forschte eine Weile darüber nach, weil es im Internet keine Erwähnung dieses merkwürdigen Verhaltens gibt. Ich habe keine Lösung, um dieses dunkle Seitenverhalten zu überwinden, aber ich habe ein genaues Szenario gefunden, in dem es sicherlich passiert.

onPause-onResume-onPause-onResume passiert immer dann, wenn die App nach der Installation zum ersten Mal gestartet wird. Sie können dieses Verhalten einfach aufrufen, indem Sie Änderungen am Code vornehmen und die App aus Ihrer IDE erneut ausführen (einschließlich erneutem Kompilieren).

Egal ob Sie AppCompat-Bibliotheken verwenden oder nicht. Ich habe beide Fälle getestet und das Verhalten geht weiter. 

Hinweis: Getestet mit Android Marshmallow.

Ich habe mir den Code aus diesem Thread über den Fragment- und Aktivitätslebenszyklus - geliehen und hier ist es (einfach kopieren, einfügen, Aktivität im Manifest deklarieren und Forest ausführen):

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()");
        }
    }

}
7
matusalem

wenn Sie jedes Mal Anforderungsberechtigungen versuchen, kann dies zu Problemen führen. Überprüfen Sie einfach, ob Sie diese bereits erteilt haben

requestPermissions kann es verursachen:

onCreate
onStart
onResume
onPause
onResume
6
user924

Ich weiß nicht genau, was los ist, aber ich vermute, dass Ihre Aktivität neu gestartet wird, da das Festlegen des Bildschirms vom System als Konfigurationsänderung behandelt wird. Sie könnten versuchen, die Konfiguration bei jedem Aufruf von onResume zu protokollieren, um zu sehen, ob dies der Fall ist und wenn ja, was sich tatsächlich ändert. Sie können dann das Manifest ändern, um dem System mitzuteilen, dass Ihre Aktivität die Änderung selbst übernimmt.

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

Ich hatte ein ähnliches Problem und mein Problem war, dass ich bei der Methode onCreate ()

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

Mein Aufruf zu "super". hat das onResume () zweimal ausgelöst. Es funktionierte wie beabsichtigt, nachdem ich es geändert hatte:

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

Ich hoffe es hilft.

2
Victor Lee

Ich habe ein ähnliches Problem. Meine Situation war die nächste CurrentActivity Erweitert MainActivity CurrentFragment Erweitert MainFragment

Ich habe CurrentActivity mit Absicht wie üblich eröffnet. In onCreate CurrentAcitivity habe ich CurrentFragment ersetzt.

Der Lebenszyklus war: 1. onResume MainActivity 2. onResume CurrentActivity 3. onResume MainFragment 4. onResume CurrentFragment

onPause Automatisch aufgerufen und danach erneut

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

Ich beschließe, alles noch einmal zu testen, und nach ein paar Stunden habe ich versucht, zu spielen und zu spielen, fand ich das Wurzelproblem. In MainFragment onStart rief ich jedes Mal startActivityForResult an (in meinem Fall Android-Popup für das Einschalten von Wifi), der Aufruf onPause on MainFragment war. Und wir alle wissen, dass nach onPause onResume das nächste ist. 

Es ist also kein Android-Fehler, sondern nur meiner :-) 

Viel Spaß beim Debuggen!

2
msamardzic

Ich bin auch auf diese Sequenz "onresume-onpause-onresume" gestoßen (ab 4.1.2 und höher, aber bei 2.3 nicht). Mein Problem war mit der Handhabung von Wakelock verbunden: Ich habe versehentlich vergessen, einen Wakelock freizugeben, und das erneute Einlesen verursachte einen Fehler mit der Meldung "WakeLock ist noch in der Warteschleife". Dieses Problem führte dazu, dass onPause unmittelbar nach onResume aufgerufen wurde und zu fehlerhaftem Verhalten führte.

Mein Vorschlag ist: Überprüfen Sie das Protokoll auf Fehler. Diese könnten mit diesem Problem zusammenhängen.

Ein weiterer Hinweis: Das Einschalten des Bildschirms ist möglicherweise etwas schwieriger als die Verwendung von Fensterflags. Sie können diese Antwort hier überprüfen. Sie sollten einen Empfänger einrichten, um zu prüfen, ob der Bildschirm bereits eingeschaltet ist, und die gewünschte Aktivität erst dann starten, wenn: https://stackoverflow.com/a/16346369/875442

0
Levente Dobson

Ich bin gerade auf dieses Thema gestoßen, und es scheint, dass getWindow().addFlags() und die Window-Eigenschaften im Allgemeinen ein Täter sind.

Wenn mein Code so ist

@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() wird zweimal ausgelöst, aber wenn ich requestWindowFeature() entferne, wird es nur einmal aufgerufen.

0
Actine

Ich hatte das gleiche Problem. Mein war für diesen Code in Runtime

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Ich habe es einfach manifestiert

Android:screenOrientation="landscape"

kein Problem mehr beim zweimaligen Aufruf von onCreate und onResume.

0
Boris Karloff

Es scheint, dass durch die Verwendung von Activity aus der Support-Bibliothek die Instanz automatisch gespeichert und wiederhergestellt wird. Führen Sie Ihre Arbeit daher nur aus, wenn savedInstanceStatenull ist.

0
yazjisuhail

Grundsätzlich kann eine Menge Zeug das auslösen. Einige Wiederherstellungsprozesse, die den Fokus verlieren, können dies tun. Bei einigen Apps wird dies ebenfalls passieren. Die einzige Möglichkeit, dies zu bewältigen, besteht darin, den doppelten Lauf zu blockieren. Beachten Sie, dass dies eine gute Pause einschließt.

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

Dies ist eine solide Methode, um solche Dinge zu verhindern. Es wird doppelte Lebensläufe blockieren. Es werden jedoch auch zwei Lebensläufe blockiert, die die Erinnerung bewahren. Wenn Sie nur den Fokus verloren haben und Ihr Material nicht neu aufgebaut werden muss. Es wird auch das blockieren. Was eindeutig von Vorteil sein könnte, denn wenn Sie den Lebenslauf verwenden, um einige Änderungen über den Fokus zu steuern, ist es only eigentlich wichtig, wenn Sie das Zeug aufgrund des Fokus neu erstellen müssen. Da die Pre-Draw-Listener nur von dem einen Thread aufgerufen werden können und sie nacheinander aufgerufen werden müssen, wird der Code hier nur einmal ausgeführt. Bis etwas die gesamte Aktivität ordnungsgemäß zerstört und den Wiederherstellungsblock wieder auf "False" setzt.

0
Tatarize

wie @TWL sagte ES File Explorer War das Problem für mich! Durch die Deinstallation der App wurde das Problem gelöst . Als dieser ES File Explorer installiert wurde, war onStart() -> onResume() -> onPause() -> onResume() .. das Problem .onResume() hieß 2'ce.

0
Pramod P K

Ich denke, Sie sollten sich diese Frage ansehen: Nexus 5 Wenn Sie in den Schlafmodus wechseln, wird der Lebenszyklus der Aktivität beeinträchtigt. Sie sollten Hinweise finden

ich war auch mit diesem Problem konfrontiert, weil es sich um Fragmente handelt ... die Anzahl der Fragmente, die Sie in der Aktivität onResume() haben, wird diese Anzahl von Malen nennen. zu überwinden verwendete ich Flag-Variablen in SharedPrefrences

0
Sanju Baghla