Ich bin hier verwirrt. Warum kann Android dafür keine einfache Überschreibung der Anwendungsklasse bereitstellen? Ist es zu schwierig, dies auf Plattformebene zu wissen? @Override protected void onApplicationSentToBackground () {}
Chuck D
2
@ChuckD - das wäre sinnvoll, was das Android SDK manchmal gerne zu vermeiden scheint. : /
iOS hat dies in den Spaten, nicht sicher, warum Google dies so schwer macht. Es ist so ein offensichtliches Bedürfnis.
Jerry Destremps
Antworten:
388
Es gibt nur wenige Möglichkeiten, um festzustellen, ob Ihre Anwendung im Hintergrund ausgeführt wird, aber nur eine davon ist absolut zuverlässig:
Die richtige Lösung (Kredite gehen zu Dan , CommonsWare und NeTeInStEiN )
verfolgen Sichtbarkeit Ihrer Anwendung selbst verwendet Activity.onPause, Activity.onResumeMethoden. Speichern Sie den Status "Sichtbarkeit" in einer anderen Klasse. Gute Entscheidungen sind Ihre eigene Implementierung von Applicationoder a Service(es gibt auch einige Variationen dieser Lösung, wenn Sie die Aktivitätssichtbarkeit des Dienstes überprüfen möchten).
Beispiel
Implementieren Sie eine benutzerdefinierte ApplicationKlasse (beachten Sie die isActivityVisible()statische Methode):
Fügen Sie onPauseund onResumezu jedem Activityim Projekt hinzu (Sie können einen gemeinsamen Vorfahren für Ihre Aktivitäten erstellen, wenn Sie möchten, aber wenn Ihre Aktivität bereits von MapActivity/ ListActivityusw. erweitert wurde, müssen Sie immer noch Folgendes von Hand schreiben):
Update ActivityLifecycleCallbacks wurden in API Level 14 (Android 4.0) hinzugefügt. Sie können sie verwenden, um zu verfolgen, ob eine Aktivität Ihrer Anwendung derzeit für den Benutzer sichtbar ist. Überprüfen Sie die Antwort von Cornstalks unten für die Details.
Die falsche habe
ich verwendet, um die folgende Lösung vorzuschlagen:
Sie können die aktuelle Vordergrund- / Hintergrundanwendung erkennen, mit ActivityManager.getRunningAppProcesses()der eine Liste von RunningAppProcessInfoDatensätzen zurückgegeben wird. Um festzustellen, ob sich Ihre Anwendung im Vordergrund befindet, überprüfen Sie, ob die RunningAppProcessInfo.importanceGleichheit mit RunningAppProcessInfo.IMPORTANCE_FOREGROUNDwhile RunningAppProcessInfo.processNameIhrem Anwendungspaketnamen entspricht.
Auch wenn Sie ActivityManager.getRunningAppProcesses()von Ihrem Anwendungs-UI-Thread aus aufrufen , wird die Bedeutung IMPORTANCE_FOREGROUNDfür Ihre Aufgabe zurückgegeben, unabhängig davon, ob sie tatsächlich im Vordergrund steht oder nicht. Rufen Sie es im Hintergrund-Thread auf (zum Beispiel über AsyncTask) und es werden korrekte Ergebnisse zurückgegeben.
Obwohl diese Lösung möglicherweise funktioniert (und tatsächlich die meiste Zeit funktioniert), empfehle ich dringend, sie nicht zu verwenden. Und hier ist warum. Wie Dianne Hackborn schrieb :
Diese APIs sind nicht für Anwendungen gedacht, auf denen der UI-Fluss basiert, sondern um dem Benutzer die ausgeführten Apps oder einen Task-Manager oder dergleichen anzuzeigen.
Ja, für diese Dinge wird eine Liste gespeichert. Es ist jedoch in einem anderen Prozess deaktiviert, der von Threads verwaltet wird, die separat von Ihrem ausgeführt werden, und nicht etwas, auf das Sie zählen können, wenn Sie (a) rechtzeitig die richtige Entscheidung treffen oder (b) bei Ihrer Rückkehr ein konsistentes Bild haben. Außerdem wird die Entscheidung darüber, zu welcher "nächsten" Aktivität Sie gehen möchten, immer an dem Punkt getroffen, an dem der Wechsel stattfinden soll, und erst an genau diesem Punkt (an dem der Aktivitätsstatus für den Wechsel kurz gesperrt wird) treffen wir weiß eigentlich genau, was das nächste sein wird.
Und es ist nicht garantiert, dass die Implementierung und das globale Verhalten in Zukunft gleich bleiben.
Ich wünschte, ich hätte dies gelesen, bevor ich eine Antwort auf die SO gepostet habe, aber hoffentlich ist es nicht zu spät, meinen Fehler zuzugeben.
Eine andere falsche Lösung, die die Droid-Fu- Bibliothek in einer der Antworten ActivityManager.getRunningTasksfür ihre isApplicationBroughtToBackgroundMethode verwendet. Siehe Diannes Kommentar oben und verwende diese Methode auch nicht.
Um zu wissen, ob Sie die Home-Taste gedrückt haben oder eine andere App den Fokus gewonnen hat: 1) Implementieren Sie die gute Lösung . 2) Auf OnStopAnfrage an isActivityVisible.
Brais Gabin
28
Leider funktioniert Ihre "richtige" Lösung bei mir nicht. Stellen Sie sich vor, Sie durchlaufen Aktivitäten in Ihrer App. Was dann passiert, ist, dass Ihr 'inForeground'-Flag folgendermaßen lautet: True, False (zwischen der onPause der ersten Aktivität und dem onResume der 2. Aktivität), dann wieder True usw. Sie würden dann eine Art Hysterese benötigen.
Radu
14
Diese Lösung funktioniert nicht, wenn Sie nicht alle Aktivitäten direkt steuern können. Zum Beispiel, wenn Sie eine Aktivität von einem Drittanbieter-SDK haben oder sogar eine ACTION_VIEW-Absicht starten.
user123321
66
Android ist so ein verdammtes Wrack. Niemand dachte, dass jemand Daten auf App-Ebene beibehalten möchte? Gib mir eine Pause
8
Die eigentliche Antwort auf diese Frage lautet anscheinend "Sie können sie nicht richtig überprüfen". Die sogenannte "richtige" Lösung ist bestenfalls eine Problemumgehung, ebenso wie die Verwendung von ActivityLifecycleCallbacks. Sie müssen noch in Betracht ziehen, zwischen Aktivitäten zu wechseln, die als "nicht im Vordergrund" registriert werden. Es macht mich wahnsinnig, dass Sie so etwas nicht überprüfen können ...
Ich werde meine ursprüngliche Antwort hier der Nachwelt zuliebe hinterlassen. Dies war das beste, das es 2012 gab, aber jetzt hat Android die richtige Unterstützung dafür.
Ursprüngliche Antwort
Der Schlüssel wird verwendet ActivityLifecycleCallbacks(beachten Sie, dass hierfür Android API Level 14 (Android 4.0) erforderlich ist). Überprüfen Sie einfach, ob die Anzahl der gestoppten Aktivitäten der Anzahl der gestarteten Aktivitäten entspricht. Wenn sie gleich sind, wird Ihre Anwendung im Hintergrund ausgeführt. Wenn mehr Aktivitäten gestartet wurden, ist Ihre Anwendung weiterhin sichtbar. Wenn mehr wieder aufgenommene als angehaltene Aktivitäten vorhanden sind, ist Ihre Anwendung nicht nur sichtbar, sondern steht auch im Vordergrund. Es gibt 3 Hauptzustände, in denen sich Ihre Aktivität befinden kann: sichtbar und im Vordergrund, sichtbar, aber nicht im Vordergrund und nicht sichtbar und nicht im Vordergrund (dh im Hintergrund).
Das wirklich Schöne an dieser Methode ist, dass sie nicht die asynchronen Probleme getRunningTasks()hat, aber Sie müssen auch nicht alle Activityin Ihrer Anwendung ändern , um etwas in onResumed()/ zu setzen / zu deaktivieren onPaused(). Es sind nur ein paar Codezeilen, die in sich geschlossen sind und in Ihrer gesamten Anwendung funktionieren. Außerdem sind keine funky Berechtigungen erforderlich.
MyLifecycleHandler.java:
publicclassMyLifecycleHandlerimplementsActivityLifecycleCallbacks{// I use four separate variables here. You can, of course, just use two and// increment/decrement them instead of using four and incrementing them all.privateint resumed;privateint paused;privateint started;privateint stopped;@Overridepublicvoid onActivityCreated(Activity activity,Bundle savedInstanceState){}@Overridepublicvoid onActivityDestroyed(Activity activity){}@Overridepublicvoid onActivityResumed(Activity activity){++resumed;}@Overridepublicvoid onActivityPaused(Activity activity){++paused;
android.util.Log.w("test","application is in foreground: "+(resumed > paused));}@Overridepublicvoid onActivitySaveInstanceState(Activity activity,Bundle outState){}@Overridepublicvoid onActivityStarted(Activity activity){++started;}@Overridepublicvoid onActivityStopped(Activity activity){++stopped;
android.util.Log.w("test","application is visible: "+(started > stopped));}// If you want a static function you can use to check if your application is// foreground/background, you can use the following:/*
// Replace the four variables above with these four
private static int resumed;
private static int paused;
private static int started;
private static int stopped;
// And these two public static functions
public static boolean isApplicationVisible() {
return started > stopped;
}
public static boolean isApplicationInForeground() {
return resumed > paused;
}
*/}
MyApplication.java:
// Don't forget to add it to your manifest by doing// <application android:name="your.package.MyApplication" ...publicclassMyApplicationextendsApplication{@Overridepublicvoid onCreate(){// Simply add the handler, and that's it! No need to add any code// to every activity. Everything is contained in MyLifecycleHandler// with just a few lines of code. Now *that's* nice.
registerActivityLifecycleCallbacks(newMyLifecycleHandler());}}
@Mewzer hat einige gute Fragen zu dieser Methode gestellt, auf die ich in dieser Antwort für alle antworten möchte:
onStop()wird in Situationen mit wenig Speicher nicht aufgerufen; ist das hier ein problem
Nein. Die Dokumente onStop()sagen:
Beachten Sie, dass diese Methode in Situationen mit wenig Arbeitsspeicher, in denen das System nicht über genügend Arbeitsspeicher verfügt, um den Prozess Ihrer Aktivität nach dem Aufruf der Methode onPause () auszuführen, möglicherweise nie aufgerufen wird.
Der Schlüssel hier ist "Halten Sie den Prozess Ihrer Aktivität am Laufen ...". Wenn diese Situation mit wenig Arbeitsspeicher jemals erreicht wird, wird Ihr Prozess tatsächlich beendet (nicht nur Ihre Aktivität). Dies bedeutet, dass diese Methode zur Überprüfung der Hintergründe weiterhin gültig ist, da a) Sie das Mitglied ohnehin nicht auf Hintergründe prüfen können, wenn Ihr Prozess beendet wird, und b) wenn Ihr Prozess erneut gestartet wird (weil eine neue Aktivität erstellt wird), das Mitglied Variablen (ob statisch oder nicht) für MyLifecycleHandlerwerden auf zurückgesetzt 0.
Funktioniert dies bei Konfigurationsänderungen?
Standardmäßig nein. Sie müssen explizit configChanges=orientation|screensize( |mit allem, was Sie wollen) in Ihrer Manifestdatei festlegen und die Konfigurationsänderungen behandeln, sonst wird Ihre Aktivität zerstört und neu erstellt. Wenn Sie dies nicht festlegen, werden die Methoden Ihrer Aktivität in der folgenden Reihenfolge aufgerufen : onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume. Wie Sie sehen können, gibt es keine Überlappung (normalerweise überlappen sich zwei Aktivitäten sehr kurz, wenn zwischen den beiden gewechselt wird. So funktioniert diese Hintergrunderkennungsmethode). Um dies zu umgehen, müssen Sie festlegen configChanges, dass Ihre Aktivität nicht zerstört wird. Zum Glück musste ich einstellenconfigChangesBereits in all meinen Projekten, weil es unerwünscht war, dass meine gesamte Aktivität auf dem Bildschirm zerstört wurde. Drehen / Ändern der Größe, daher habe ich dies nie als problematisch empfunden. (Danke an dpimka für das Auffrischen meines Gedächtnisses und das Korrigieren von mir!)
Eine Note:
Wenn ich hier in dieser Antwort "Hintergrund" gesagt habe, meine ich "Ihre App ist nicht mehr sichtbar". Android-Aktivitäten können sichtbar sein, jedoch nicht im Vordergrund (z. B. wenn eine transparente Benachrichtigungsüberlagerung vorhanden ist). Deshalb habe ich diese Antwort aktualisiert, um dies widerzuspiegeln.
Es ist wichtig zu wissen, dass Android beim Wechseln von Aktivitäten, bei denen nichts im Vordergrund steht, einen seltsamen Moment in der Schwebe hat . Wenn Sie beim Wechseln zwischen Aktivitäten (in derselben App) überprüfen, ob sich Ihre Anwendung im Vordergrund befindet, wird Ihnen aus diesem Grund mitgeteilt, dass Sie nicht im Vordergrund stehen (obwohl Ihre App immer noch die aktive App ist und sichtbar ist ).
Sie können überprüfen , ob Ihre App im Vordergrund in Ihrem sind Activity‚s onPause()Methode nachsuper.onPause() . Denken Sie nur an den seltsamen Schwebezustand, über den ich gerade gesprochen habe.
Sie können überprüfen , ob Ihre App sichtbar sind (dh , wenn es nicht im Hintergrund ist) in Ihrem Activity‚s onStop()Methode nachsuper.onStop() .
Das sieht interessant aus - aber was passiert in Situationen mit wenig Speicher? Es kann nicht garantiert werden, dass onStop () aufgerufen wird. Könnten wir jemals in die Situation geraten, dass ein onStop () nicht aufgerufen wird und der gestoppte Zähler nicht inkrementiert wird - dies bedeutet, dass die Hintergrundprüfung nicht mehr zuverlässig ist? Oder würde das niemals passieren?
Mewzer
1
Ignoriert dies auch Konfigurationsänderungen? Oder wird die Anwendung als Hintergrund betrachtet, wenn eine Aktivität aufgrund einer Konfigurationsänderung (z. B. Änderung der Ausrichtung) neu erstellt wird? Entschuldigung für die Fragen, aber ich denke, Sie sind auf etwas und sind daran interessiert zu wissen, ob es in diesen Randfällen funktioniert.
Mewzer
1
@Mewzer: Ich wollte als Kommentar antworten, aber es wird ein bisschen Tippen erfordern, um diese Antworten zu erhalten. Schauen Sie also in ein paar Minuten noch einmal vorbei und ich werde meine Antwort bearbeiten.
Cornstalks
1
@Mewzer: Du solltest jetzt deine Antworten finden. Lassen Sie mich wissen, wenn Sie weitere Fragen haben!
Cornstalks
2
@Mewzer: Ich habe eine Notiz nur hinzugefügt , dass Sie von Interesse sein könnten Insbesondere prüfen in Hintergrund versetzen . onStop()Nach super.onStop(). Überprüfen Sie nicht, ob Hintergrundinformationen vorhanden sind onPause().
Cornstalks
186
GOOGLE-LÖSUNG - kein Hack wie bei früheren Lösungen. Verwenden Sie ProcessLifecycleOwner
Kotlin:
classArchLifecycleApp:Application(),LifecycleObserver{override fun onCreate(){super.onCreate()ProcessLifecycleOwner.get().lifecycle.addObserver(this)}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onAppBackgrounded(){//App in background}@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onAppForegrounded(){// App in foreground}}
Java:
publicclassArchLifecycleAppextendsApplicationimplementsLifecycleObserver{@Overridepublicvoid onCreate(){super.onCreate();ProcessLifecycleOwner.get().getLifecycle().addObserver(this);}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)publicvoid onAppBackgrounded(){//App in background}@OnLifecycleEvent(Lifecycle.Event.ON_START)publicvoid onAppForegrounded(){// App in foreground}}
in app.gradle
dependencies {...
implementation "android.arch.lifecycle:extensions:1.1.0"//New Android X dependency is this -
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"}
allprojects {
repositories {...
google()
jcenter()
maven { url 'https://maven.google.com'}}}
Dies sollte definitiv die richtige Antwort sein! Es funktionierte wie ein Zauber: D
JaviOverflow
2
Dies funktioniert perfekt, ich habe auch ein wenig geändert, damit ich außerhalb dieser Klasse leichter auf den Vordergrund- / Hintergrundstatus zugreifen companion object { private var foreground = false fun isForeground() : Boolean { return foreground } }kann : Dann können Sie den Vordergrundstatus mitArchLifecycleApp.isForeground()
Jose Jet
2
Oh Mann, das ist so viel besser als meine alte Antwort. Habe eine +1 von mir. Ich habe meine Antwort aktualisiert, um Personen auf Ihre zu verweisen.
Cornstalks
2
Obwohl dies eine richtige Antwort ist, müssen keine Rückrufe implementiert werden. Sie können ProcessLifecycleOwner einfach abfragen, wann immer Sie möchten. Überprüfen Sie stackoverflow.com/a/52678290/6600000
Keivan Esbati
2
Wie doc sagt The LifecycleOwner for the whole application process. Note that if your application has multiple processes, this provider does not know about other processes. , funktioniert dies nicht für multiple processesApps. Gibt es eine API, die wir elegant erreichen können?
acntwww
23
Wenn Sie die Support-Bibliothek Version 26 starten , können Sie ProcessLifecycleOwner verwenden. Fügen Sie es einfach wie hier beschrieben zu Ihrer Abhängigkeit hinzu , zum Beispiel:
dependencies {def lifecycle_version ="1.1.1"// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:$lifecycle_version"// alternatively - Lifecycles only (no ViewModel or LiveData).// Support library depends on this lightweight import
implementation "android.arch.lifecycle:runtime:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version"// use kapt for Kotlin}
Und ProcessLifecycleOwnerfragen Sie dann einfach ab, wann immer Sie den App-Status wünschen. Beispiele:
//Check if app is in backgroundProcessLifecycleOwner.get().getLifecycle().getCurrentState()==Lifecycle.State.CREATED;//Check if app is in foregroundProcessLifecycleOwner.get().getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED);
Danke Mann, dies ist der beste und einfachste Weg, der in jedem Teil Ihres Codes geeignet ist, insbesondere wenn Sie fcm verwenden.
Mihae Kheel
Wenn die Anwendung vollständig geschlossen ist, was würde die erste Methode zurückgeben?
Evgeniy Mishustin
@EvgeniyMishustin, das vom aktuellen Status der Anwendung abhängt, aber normalerweise wird CREATED und DESTROYED angezeigt, und danach werden keine neuen Ereignisse mehr angezeigt.
Keivan Esbati
Wo ist also eine "IF" -Anweisung, um zu sehen, ob sich die IF-App im Hintergrund befindet?
Ekashking
@ekashking fügt einfach die gesamte Anweisung in die if-Klausel ein. Zum Beispiel: if (ProcessLifecycleOwner.get (). GetLifecycle (). GetCurrentState (). IsAtLeast (Lifecycle.State.STARTED)) => App steht im Vordergrund
Keivan Esbati
20
Seit Android API 16 gibt es eine einfache Möglichkeit zu überprüfen, ob die App im Vordergrund steht. Es ist vielleicht nicht kinderleicht, aber keine Methoden unter Android sind kinderleicht. Diese Methode ist gut genug, um verwendet zu werden, wenn Ihr Dienst ein Update vom Server erhält und entscheiden muss, ob eine Benachrichtigung angezeigt werden soll oder nicht (denn wenn die Benutzeroberfläche im Vordergrund steht, wird der Benutzer das Update ohne Benachrichtigung bemerken).
Sollte sich dieser Code innerhalb der Serviceklasse oder einer anderen Klasse befinden, z. B. der Anwendungsklasse? Vielen Dank.
Woppi
..wenn Sie es als letzte Zeile verwenden möchten, ist dies nur ein Boolescher Wert, gegen den Sie prüfen würden.
AO_
Dies ist die gleiche Methode wie das AWS Android SDK für Push-Benachrichtigungen.
Spakmad
Beachten Sie Folgendes: "Die Definition des Hintergrunds für Zwecke von Dienstbeschränkungen unterscheidet sich von der Definition, die von der Speicherverwaltung verwendet wird. Eine App befindet sich möglicherweise im Hintergrund, was die Speicherverwaltung betrifft, steht jedoch im Vordergrund, was die Fähigkeit zum Starten von Diensten betrifft.) " developer.android.com/about/versions/oreo/background.html (
ARLabs
Danke, das hat funktioniert! Ich konnte diesen Code in einem verwenden , JobServicezu erkennen , dass der Dienst im Hintergrund ausgeführt wird .
Idolon's answer is error prone- Leider muss ich dir zustimmen. Basierend auf dem Kommentar von Dianne Hackborn in den Google Groups habe ich meine Antwort aktualisiert. Überprüfen Sie es bitte für die Details.
Idolon
2
Dies ist auch keine narrensichere Lösung. Ein Szenario ist , wenn der Benutzer nach unten gezogen , das Benachrichtigungsfeld, dann weder das onPause, onStopnoch das onResumeEreignis aufgerufen wird. Was machen Sie dann, wenn keines dieser Ereignisse ausgelöst wird?!
Leider, aber dieser Code funktioniert falsch, wenn eine Aktivität gestartet wird, wenn ein Bildschirm ausgeschaltet ist. In diesem Fall werden onResume und onPause aufgerufen, isVisible = false zu machen.
CoolMind
@CoolMind Können Sie bitte erklären, in welchem Anwendungsfall Sie eine Aktivität im Hintergrund starten würden?
Neteinstein
11
Ich habe die empfohlene Lösung ausprobiert, die Application.ActivityLifecycleCallbacks und viele andere verwendet, aber sie funktionierten nicht wie erwartet. Dank Sarge habe ich eine ziemlich einfache und unkomplizierte Lösung gefunden, die ich unten beschreibe.
Der Schlüssel der Lösung ist die Tatsache, dass wenn wir ActivityA und ActivityB haben und ActivityB von ActivityA aus aufrufen (und nicht aufrufen ActivityA.finish), ActivityB vor ActivityA onStart()aufgerufen wird .onStop()
Das ist auch der Hauptunterschied zwischen onStop()und dem onPause(), den keiner in den Artikeln erwähnt hat, die ich gelesen habe.
Basierend auf dem Lebenszyklusverhalten dieser Aktivität können Sie einfach zählen, wie oft onStart()und onPause()in welchem Programm Sie aufgerufen wurden. Beachten Sie, dass Sie für jedesActivity Programm die zum Zählen verwendete statische Variable überschreiben onStart()und onStop()dekrementieren müssen. Unten finden Sie den Code, der diese Logik implementiert. Beachten Sie, dass ich eine Klasse verwende, die erweitert Applicationwird. Vergessen Sie also nicht, Manifest.xmlinnerhalb des Application-Tags zu deklarieren : android:name=".Utilities"obwohl dies auch mit einer einfachen benutzerdefinierten Klasse implementiert werden kann.
publicclassUtilitiesextendsApplication{privatestaticint stateCounter;publicvoid onCreate(){super.onCreate();
stateCounter =0;}/**
* @return true if application is on background
* */publicstaticboolean isApplicationOnBackground(){return stateCounter ==0;}//to be called on each Activity onStart()publicstaticvoid activityStarted(){
stateCounter++;}//to be called on each Activity onStop()publicstaticvoid activityStopped(){
stateCounter--;}}
Jetzt auf jeder Aktivität unseres Programms, sollten wir außer Kraft setzen onStart()und onStop()und Erhöhen / Verringern wie unten dargestellt:
@Overridepublicvoid onStart(){super.onStart();Utilities.activityStarted();}@Overridepublicvoid onStop(){Utilities.activityStopped();if(Utilities.isApplicationOnBackground()){//you should want to check here if your application is on background}super.onStop();}
Mit dieser Logik gibt es zwei mögliche Fälle:
stateCounter = 0 : Die Anzahl der gestoppten Aktivitäten entspricht der Anzahl der gestarteten Aktivitäten. Dies bedeutet, dass die Anwendung im Hintergrund ausgeführt wird.
stateCounter > 0 : Die Anzahl der gestarteten Anwendungen ist größer als die Anzahl der gestoppten Anwendungen. Dies bedeutet, dass die Anwendung im Vordergrund ausgeführt wird.
Hinweis: Dies stateCounter < 0würde bedeuten, dass mehr Aktivitäten gestoppt als gestartet werden, was unmöglich ist. Wenn Sie auf diesen Fall stoßen, bedeutet dies, dass Sie den Zähler nicht wie gewünscht erhöhen / verringern.
Sie sind bereit zu gehen. Sie sollten überprüfen wollen, ob sich Ihre Anwendung im Hintergrund befindet onStop().
Ich würde bewegen if(Utilities.isApplicationOnBackground()) …zu Utilities. Denn sonst reagiert nur eine bestimmte Aktivität auf das Ereignis.
Anzeigename
10
Es gibt keine Möglichkeit, ohne dass Sie es selbst verfolgen, festzustellen, ob eine Ihrer Aktivitäten sichtbar ist oder nicht. Vielleicht sollten Sie eine neue StackOverflow-Frage stellen und erklären, was Sie mit einer Benutzererfahrung erreichen möchten, damit wir Ihnen möglicherweise alternative Implementierungsideen geben können.
In Android haben wir eine Einstellung namens "Hintergrunddaten". Diese Einstellung deaktiviert jede Hintergrunddatenverbindung, wenn die Anwendung im Hintergrund ausgeführt wird. Ich möchte das Umschalten "Hintergrunddaten" für meine Anwendung implementieren. Wenn also keine meiner Aktivitäten für den Benutzer sichtbar ist, möchte ich, dass mein Dienst die Datenübertragung beendet, aber sobald eine meiner Aktivitäten wieder aufgenommen wird, möchte ich dies tun Datenübertragung fortsetzen
cppdev
1
@cppdev: Hoffentlich wird die "Datenübertragung" von a durchgeführt Service. Wenn ja, lassen Sie Ihre Aktivitäten den Dienst benachrichtigen, sobald sie angezeigt werden und verschwinden. Wenn das Servicefeststellt, dass keine Aktivitäten sichtbar sind und dies für einige Zeit so bleibt, stoppen Sie die Datenübertragung am nächsten logischen Stopppunkt. Ja, dies erfordert Code für jede Ihrer Aktivitäten, aber im Moment ist dies unvermeidlich, AFAIK.
CommonsWare
1
Wenn Sie vermeiden möchten, den gemeinsamen Code aller Ihrer Aktivitäten zu kopieren und einzufügen, können Sie eine Klasse erstellen, MyActivityClassdie von Activityden Lebenszyklusmethoden erbt und diese implementiert, und alle Ihre Aktivitäten erben lassen MyActivityClass. Dies wird nicht funktionieren für PreferenceActivityoder MapActivityobwohl (siehe diese Frage )
Guillaume Brunerie
@ CommonsWare Ich hatte mit OnPause () OnResume () versucht, dass es aktiv ist oder nicht, aber wenn meine App nicht im Ansichtsbildschirm angezeigt wird, wenn sie im Hintergrund ausgeführt wird, wie überprüfen Sie, ob sie aktiv ist oder nicht
Manoj
@ CommonsWare Ich hatte mit OnPause () OnResume () versucht, dass es aktiv ist oder nicht, aber wenn meine App nicht im Ansichtsbildschirm angezeigt wird, wenn sie im Hintergrund ausgeführt wird, wie überprüfen Sie, ob sie aktiv ist oder nicht
Manoj
5
Mit ComponentCallbacks2 können Sie feststellen, ob sich die App im Hintergrund befindet. Übrigens ist dieser Rückruf nur in API Level 14 (Ice Cream Sandwich) und höher verfügbar .
Sie erhalten einen Aufruf der Methode:
public abstract void onTrimMemory (int level)
Wenn das Level ist, befindet sich ComponentCallbacks2.TRIM_MEMORY_UI_HIDDENdie App im Hintergrund.
Sie können diese Schnittstelle zu einem Gerät activity, serviceusw.
publicclassMainActivityextendsAppCompatActivityimplementsComponentCallbacks2{@Overridepublicvoid onConfigurationChanged(finalConfiguration newConfig){}@Overridepublicvoid onLowMemory(){}@Overridepublicvoid onTrimMemory(finalint level){if(level ==ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){// app is in background}}}
Habe deine Antwort ausprobiert, ist aber nicht so zuverlässig. Der onTrimMemory-Rückruf wird weder beim Sperren des Bildschirms noch beim Drücken der Ein- / Aus-Taste zum Sperren des Bildschirms ausgelöst. TRIM_MEMORY_UI_HIDDEN wird nicht immer zurückgegeben, wenn Ihre App sichtbar ist und Sie eine andere App über eine Statusleistenbenachrichtigung öffnen. Die einzig zuverlässige Lösung besteht darin, die ActivityLifecycleCallbacks zu implementieren und an den jeweiligen Anwendungsfall anzupassen.
Velval
4
Aufbauend auf der Antwort von @Cornstalks mit einigen nützlichen Funktionen.
Zusätzliche Funktionen:
Das Singleton-Muster wurde eingeführt, sodass Sie dies überall in der Anwendung tun können: AppLifecycleHandler.isApplicationVisible () und AppLifecycleHandler.isApplicationInForeground ()
Behandlung von doppelten Ereignissen hinzugefügt (siehe Kommentare // Maßnahmen zur Änderung der Sichtbarkeit ergreifen und // Maßnahmen zur Änderung des Vordergrunds ergreifen)
Die beste Lösung, die ich mir ausgedacht habe, verwendet Timer.
Sie haben einen Timer in onPause () gestartet und denselben Timer in onResume () abgebrochen. Es gibt 1 Instanz des Timers (normalerweise in der Application-Klasse definiert). Der Timer selbst ist so eingestellt, dass nach 2 Sekunden (oder einem beliebigen Intervall, das Sie für angemessen halten) ein Runnable ausgeführt wird. Wenn der Timer ausgelöst wird, setzen Sie ein Flag, das die Anwendung als im Hintergrund markiert.
In der onResume () -Methode können Sie vor dem Abbrechen des Timers das Hintergrundflag abfragen, um Startvorgänge auszuführen (z. B. Downloads starten oder Standortdienste aktivieren).
Mit dieser Lösung können Sie mehrere Aktivitäten auf dem Backstack ausführen und benötigen keine Implementierungsberechtigungen.
Diese Lösung funktioniert gut, wenn Sie auch einen Ereignisbus verwenden, da Ihr Timer einfach ein Ereignis auslösen kann und verschiedene Teile Ihrer App entsprechend reagieren können.
Ich fange an zu denken, dass dies die beste (wenn auch unglückliche) Lösung ist
dhaag23
Ja, das ist die beste Lösung, die ich auch geschafft habe. Ich musste das Bluetooth-Scannen stoppen, wenn die App nicht im Vordergrund stand, konnte aber nicht einfach die Pause verwenden oder anhalten oder zerstören, da ich nicht ständig anhalten und starten wollte, wenn der Benutzer durch die App navigierte.
CaptRespect
3
Wenn Sie die Entwicklereinstellungen "Aktivitäten nicht beibehalten" aktivieren, ist es nicht ausreichend, nur die Anzahl der erstellten Aktivitäten zu überprüfen. Sie müssen auch isSaveInstanceState überprüfen . Meine benutzerdefinierte Methode isApplicationRunning () prüft, ob die Android-App ausgeführt wird:
Ich sehe nicht ein, wie diese Lösung mir möglicherweise eine Antwort auf eine einfache Frage innerhalb einer IF-Anweisung zu meiner Aktivität (oder meinem Fragment) geben kann, ob sich meine App im Hintergrund oder im Vordergrund befindet. Wo ist die "IF" -Anweisung ???
Ekashking
2
Um auf die Aussagen von CommonsWare und Key zurückzugreifen, können Sie möglicherweise die Application-Klasse erweitern und alle Ihre Aktivitäten dies für ihre onPause / onResume-Methoden aufrufen lassen. Auf diese Weise können Sie feststellen, welche Aktivitäten sichtbar sind, dies könnte jedoch wahrscheinlich besser gehandhabt werden.
Können Sie genau erläutern, was Sie vorhaben? Wenn Sie sagen, dass Sie im Hintergrund laufen, meinen Sie damit, dass Ihre Anwendung immer noch im Speicher ist, obwohl sie derzeit nicht auf dem Bildschirm angezeigt wird? Haben Sie darüber nachgedacht, Services als dauerhaftere Methode zur Verwaltung Ihrer App zu verwenden, wenn diese nicht im Fokus steht?
In Android haben wir eine Einstellung namens "Hintergrunddaten". Diese Einstellung deaktiviert jede Hintergrunddatenverbindung, wenn die Anwendung im Hintergrund ausgeführt wird. Ich möchte das Umschalten "Hintergrunddaten" für meine Anwendung implementieren. Wenn also keine meiner Aktivitäten für den Benutzer sichtbar ist, möchte ich, dass mein Dienst die Datenübertragung beendet, aber sobald eine meiner Aktivitäten wieder aufgenommen wird, möchte ich dies tun Wiederaufnahme der Datenübertragung
cppdev
1
Applicationhat nicht onPause()oder onResume().
CommonsWare
1
@CommonsWare Sie haben Recht, ich bezog mich auf jede einzelne Aktivität, die die Anwendung in ihrer Pause / ihrem Lebenslauf kontaktierte. Dies ist im Grunde die Idee, die Sie gerade in dem Kommentar zu Ihrer Antwort geteilt haben, obwohl Sie Dienste verwendet haben, die ich für einen intelligenteren Schritt halte.
Dan
2
Ich habe ActivityLifecycleCallbacks selbst implementiert. Ich verwende SherlockActivity, aber für normale Aktivitäten könnte die Klasse funktionieren.
Zunächst erstelle ich eine Schnittstelle, die alle Methoden zum Verfolgen des Aktivitätslebenszyklus enthält:
Die Aktivität wird angehalten, wenn ein Dialog darüber angezeigt wird, sodass alle empfohlenen Lösungen Halblösungen sind. Sie müssen auch Hooks für Dialoge erstellen.
Das System unterscheidet zwischen Vordergrund- und Hintergrund-Apps. (Die Definition des Hintergrunds für Zwecke von Dienstbeschränkungen unterscheidet sich von der Definition, die von der Speicherverwaltung verwendet wird. Eine App befindet sich möglicherweise im Hintergrund , was die Speicherverwaltung betrifft , steht jedoch im Vordergrund, was die Fähigkeit zum Starten von Diensten betrifft.) Eine App ist gilt als im Vordergrund, wenn eine der folgenden Aussagen zutrifft:
Es hat eine sichtbare Aktivität, unabhängig davon, ob die Aktivität gestartet oder angehalten wurde.
Es hat einen Vordergrunddienst.
Eine andere Vordergrund-App ist mit der App verbunden, indem sie entweder an einen ihrer Dienste gebunden wird oder einen ihrer Inhaltsanbieter nutzt. Zum Beispiel steht die App im Vordergrund, wenn eine andere App an Folgendes bindet:
IME
Tapetenservice
Benachrichtigungs-Listener
Sprach- oder Textdienst
Wenn keine dieser Bedingungen erfüllt ist, wird die App als im Hintergrund betrachtet.
Sie sollten eine gemeinsame Einstellung verwenden, um die Eigenschaft zu speichern und mithilfe der Servicebindung aus Ihren Aktivitäten darauf zu reagieren. Wenn Sie nur die Bindung verwenden (dh niemals startService verwenden), wird Ihr Dienst nur ausgeführt, wenn Sie an ihn binden (onResume binden und onPause aufheben), sodass er nur im Vordergrund ausgeführt wird und wenn Sie daran arbeiten möchten Hintergrund können Sie den regulären Start-Stopp-Dienst verwenden.
Ich denke, diese Frage sollte klarer sein. Wann? Wo? Was ist Ihre spezifische Situation, die Sie kennenlernen möchten, wenn sich Ihre App im Hintergrund befindet?
Ich stelle meine Lösung nur auf meine Weise vor.
Ich erreiche dies, indem ich das Feld "Wichtigkeit" der RunningAppProcessInfoKlasse in der onStopMethode jeder Aktivität in meiner App verwende. Dies kann einfach erreicht werden, indem BaseActivityfür andere Aktivitäten eine Erweiterung bereitgestellt wird , die die onStopMethode implementiert , um den Wert von "Wichtigkeit" zu überprüfen. Hier ist der Code:
Ich habe ungefähr 10 Aktivitäten in meiner Bewerbung. Ich möchte also wissen, ob keiner von ihnen für den Benutzer sichtbar ist. Insgesamt möchte ich wissen, ob meine Anwendung als Ganzes im Hintergrund ausgeführt wird
cppdev
Dann behalten Sie alle 10-ish im Auge. Oder erklären Sie, wie CommonsWare vorgeschlagen hat, was Sie versuchen.
Schlüssel
3
Das ist nicht richtig. Ihre Aktivität ist sichtbar bis onStop; dazwischen onPauseund onStopes ist sichtbar , aber nicht im Vordergrund .
Nickgrim
@nickgrim: was ist nicht richtig? Ich habe angegeben, dass eine Aktivität nach dem onStop()Aufruf nicht mehr sichtbar ist, was mit dem übereinstimmt, was Sie geschrieben haben.
Schlüssel
@Key: Du hast ursprünglich gesagt, bis onPauseaufgerufen wird: Eine kürzlich vorgenommene Bearbeitung hat dich korrigiert.
Nickgrim
0
Was ist mit getApplicationState (). IsInForeground ()?
Sie wissen, dass die von Ihnen gesendeten Daten Ihre App nicht verlassen. Sie müssen sich also keine Sorgen machen, dass private Daten verloren gehen.
Andere Anwendungen können diese Broadcasts nicht an Ihre App senden, sodass Sie sich keine Sorgen über Sicherheitslücken machen müssen, die sie ausnutzen können.
Es ist effizienter als das Senden einer globalen Sendung über das System.
Nicht in den Dokumenten:
Es sind keine externen Bibliotheken erforderlich
Der Code ist minimal
Es ist schnell zu implementieren und zu verstehen
Keine benutzerdefinierten selbst implementierten Rückrufe / Ultra-Singleton / Intra-Prozess-Muster ...
Keine starken Referenzen auf Activity, Application...
Beschreibung
Sie möchten also überprüfen, ob sich eines der ActivityElemente derzeit im Vordergrund befindet. Das machst du normalerweise in einer Serviceoder deiner ApplicationKlasse.
Dies bedeutet, dass Ihre ActivityObjekte zum Absender eines Signals werden (ich bin an / ich bin aus). Ihr Servicehingegen wird zum Receiver.
Es gibt zwei Momente, in denen IhreActivity erfahren, ob es im Vordergrund oder im Hintergrund läuft (ja, nur zwei ... nicht 6).
Wenn das Activityin den Vordergrund tritt, wird die onResume()Methode ausgelöst (auch nach aufgerufen)onCreate() ).
Wenn das Activityin den Rücken geht,onPause() wird gerufen.
Dies sind die Momente, in denen Sie Activitydas Signal an Ihre senden solltenService um seinen Zustand zu beschreiben.
Denken Sie bei mehreren Activityan die anActivity in den Hintergrund tritt und dann ein anderes in den Vordergrund tritt.
Das Service/ Applicationhört einfach weiter auf diese Signale und handelt entsprechend.
Code (TLDR)
Sie Servicemüssen ein implementieren BroadcastReceiver, um auf Signale zu warten.
this.localBroadcastReceiver =newBroadcastReceiver(){@Overridepublicvoid onReceive(Context context,Intent intent){// received data if Activity is on / off}}publicstaticfinalIntentFilter SIGNAL_FILTER =newIntentFilter("com.you.yourapp.MY_SIGNAL")
Registrieren Sie die ReceiverinService::onCreate()
Heben Sie die Registrierung auf Service::onDestroy()
@Overrideprotectedvoid onDestroy(){// I'm dead, no need to listen to anything anymore.LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(this.localBroadcastReceiver);}
Jetzt Activitymüssen Sie ihren Zustand mitteilen.
Im Activity::onResume()
Intent intent =newIntent();
intent.setAction(SomeActivity.SIGNAL_FILTER);// put ON boolean in intent LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
Im Activity::onPause()
Intent intent =newIntent();
intent.setAction(SomeActivity.SIGNAL_FILTER);// put OFF boolean in intent LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
Eine sehr, sehr häufige Situation
Entwickler: Ich möchte Daten von meinem senden Serviceund das aktualisieren Activity. Wie überprüfe ich, ob das Activityim Vordergrund steht?
In der Regel muss nicht überprüft werden, ob sich das Activityim Vordergrund befindet oder nicht. Senden Sie einfach die Daten über LocalBroadcastManagervon Ihrem Service. Wenn das eingeschaltet Activityist, reagiert es und handelt.
Für diese sehr häufige Situation wird der Servicezum Absender und der Activityimplementiert den BroadcastReceiver.
Erstellen Sie also eine Receiverin Ihrem Activity. Registrieren Sie es in onResume()und heben Sie die Registrierung auf onPause(). Es ist nicht erforderlich, die anderen Lebenszyklusmethoden zu verwenden .
Definieren Sie das ReceiverVerhalten in onReceive()(ListView aktualisieren, dies tun, das tun, ...).
Auf diese Weise Activityhört der Wille nur zu, wenn er im Vordergrund ist und nichts passiert, wenn er im Hintergrund ist oder zerstört wird.
Im Falle von mehreren Activitywird jeder, der eingeschaltet Activityist, antworten (wenn sie auch das implementieren Receiver).
Wenn sich alle im Hintergrund befinden, reagiert niemand und das Signal geht einfach verloren.
Senden Sie die Daten von der ServiceVia Intent(siehe Code oben), indem Sie die Signal-ID angeben.
Mit Ausnahme der Unterstützung für mehrere Fenster . Es kann schwierig sein (bitte testen Sie es bei Bedarf) ...
fun isAppInForeground():Boolean{
val activityManager = getSystemService(Context.ACTIVITY_SERVICE)asActivityManager?:returnfalse
val appProcesses = activityManager.runningAppProcesses ?:returnfalse
val packageName = packageName
for(appProcess in appProcesses){if(appProcess.importance ==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName == packageName){returntrue}}returnfalse}
Keine der Antworten passte ganz zum speziellen Fall, wenn Sie wissen möchten, ob sich eine bestimmte Aktivität im Vordergrund befindet und wenn Sie ein SDK ohne direkten Zugriff auf die Anwendung sind. Für mich war ich im Hintergrund-Thread, habe gerade eine Push-Benachrichtigung für eine neue Chat-Nachricht erhalten und möchte nur dann eine Systembenachrichtigung anzeigen, wenn der Chat-Bildschirm nicht im Vordergrund steht.
Mit dem ActivityLifecycleCallbacks, wie in anderen Antworten empfohlen, habe ich eine kleine util-Klasse erstellt, die die Logik enthält, ob MyActivityim Vordergrund steht oder nicht.
classMyActivityMonitor(context:Context):Application.ActivityLifecycleCallbacks{privatevar isMyActivityInForeground =false
init {(context.applicationContext asApplication).registerActivityLifecycleCallbacks(this)}
fun isMyActivityForeground()= isMyActivityInForeground
override fun onActivityPaused(activity:Activity?){if(activity isMyActivity){
isMyActivityInForeground =false}}override fun onActivityResumed(activity:Activity?){if(activity isMyActivity){
isMyActivityInForeground =true}}
// Show a Toast Notification if App is not visible (ie in background. Not running, etc) SharedPreferences sharedPrefs =PreferenceManager.getDefaultSharedPreferences(context);if(!sharedPrefs.getBoolean("visible",true)){...}
Vielleicht nicht elegant, aber es funktioniert bei mir ...
Es mag zu spät sein, um zu antworten, aber wenn jemand zu Besuch kommt, dann ist hier die Lösung, die ich vorschlage: Der Grund, warum eine App wissen möchte, dass sie sich im Hintergrund befindet oder in den Vordergrund tritt, kann viele sein, einige sind, 1. Anzeigen von Toasts und Benachrichtigungen, wenn sich der Benutzer in BG befindet. 2.Um einige Aufgaben zum ersten Mal auszuführen, wenn der Benutzer von BG kommt, z. B. eine Umfrage, ein Neuzeichnen usw.
Die Lösung von Idolon und anderen kümmert sich um den ersten Teil, nicht jedoch um den zweiten. Wenn Ihre App mehrere Aktivitäten enthält und der Benutzer zwischen ihnen wechselt, ist das sichtbare Flag zu dem Zeitpunkt, an dem Sie sich in der zweiten Aktivität befinden, falsch. Es kann also nicht deterministisch verwendet werden.
Ich habe etwas getan, was von CommonsWare vorgeschlagen wurde: "Wenn der Dienst feststellt, dass keine Aktivitäten sichtbar sind und dies für einige Zeit so bleibt , stoppen Sie die Datenübertragung am nächsten logischen Stopppunkt."
Die fettgedruckte Zeile ist wichtig und kann verwendet werden, um einen zweiten Punkt zu erzielen. Wenn ich also onActivityPaused () erhalte, ändere ich das sichtbare nicht direkt in false, sondern habe einen Timer von 3 Sekunden (das ist das Maximum, mit dem die nächste Aktivität gestartet werden sollte) und wenn es nicht onActivityResumed gibt ( ) in den nächsten 3 Sekunden aufrufen, sichtbar in false ändern. Ähnlich wie bei onActivityResumed (), wenn es einen Timer gibt, brich ich ihn ab. Zusammenfassend wird das Sichtbare zu isAppInBackground.
Der Code kann leider nicht kopiert und eingefügt werden ...
Ich möchte Ihnen empfehlen, dies auf eine andere Weise zu tun.
Ich denke, Sie möchten den Startbildschirm anzeigen, während das Programm gestartet wird. Wenn es bereits im Backend ausgeführt wird, zeigen Sie es nicht an.
Ihre Anwendung kann kontinuierlich die aktuelle Zeit in eine bestimmte Datei schreiben. Überprüfen Sie beim Starten Ihrer Anwendung den letzten Zeitstempel. Wenn current_time-last_time> der Zeitbereich ist, den Sie zum Schreiben der letzten Zeit angegeben haben, bedeutet dies, dass Ihre Anwendung gestoppt wird, entweder vom System oder vom Benutzer selbst beendet.
Antworten:
Es gibt nur wenige Möglichkeiten, um festzustellen, ob Ihre Anwendung im Hintergrund ausgeführt wird, aber nur eine davon ist absolut zuverlässig:
Die richtige Lösung (Kredite gehen zu Dan , CommonsWare und NeTeInStEiN )
verfolgen Sichtbarkeit Ihrer Anwendung selbst verwendet
Activity.onPause
,Activity.onResume
Methoden. Speichern Sie den Status "Sichtbarkeit" in einer anderen Klasse. Gute Entscheidungen sind Ihre eigene Implementierung vonApplication
oder aService
(es gibt auch einige Variationen dieser Lösung, wenn Sie die Aktivitätssichtbarkeit des Dienstes überprüfen möchten).Beispiel
Implementieren Sie eine benutzerdefinierte
Application
Klasse (beachten Sie dieisActivityVisible()
statische Methode):Registrieren Sie Ihre Bewerbungsklasse in
AndroidManifest.xml
:Fügen Sie
onPause
undonResume
zu jedemActivity
im Projekt hinzu (Sie können einen gemeinsamen Vorfahren für Ihre Aktivitäten erstellen, wenn Sie möchten, aber wenn Ihre Aktivität bereits vonMapActivity
/ListActivity
usw. erweitert wurde, müssen Sie immer noch Folgendes von Hand schreiben):Update
ActivityLifecycleCallbacks wurden in API Level 14 (Android 4.0) hinzugefügt. Sie können sie verwenden, um zu verfolgen, ob eine Aktivität Ihrer Anwendung derzeit für den Benutzer sichtbar ist. Überprüfen Sie die Antwort von Cornstalks unten für die Details.
Die falsche habe
ich verwendet, um die folgende Lösung vorzuschlagen:
Obwohl diese Lösung möglicherweise funktioniert (und tatsächlich die meiste Zeit funktioniert), empfehle ich dringend, sie nicht zu verwenden. Und hier ist warum. Wie Dianne Hackborn schrieb :
Ich wünschte, ich hätte dies gelesen, bevor ich eine Antwort auf die SO gepostet habe, aber hoffentlich ist es nicht zu spät, meinen Fehler zuzugeben.
Eine andere falsche Lösung, die die
Droid-Fu- Bibliothek in einer der Antworten
ActivityManager.getRunningTasks
für ihreisApplicationBroughtToBackground
Methode verwendet. Siehe Diannes Kommentar oben und verwende diese Methode auch nicht.quelle
OnStop
Anfrage anisActivityVisible
.VERWENDEN SIE DIESE ANTWORT NICHT
Die Antwort von user1269737 ist der richtige (von Google / Android genehmigte) Weg, dies zu tun . Lies ihre Antwort und gib ihnen eine +1.
Ich werde meine ursprüngliche Antwort hier der Nachwelt zuliebe hinterlassen. Dies war das beste, das es 2012 gab, aber jetzt hat Android die richtige Unterstützung dafür.
Ursprüngliche Antwort
Der Schlüssel wird verwendet
ActivityLifecycleCallbacks
(beachten Sie, dass hierfür Android API Level 14 (Android 4.0) erforderlich ist). Überprüfen Sie einfach, ob die Anzahl der gestoppten Aktivitäten der Anzahl der gestarteten Aktivitäten entspricht. Wenn sie gleich sind, wird Ihre Anwendung im Hintergrund ausgeführt. Wenn mehr Aktivitäten gestartet wurden, ist Ihre Anwendung weiterhin sichtbar. Wenn mehr wieder aufgenommene als angehaltene Aktivitäten vorhanden sind, ist Ihre Anwendung nicht nur sichtbar, sondern steht auch im Vordergrund. Es gibt 3 Hauptzustände, in denen sich Ihre Aktivität befinden kann: sichtbar und im Vordergrund, sichtbar, aber nicht im Vordergrund und nicht sichtbar und nicht im Vordergrund (dh im Hintergrund).Das wirklich Schöne an dieser Methode ist, dass sie nicht die asynchronen Probleme
getRunningTasks()
hat, aber Sie müssen auch nicht alleActivity
in Ihrer Anwendung ändern , um etwas inonResumed()
/ zu setzen / zu deaktivierenonPaused()
. Es sind nur ein paar Codezeilen, die in sich geschlossen sind und in Ihrer gesamten Anwendung funktionieren. Außerdem sind keine funky Berechtigungen erforderlich.MyLifecycleHandler.java:
MyApplication.java:
@Mewzer hat einige gute Fragen zu dieser Methode gestellt, auf die ich in dieser Antwort für alle antworten möchte:
onStop()
wird in Situationen mit wenig Speicher nicht aufgerufen; ist das hier ein problemNein. Die Dokumente
onStop()
sagen:Der Schlüssel hier ist "Halten Sie den Prozess Ihrer Aktivität am Laufen ...". Wenn diese Situation mit wenig Arbeitsspeicher jemals erreicht wird, wird Ihr Prozess tatsächlich beendet (nicht nur Ihre Aktivität). Dies bedeutet, dass diese Methode zur Überprüfung der Hintergründe weiterhin gültig ist, da a) Sie das Mitglied ohnehin nicht auf Hintergründe prüfen können, wenn Ihr Prozess beendet wird, und b) wenn Ihr Prozess erneut gestartet wird (weil eine neue Aktivität erstellt wird), das Mitglied Variablen (ob statisch oder nicht) für
MyLifecycleHandler
werden auf zurückgesetzt0
.Funktioniert dies bei Konfigurationsänderungen?
Standardmäßig nein. Sie müssen explizit
configChanges=orientation|screensize
(|
mit allem, was Sie wollen) in Ihrer Manifestdatei festlegen und die Konfigurationsänderungen behandeln, sonst wird Ihre Aktivität zerstört und neu erstellt. Wenn Sie dies nicht festlegen, werden die Methoden Ihrer Aktivität in der folgenden Reihenfolge aufgerufen :onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume
. Wie Sie sehen können, gibt es keine Überlappung (normalerweise überlappen sich zwei Aktivitäten sehr kurz, wenn zwischen den beiden gewechselt wird. So funktioniert diese Hintergrunderkennungsmethode). Um dies zu umgehen, müssen Sie festlegenconfigChanges
, dass Ihre Aktivität nicht zerstört wird. Zum Glück musste ich einstellenconfigChanges
Bereits in all meinen Projekten, weil es unerwünscht war, dass meine gesamte Aktivität auf dem Bildschirm zerstört wurde. Drehen / Ändern der Größe, daher habe ich dies nie als problematisch empfunden. (Danke an dpimka für das Auffrischen meines Gedächtnisses und das Korrigieren von mir!)Eine Note:
Wenn ich hier in dieser Antwort "Hintergrund" gesagt habe, meine ich "Ihre App ist nicht mehr sichtbar". Android-Aktivitäten können sichtbar sein, jedoch nicht im Vordergrund (z. B. wenn eine transparente Benachrichtigungsüberlagerung vorhanden ist). Deshalb habe ich diese Antwort aktualisiert, um dies widerzuspiegeln.
Es ist wichtig zu wissen, dass Android beim Wechseln von Aktivitäten, bei denen nichts im Vordergrund steht, einen seltsamen Moment in der Schwebe hat . Wenn Sie beim Wechseln zwischen Aktivitäten (in derselben App) überprüfen, ob sich Ihre Anwendung im Vordergrund befindet, wird Ihnen aus diesem Grund mitgeteilt, dass Sie nicht im Vordergrund stehen (obwohl Ihre App immer noch die aktive App ist und sichtbar ist ).
Sie können überprüfen , ob Ihre App im Vordergrund in Ihrem sind
Activity
‚sonPause()
Methode nachsuper.onPause()
. Denken Sie nur an den seltsamen Schwebezustand, über den ich gerade gesprochen habe.Sie können überprüfen , ob Ihre App sichtbar sind (dh , wenn es nicht im Hintergrund ist) in Ihrem
Activity
‚sonStop()
Methode nachsuper.onStop()
.quelle
onStop()
Nachsuper.onStop()
. Überprüfen Sie nicht, ob Hintergrundinformationen vorhanden sindonPause()
.GOOGLE-LÖSUNG - kein Hack wie bei früheren Lösungen. Verwenden Sie ProcessLifecycleOwner
Kotlin:
Java:
in app.gradle
Weitere Informationen zu Lifecycle-bezogenen Architekturkomponenten finden Sie hier - https://developer.android.com/topic/libraries/architecture/lifecycle
quelle
companion object { private var foreground = false fun isForeground() : Boolean { return foreground } }
kann : Dann können Sie den Vordergrundstatus mitArchLifecycleApp.isForeground()
The LifecycleOwner for the whole application process. Note that if your application has multiple processes, this provider does not know about other processes.
, funktioniert dies nicht fürmultiple processes
Apps. Gibt es eine API, die wir elegant erreichen können?Wenn Sie die Support-Bibliothek Version 26 starten , können Sie ProcessLifecycleOwner verwenden. Fügen Sie es einfach wie hier beschrieben zu Ihrer Abhängigkeit hinzu , zum Beispiel:
Und
ProcessLifecycleOwner
fragen Sie dann einfach ab, wann immer Sie den App-Status wünschen. Beispiele:quelle
Seit Android API 16 gibt es eine einfache Möglichkeit zu überprüfen, ob die App im Vordergrund steht. Es ist vielleicht nicht kinderleicht, aber keine Methoden unter Android sind kinderleicht. Diese Methode ist gut genug, um verwendet zu werden, wenn Ihr Dienst ein Update vom Server erhält und entscheiden muss, ob eine Benachrichtigung angezeigt werden soll oder nicht (denn wenn die Benutzeroberfläche im Vordergrund steht, wird der Benutzer das Update ohne Benachrichtigung bemerken).
quelle
JobService
zu erkennen , dass der Dienst im Hintergrund ausgeführt wird .Idolons Antwort ist fehleranfällig und viel komplizierter, obwohl hier wiederholt wird. Überprüfen Sie, ob die Android-Anwendung im Vordergrund steht oder nicht. und hier Bestimmen der aktuellen Vordergrundanwendung aus einer Hintergrundaufgabe oder einem Hintergrunddienst
Es gibt einen viel einfacheren Ansatz:
Auf einer BaseActivity, die alle Aktivitäten erweitern:
Wann immer Sie überprüfen müssen, ob eine Ihrer Anwendungsaktivitäten im Vordergrund steht, überprüfen Sie einfach
isVisible()
;Um diesen Ansatz zu verstehen, überprüfen Sie diese Antwort des Side-by-Side-Aktivitätslebenszyklus: Aktivität Side-by-Side-Lebenszyklus
quelle
Idolon's answer is error prone
- Leider muss ich dir zustimmen. Basierend auf dem Kommentar von Dianne Hackborn in den Google Groups habe ich meine Antwort aktualisiert. Überprüfen Sie es bitte für die Details.onPause
,onStop
noch dasonResume
Ereignis aufgerufen wird. Was machen Sie dann, wenn keines dieser Ereignisse ausgelöst wird?!Ich habe die empfohlene Lösung ausprobiert, die Application.ActivityLifecycleCallbacks und viele andere verwendet, aber sie funktionierten nicht wie erwartet. Dank Sarge habe ich eine ziemlich einfache und unkomplizierte Lösung gefunden, die ich unten beschreibe.
Das ist auch der Hauptunterschied zwischen
onStop()
und demonPause()
, den keiner in den Artikeln erwähnt hat, die ich gelesen habe.Basierend auf dem Lebenszyklusverhalten dieser Aktivität können Sie einfach zählen, wie oft
onStart()
undonPause()
in welchem Programm Sie aufgerufen wurden. Beachten Sie, dass Sie für jedesActivity
Programm die zum Zählen verwendete statische Variable überschreibenonStart()
undonStop()
dekrementieren müssen. Unten finden Sie den Code, der diese Logik implementiert. Beachten Sie, dass ich eine Klasse verwende, die erweitertApplication
wird. Vergessen Sie also nicht,Manifest.xml
innerhalb des Application-Tags zu deklarieren :android:name=".Utilities"
obwohl dies auch mit einer einfachen benutzerdefinierten Klasse implementiert werden kann.Jetzt auf jeder Aktivität unseres Programms, sollten wir außer Kraft setzen
onStart()
undonStop()
und Erhöhen / Verringern wie unten dargestellt:Mit dieser Logik gibt es zwei mögliche Fälle:
stateCounter = 0
: Die Anzahl der gestoppten Aktivitäten entspricht der Anzahl der gestarteten Aktivitäten. Dies bedeutet, dass die Anwendung im Hintergrund ausgeführt wird.stateCounter > 0
: Die Anzahl der gestarteten Anwendungen ist größer als die Anzahl der gestoppten Anwendungen. Dies bedeutet, dass die Anwendung im Vordergrund ausgeführt wird.Hinweis: Dies
stateCounter < 0
würde bedeuten, dass mehr Aktivitäten gestoppt als gestartet werden, was unmöglich ist. Wenn Sie auf diesen Fall stoßen, bedeutet dies, dass Sie den Zähler nicht wie gewünscht erhöhen / verringern.Sie sind bereit zu gehen. Sie sollten überprüfen wollen, ob sich Ihre Anwendung im Hintergrund befindet
onStop()
.quelle
if(Utilities.isApplicationOnBackground()) …
zuUtilities
. Denn sonst reagiert nur eine bestimmte Aktivität auf das Ereignis.Es gibt keine Möglichkeit, ohne dass Sie es selbst verfolgen, festzustellen, ob eine Ihrer Aktivitäten sichtbar ist oder nicht. Vielleicht sollten Sie eine neue StackOverflow-Frage stellen und erklären, was Sie mit einer Benutzererfahrung erreichen möchten, damit wir Ihnen möglicherweise alternative Implementierungsideen geben können.
quelle
Service
. Wenn ja, lassen Sie Ihre Aktivitäten den Dienst benachrichtigen, sobald sie angezeigt werden und verschwinden. Wenn dasService
feststellt, dass keine Aktivitäten sichtbar sind und dies für einige Zeit so bleibt, stoppen Sie die Datenübertragung am nächsten logischen Stopppunkt. Ja, dies erfordert Code für jede Ihrer Aktivitäten, aber im Moment ist dies unvermeidlich, AFAIK.MyActivityClass
die vonActivity
den Lebenszyklusmethoden erbt und diese implementiert, und alle Ihre Aktivitäten erben lassenMyActivityClass
. Dies wird nicht funktionieren fürPreferenceActivity
oderMapActivity
obwohl (siehe diese Frage )Mit ComponentCallbacks2 können Sie feststellen, ob sich die App im Hintergrund befindet. Übrigens ist dieser Rückruf nur in API Level 14 (Ice Cream Sandwich) und höher verfügbar .
Sie erhalten einen Aufruf der Methode:
public abstract void onTrimMemory (int level)
Wenn das Level ist, befindet sich
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
die App im Hintergrund.Sie können diese Schnittstelle zu einem Gerät
activity
,service
usw.quelle
Aufbauend auf der Antwort von @Cornstalks mit einigen nützlichen Funktionen.
Zusätzliche Funktionen:
App.java
AppLifecycleHandler.java
quelle
Die beste Lösung, die ich mir ausgedacht habe, verwendet Timer.
Sie haben einen Timer in onPause () gestartet und denselben Timer in onResume () abgebrochen. Es gibt 1 Instanz des Timers (normalerweise in der Application-Klasse definiert). Der Timer selbst ist so eingestellt, dass nach 2 Sekunden (oder einem beliebigen Intervall, das Sie für angemessen halten) ein Runnable ausgeführt wird. Wenn der Timer ausgelöst wird, setzen Sie ein Flag, das die Anwendung als im Hintergrund markiert.
In der onResume () -Methode können Sie vor dem Abbrechen des Timers das Hintergrundflag abfragen, um Startvorgänge auszuführen (z. B. Downloads starten oder Standortdienste aktivieren).
Mit dieser Lösung können Sie mehrere Aktivitäten auf dem Backstack ausführen und benötigen keine Implementierungsberechtigungen.
Diese Lösung funktioniert gut, wenn Sie auch einen Ereignisbus verwenden, da Ihr Timer einfach ein Ereignis auslösen kann und verschiedene Teile Ihrer App entsprechend reagieren können.
quelle
Wenn Sie die Entwicklereinstellungen "Aktivitäten nicht beibehalten" aktivieren, ist es nicht ausreichend, nur die Anzahl der erstellten Aktivitäten zu überprüfen. Sie müssen auch isSaveInstanceState überprüfen . Meine benutzerdefinierte Methode isApplicationRunning () prüft, ob die Android-App ausgeführt wird:
Hier mein Arbeitscode:
quelle
Die einzig richtige Lösung:
MainActivity.java:
MyApp.java:
quelle
Um auf die Aussagen von CommonsWare und Key zurückzugreifen, können Sie möglicherweise die Application-Klasse erweitern und alle Ihre Aktivitäten dies für ihre onPause / onResume-Methoden aufrufen lassen. Auf diese Weise können Sie feststellen, welche Aktivitäten sichtbar sind, dies könnte jedoch wahrscheinlich besser gehandhabt werden.
Können Sie genau erläutern, was Sie vorhaben? Wenn Sie sagen, dass Sie im Hintergrund laufen, meinen Sie damit, dass Ihre Anwendung immer noch im Speicher ist, obwohl sie derzeit nicht auf dem Bildschirm angezeigt wird? Haben Sie darüber nachgedacht, Services als dauerhaftere Methode zur Verwaltung Ihrer App zu verwenden, wenn diese nicht im Fokus steht?
quelle
Application
hat nichtonPause()
oderonResume()
.Ich habe ActivityLifecycleCallbacks selbst implementiert. Ich verwende SherlockActivity, aber für normale Aktivitäten könnte die Klasse funktionieren.
Zunächst erstelle ich eine Schnittstelle, die alle Methoden zum Verfolgen des Aktivitätslebenszyklus enthält:
Zweitens habe ich diese Schnittstelle in der Klasse meiner Anwendung implementiert:
Drittens erstelle ich eine Klasse, die von SherlockActivity ausgeht:
Viertens habe ich alle Klassen, die von SherlockActivity ausgehen, durch MySherlockActivity ersetzt:
Jetzt sehen Sie im Logcat die Protokolle, die in der in MyApplication vorgenommenen Schnittstellenimplementierung programmiert wurden.
quelle
Die Aktivität wird angehalten, wenn ein Dialog darüber angezeigt wird, sodass alle empfohlenen Lösungen Halblösungen sind. Sie müssen auch Hooks für Dialoge erstellen.
quelle
Da dies noch nicht erwähnt ist, empfehle ich den Lesern, ProcessLifecycleOwner zu erkunden, das über Android Architecture-Komponenten verfügbar ist
quelle
Offizielle Dokumente:
Das System unterscheidet zwischen Vordergrund- und Hintergrund-Apps. (Die Definition des Hintergrunds für Zwecke von Dienstbeschränkungen unterscheidet sich von der Definition, die von der Speicherverwaltung verwendet wird. Eine App befindet sich möglicherweise im Hintergrund , was die Speicherverwaltung betrifft , steht jedoch im Vordergrund, was die Fähigkeit zum Starten von Diensten betrifft.) Eine App ist gilt als im Vordergrund, wenn eine der folgenden Aussagen zutrifft:
Wenn keine dieser Bedingungen erfüllt ist, wird die App als im Hintergrund betrachtet.
quelle
Eine andere Lösung für diesen alten Beitrag (für diejenigen, denen es helfen könnte):
quelle
Siehe den Kommentar in der Funktion onActivityDestroyed.
Funktioniert mit SDK-Zielversion 14>:
quelle
Sie sollten eine gemeinsame Einstellung verwenden, um die Eigenschaft zu speichern und mithilfe der Servicebindung aus Ihren Aktivitäten darauf zu reagieren. Wenn Sie nur die Bindung verwenden (dh niemals startService verwenden), wird Ihr Dienst nur ausgeführt, wenn Sie an ihn binden (onResume binden und onPause aufheben), sodass er nur im Vordergrund ausgeführt wird und wenn Sie daran arbeiten möchten Hintergrund können Sie den regulären Start-Stopp-Dienst verwenden.
quelle
Ich denke, diese Frage sollte klarer sein. Wann? Wo? Was ist Ihre spezifische Situation, die Sie kennenlernen möchten, wenn sich Ihre App im Hintergrund befindet?
Ich stelle meine Lösung nur auf meine Weise vor.
Ich erreiche dies, indem ich das Feld "Wichtigkeit" der
RunningAppProcessInfo
Klasse in deronStop
Methode jeder Aktivität in meiner App verwende. Dies kann einfach erreicht werden, indemBaseActivity
für andere Aktivitäten eine Erweiterung bereitgestellt wird , die dieonStop
Methode implementiert , um den Wert von "Wichtigkeit" zu überprüfen. Hier ist der Code:quelle
Ich empfehle, diese Seite durchzulesen : http://developer.android.com/reference/android/app/Activity.html
Kurz gesagt, Ihre Aktivität ist nach dem
onStop()
Aufruf nicht mehr sichtbar .quelle
onStop
; dazwischenonPause
undonStop
es ist sichtbar , aber nicht im Vordergrund .onStop()
Aufruf nicht mehr sichtbar ist, was mit dem übereinstimmt, was Sie geschrieben haben.onPause
aufgerufen wird: Eine kürzlich vorgenommene Bearbeitung hat dich korrigiert.Was ist mit getApplicationState (). IsInForeground ()?
quelle
Meiner Meinung nach führen viele Antworten zu einer großen Menge an Code und bringen viel Komplexität und Nichtlesbarkeit mit sich.
Wenn Leute auf SO fragen, wie sie zwischen a
Service
und a kommunizieren sollenActivity
, empfehle ich normalerweise, den LocalBroadcastManager zu verwenden .Warum?
Nun, indem Sie die Dokumente zitieren:
Nicht in den Dokumenten:
Activity
,Application
...Beschreibung
Sie möchten also überprüfen, ob sich eines der
Activity
Elemente derzeit im Vordergrund befindet. Das machst du normalerweise in einerService
oder deinerApplication
Klasse.Dies bedeutet, dass Ihre
Activity
Objekte zum Absender eines Signals werden (ich bin an / ich bin aus). IhrService
hingegen wird zumReceiver
.Es gibt zwei Momente, in denen Ihre
Activity
erfahren, ob es im Vordergrund oder im Hintergrund läuft (ja, nur zwei ... nicht 6).Wenn das
Activity
in den Vordergrund tritt, wird dieonResume()
Methode ausgelöst (auch nach aufgerufen)onCreate()
).Wenn das
Activity
in den Rücken geht,onPause()
wird gerufen.Dies sind die Momente, in denen Sie
Activity
das Signal an Ihre senden solltenService
um seinen Zustand zu beschreiben.Denken Sie bei mehreren
Activity
an die anActivity
in den Hintergrund tritt und dann ein anderes in den Vordergrund tritt.Die Situation wäre also: *
Das
Service
/Application
hört einfach weiter auf diese Signale und handelt entsprechend.Code (TLDR)
Sie
Service
müssen ein implementierenBroadcastReceiver
, um auf Signale zu warten.Registrieren Sie die
Receiver
inService::onCreate()
Heben Sie die Registrierung auf
Service::onDestroy()
Jetzt
Activity
müssen Sie ihren Zustand mitteilen.Im
Activity::onResume()
Im
Activity::onPause()
Eine sehr, sehr häufige Situation
In der Regel muss nicht überprüft werden, ob sich das
Activity
im Vordergrund befindet oder nicht. Senden Sie einfach die Daten überLocalBroadcastManager
von IhremService
. Wenn das eingeschaltetActivity
ist, reagiert es und handelt.Für diese sehr häufige Situation wird der
Service
zum Absender und derActivity
implementiert denBroadcastReceiver
.Erstellen Sie also eine
Receiver
in IhremActivity
. Registrieren Sie es inonResume()
und heben Sie die Registrierung aufonPause()
. Es ist nicht erforderlich, die anderen Lebenszyklusmethoden zu verwenden .Definieren Sie das
Receiver
Verhalten inonReceive()
(ListView aktualisieren, dies tun, das tun, ...).Auf diese Weise
Activity
hört der Wille nur zu, wenn er im Vordergrund ist und nichts passiert, wenn er im Hintergrund ist oder zerstört wird.Im Falle von mehreren
Activity
wird jeder, der eingeschaltetActivity
ist, antworten (wenn sie auch das implementierenReceiver
).Wenn sich alle im Hintergrund befinden, reagiert niemand und das Signal geht einfach verloren.
Senden Sie die Daten von der
Service
ViaIntent
(siehe Code oben), indem Sie die Signal-ID angeben.quelle
quelle
Keine der Antworten passte ganz zum speziellen Fall, wenn Sie wissen möchten, ob sich eine bestimmte Aktivität im Vordergrund befindet und wenn Sie ein SDK ohne direkten Zugriff auf die Anwendung sind. Für mich war ich im Hintergrund-Thread, habe gerade eine Push-Benachrichtigung für eine neue Chat-Nachricht erhalten und möchte nur dann eine Systembenachrichtigung anzeigen, wenn der Chat-Bildschirm nicht im Vordergrund steht.
Mit dem
ActivityLifecycleCallbacks
, wie in anderen Antworten empfohlen, habe ich eine kleine util-Klasse erstellt, die die Logik enthält, obMyActivity
im Vordergrund steht oder nicht.}}
quelle
In meinen Aktivitäten onResume und onPause schreibe ich einen isVisible-Booleschen Wert in SharedPrefences.
Und lesen Sie es woanders, wenn nötig über,
Vielleicht nicht elegant, aber es funktioniert bei mir ...
quelle
Es mag zu spät sein, um zu antworten, aber wenn jemand zu Besuch kommt, dann ist hier die Lösung, die ich vorschlage: Der Grund, warum eine App wissen möchte, dass sie sich im Hintergrund befindet oder in den Vordergrund tritt, kann viele sein, einige sind, 1. Anzeigen von Toasts und Benachrichtigungen, wenn sich der Benutzer in BG befindet. 2.Um einige Aufgaben zum ersten Mal auszuführen, wenn der Benutzer von BG kommt, z. B. eine Umfrage, ein Neuzeichnen usw.
Die Lösung von Idolon und anderen kümmert sich um den ersten Teil, nicht jedoch um den zweiten. Wenn Ihre App mehrere Aktivitäten enthält und der Benutzer zwischen ihnen wechselt, ist das sichtbare Flag zu dem Zeitpunkt, an dem Sie sich in der zweiten Aktivität befinden, falsch. Es kann also nicht deterministisch verwendet werden.
Ich habe etwas getan, was von CommonsWare vorgeschlagen wurde: "Wenn der Dienst feststellt, dass keine Aktivitäten sichtbar sind und dies für einige Zeit so bleibt , stoppen Sie die Datenübertragung am nächsten logischen Stopppunkt."
Die fettgedruckte Zeile ist wichtig und kann verwendet werden, um einen zweiten Punkt zu erzielen. Wenn ich also onActivityPaused () erhalte, ändere ich das sichtbare nicht direkt in false, sondern habe einen Timer von 3 Sekunden (das ist das Maximum, mit dem die nächste Aktivität gestartet werden sollte) und wenn es nicht onActivityResumed gibt ( ) in den nächsten 3 Sekunden aufrufen, sichtbar in false ändern. Ähnlich wie bei onActivityResumed (), wenn es einen Timer gibt, brich ich ihn ab. Zusammenfassend wird das Sichtbare zu isAppInBackground.
Der Code kann leider nicht kopiert und eingefügt werden ...
quelle
Ich möchte Ihnen empfehlen, dies auf eine andere Weise zu tun.
Ich denke, Sie möchten den Startbildschirm anzeigen, während das Programm gestartet wird. Wenn es bereits im Backend ausgeführt wird, zeigen Sie es nicht an.
Ihre Anwendung kann kontinuierlich die aktuelle Zeit in eine bestimmte Datei schreiben. Überprüfen Sie beim Starten Ihrer Anwendung den letzten Zeitstempel. Wenn current_time-last_time> der Zeitbereich ist, den Sie zum Schreiben der letzten Zeit angegeben haben, bedeutet dies, dass Ihre Anwendung gestoppt wird, entweder vom System oder vom Benutzer selbst beendet.
quelle