446 Stimmen

Wie man erkennt, wenn eine Android-App in den Hintergrund geht und wieder in den Vordergrund kommt

Ich versuche, eine Anwendung zu schreiben, die etwas Bestimmtes tut, wenn sie nach einer gewissen Zeit wieder in den Vordergrund gebracht wird. Gibt es eine Möglichkeit zu erkennen, wann eine App in den Hintergrund oder in den Vordergrund gebracht wird?

17voto

matdev Punkte 3672

En Android.arch.lifecycle Paket bietet Klassen und Schnittstellen, mit denen Sie lebenszyklusorientierte Komponenten erstellen können

Ihre Anwendung sollte die Schnittstelle LifecycleObserver implementieren:

public class MyApplication extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
        Log.d("MyApp", "App in background");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
        Log.d("MyApp", "App in foreground");
    }
}

Um dies zu tun, müssen Sie diese Abhängigkeit zu Ihrer build.gradle-Datei hinzufügen:

dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
}

Wie von Google empfohlen, sollten Sie den Code, der in den Lebenszyklusmethoden von Aktivitäten ausgeführt wird, auf ein Minimum reduzieren:

Ein gängiges Muster ist die Implementierung der Aktionen der abhängigen Komponenten in den Lebenszyklusmethoden von Aktivitäten und Fragmenten zu implementieren. Dieses Muster führt jedoch zu einer schlechten Organisation des Codes und zu und zur Vermehrung von Fehlern. Durch die Verwendung von Komponenten, die den Lebenszyklus berücksichtigen, können Sie können Sie den Code der abhängigen Komponenten aus den Lebenszyklusmethoden und in die Komponenten selbst verlagern.

Weitere Informationen finden Sie hier: https://developer.Android.com/topic/libraries/architecture/lifecycle

14voto

Reno Punkte 33186

ActivityLifecycleCallbacks könnte von Interesse sein, ist aber nicht gut dokumentiert.

Wenn Sie jedoch registerActivityLifecycleCallbacks () sollten Sie in der Lage sein, Rückrufe zu erhalten, wenn Aktivitäten erstellt oder zerstört werden usw. Sie können aufrufen getComponentName () für die Aktivität.

9voto

Cynichniy Bandera Punkte 5895

Fügen Sie in Ihrer Anwendung den Rückruf hinzu und überprüfen Sie die Root-Aktivität auf diese Weise:

@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
        @Override
        public void onActivityStopped(Activity activity) {
        }

        @Override
        public void onActivityStarted(Activity activity) {
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        }

        @Override
        public void onActivityResumed(Activity activity) {
        }

        @Override
        public void onActivityPaused(Activity activity) {
        }

        @Override
        public void onActivityDestroyed(Activity activity) {
        }

        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            if (activity.isTaskRoot() && !(activity instanceof YourSplashScreenActivity)) {
                Log.e(YourApp.TAG, "Reload defaults on restoring from background.");
                loadDefaults();
            }
        }
    });
}

7voto

Alécio Carvalho Punkte 13103

Sie können die ProcessLifecycleOwner einen Lebenszyklus-Beobachter zuzuordnen.

  public class ForegroundLifecycleObserver implements LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void onAppCreated() {
        Timber.d("onAppCreated() called");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onAppStarted() {
        Timber.d("onAppStarted() called");
    }

    @OnLifecycleEvent(Event.ON_RESUME)
    public void onAppResumed() {
        Timber.d("onAppResumed() called");
    }

    @OnLifecycleEvent(Event.ON_PAUSE)
    public void onAppPaused() {
        Timber.d("onAppPaused() called");
    }

    @OnLifecycleEvent(Event.ON_STOP)
    public void onAppStopped() {
        Timber.d("onAppStopped() called");
    }
}

dann auf der onCreate() Ihrer Anwendungsklasse rufen Sie dies auf:

ProcessLifecycleOwner.get().getLifecycle().addObserver(new ForegroundLifecycleObserver());

Damit können Sie die Ereignisse von ON_PAUSE y ON_STOP Ihrer Anwendung, wenn sie im Hintergrund läuft.

6voto

Komal Nikhare Punkte 252

Es gibt keine einfachen Lifecycle-Methoden, die Ihnen sagen, wann die gesamte Anwendung in den Hintergrund oder in den Vordergrund tritt.

Ich habe dies auf einfache Weise getan. Befolgen Sie die folgenden Anweisungen, um die Hintergrund-/Vordergrundphase der Anwendung zu erkennen.

Mit einer kleinen Umgehung ist es möglich. Hier, ActivityLifecycleCallbacks kommt zur Rettung. Lassen Sie mich Schritt für Schritt vorgehen.

  1. Erstellen Sie zunächst eine Klasse, die die Klasse Android.app.Anwendung und implementiert die ActivityLifecycleCallbacks Schnittstelle. In Application.onCreate() registrieren Sie den Callback.

    public class App extends Application implements 
        Application.ActivityLifecycleCallbacks {
    
        @Override
        public void onCreate() {
            super.onCreate();
            registerActivityLifecycleCallbacks(this);
        }
    }
  2. Registrieren Sie die Klasse "App" im Manifest wie unten beschrieben, <application android:name=".App" .

  3. Es gibt mindestens eine Aktivität im gestarteten Zustand, wenn die App im Vordergrund ist, und es gibt keine Aktivität im gestarteten Zustand, wenn die App im Hintergrund ist.

    Deklarieren Sie 2 Variablen wie unten in der Klasse "App".

    private int activityReferences = 0;
    private boolean isActivityChangingConfigurations = false;

    activityReferences wird die Anzahl der Aktivitäten in der gestartet Zustand. isActivityChangingConfigurations ist ein Flag, das anzeigt, ob die aktuelle Aktivität eine Konfigurationsänderung durchläuft, wie z. B. einen Orientierungswechsel.

  4. Mit dem folgenden Code können Sie erkennen, ob die App im Vordergrund ist.

    @Override
    public void onActivityStarted(Activity activity) {
        if (++activityReferences == 1 && !isActivityChangingConfigurations) {
            // App enters foreground
        }
    }
  5. So erkennen Sie, ob die App in den Hintergrund geht.

    @Override
    public void onActivityStopped(Activity activity) {
        isActivityChangingConfigurations = activity.isChangingConfigurations();
        if (--activityReferences == 0 && !isActivityChangingConfigurations) {
            // App enters background
        }
    }

Wie es funktioniert:

Dies ist ein kleiner Trick, der mit der Art und Weise zusammenhängt, wie die Lebenszyklusmethoden nacheinander aufgerufen werden. Lassen Sie mich ein Szenario durchspielen.

Angenommen, der Benutzer startet die App und die Launcher-Aktivität A wird gestartet. Die Lifecycle-Aufrufe werden sein,

A.onCreate()

A.onStart() (++activityReferences == 1) (App tritt in den Vordergrund)

A.onResume()

Jetzt startet Aktivität A Aktivität B.

A.onPause()

B.onCreate()

B.onStart() (++activityReferences == 2)

B.onResume()

A.onStop() (--activityReferences == 1)

Dann navigiert der Benutzer von Aktivität B zurück,

B.onPause()

A.onStart() (++activityReferences == 2)

A.onResume()

B.onStop() (--activityReferences == 1)

B.onDestroy()

Dann drückt der Benutzer die Home-Taste,

A.onPause()

A.onStop() (--activityReferences == 0) (App geht in den Hintergrund)

Wenn der Benutzer in Aktivität B die Home-Taste anstelle der Zurück-Taste drückt, ist es immer noch dasselbe und die activityReferences sind 0 . Daher können wir erkennen, wie die App in den Hintergrund tritt.

Was ist also die Rolle der isActivityChangingConfigurations ? Im obigen Szenario wird angenommen, dass die Aktivität B die Ausrichtung ändert. Die Rückrufsequenz wird sein,

B.onPause()

B.onStop() (--activityReferences == 0) (App tritt in den Hintergrund??)

B.onDestroy()

B.onCreate()

B.onStart() (++activityReferences == 1) (App tritt in den Vordergrund??)

B.onResume()

Deshalb haben wir eine zusätzliche Prüfung von isActivityChangingConfigurations um das Szenario zu vermeiden, wenn die Aktivität die Konfigurationsänderungen durchläuft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X