Ich habe einen Begrüßungsbildschirm auf einem Timer. Mein Problem ist, dass ich vor finish()
meiner Aktivität überprüfen muss, ob die nächste Aktivität gestartet wurde, da ein Systemdialogfeld angezeigt wird und ich nur möchte finish()
. Sobald der Benutzer eine Option aus dem Dialogfeld ausgewählt hat?
Ich weiß, dass es viele Fragen gibt, wie Sie feststellen können, ob Ihre Aktivität im Vordergrund steht, aber ich weiß nicht, ob dies auch Dialogfelder über der Aktivität zulässt.
Hier ist das Problem, das Rot ist meine Aktivität, die im Hintergrund ist, während der Dialog im Vordergrund steht:
BEARBEITEN: Ich habe versucht, es einfach nicht zu verwenden, finish()
aber dann kann meine Aktivität in dem Stapel von Anwendungen wiederhergestellt werden, den ich vermeiden möchte.
Antworten:
Dies wird als richtige Lösung empfohlen :
In Ihrer
finish()
Methode möchten SieisActivityVisible()
überprüfen, ob die Aktivität sichtbar ist oder nicht. Dort können Sie auch prüfen, ob der Benutzer eine Option ausgewählt hat oder nicht. Fahren Sie fort, wenn beide Bedingungen erfüllt sind.Die Quelle erwähnt auch zwei falsche Lösungen ... also vermeiden Sie das.
Quelle: Stackoverflow
quelle
onPause
,onStop
noch dasonResume
Ereignis aufgerufen wird. Was machen Sie dann, wenn keines dieser Ereignisse ausgelöst wird?!Wenn Sie auf API-Level 14 oder höher abzielen, können Sie android.app.Application.ActivityLifecycleCallbacks verwenden
quelle
UPD : aktualisiert auf Status
Lifecycle.State.RESUMED
. Danke an @htafoya dafür.Im Jahr 2019 können Sie mithilfe einer neuen Support-Bibliothek
28+
oder AndroidX einfach Folgendes verwenden:Sie können mehr in der Dokumentation lesen, um zu verstehen, was unter der Haube passiert ist.
quelle
activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)
oder zu starten.INITIALIZED
garantiert nicht, dass es im Vordergrund ist.Activity :: hasWindowFocus () gibt Ihnen den Booleschen Wert zurück, den Sie benötigen.
Hier ist eine Beispielklasse, mit der Sie die Sichtbarkeit Ihrer Aktivitäten von jedem Ort aus überprüfen können.
Denken Sie daran, dass das Ergebnis falsch ist , wenn Sie einen Dialog anzeigen , da der Dialog den Hauptfokus hat. Davon abgesehen ist es sehr praktisch und zuverlässiger als Lösungsvorschläge.
quelle
Dies ist genau der Unterschied zwischen
onPause
und denonStop
Ereignissen der Aktivität, wie in der Dokumentation zur Aktivitätsklasse beschrieben .Wenn ich Sie richtig verstehe, möchten Sie
finish()
von Ihrer Aktivität aus anrufen,onStop
um sie zu beenden. Siehe das angehängte Bild der Activity Lifecycle Demo App . So sieht es aus, wenn Aktivität B von Aktivität A gestartet wird. Die Reihenfolge der Ereignisse ist von unten nach oben, sodass Sie sehen können, dass Aktivität AonStop
aufgerufen wird, nachdem Aktivität BonResume
bereits aufgerufen wurde.Wenn ein Dialogfeld angezeigt wird, wird Ihre Aktivität im Hintergrund abgeblendet und nur
onPause
aufgerufen.quelle
Zwei mögliche Lösungen:
1) Aktivitätslebenszyklus-Rückrufe
Verwenden Sie eine Anwendung , die ActivityLifecycleCallbacks implementiert, und verwenden Sie sie, um die Lebenszyklusereignisse von Aktivitäten in Ihrer Anwendung zu verfolgen. Beachten Sie, dass ActivityLifecycleCallbacks für Android-API> = 14 sind. Für frühere Android-APIs müssen Sie es in all Ihren Aktivitäten selbst implementieren ;-)
Verwenden Sie die Anwendung, wenn Sie Status für Aktivitäten freigeben / speichern müssen.
2) Überprüfen Sie, ob Prozessinformationen ausgeführt werden
Mit dieser Klasse RunningAppProcessInfo können Sie den Status eines laufenden Prozesses überprüfen
Rufen Sie die Liste der laufenden Prozesse mit ActivityManager.getRunningAppProcesses () ab und filtern Sie die Ergebnisliste, um nach der gewünschten RunningAppProcessInfo zu suchen und ihre "Wichtigkeit" zu überprüfen.
quelle
Ich habe ein Projekt auf Github erstellt App-Vordergrund-Hintergrund-Listen erstellt
Das verwendet sehr einfache Logik und funktioniert gut mit allen Android API-Ebene.
quelle
Verwenden Sie die Zeitspanne zwischen Pause und Wiederaufnahme aus dem Hintergrund, um festzustellen, ob sie aus dem Hintergrund wach ist
In der benutzerdefinierten Anwendung
In der BaseActivity-Klasse
quelle
Ich denke, ich habe eine bessere Lösung. Weil Sie einfach MyApplication.activityResumed () einbauen können; zu jeder Aktivität um eine Ausdehnung.
Zuerst müssen Sie erstellen (wie CyberneticTwerkGuruOrc)
Als Nächstes müssen Sie die Anwendungsklasse zu AndroidManifest.xml hinzufügen
Erstellen Sie dann die Klasse ActivityBase
Wenn Sie eine neue Aktivität erstellen, können Sie sie einfach um ActivityBase anstelle von Activity erweitern.
Für mich ist es eine bessere Methode, weil Sie sich nur an die Erweiterung durch ActivityBase erinnern müssen. Darüber hinaus können Sie Ihre Basisfunktion in Zukunft erweitern. In meinem Fall habe ich Empfänger für meinen Dienst und Warnungen zum Netzwerk in einer Klasse hinzugefügt.
Wenn Sie die Sichtbarkeit Ihrer App überprüfen möchten, können Sie einfach anrufen
quelle
Dies kann durch eine effiziente Verwendung erreicht werden Application.ActivityLifecycleCallbacks erreicht werden
Nehmen wir zum Beispiel den Namen der Aktivitätsklasse als ProfilActivity, um herauszufinden, ob er sich im Vordergrund oder im Hintergrund befindet
Zuerst müssen wir unsere Anwendungsklasse durch Erweitern erstellen Anwendungsklasse
welche implementiert
Lassen Sie uns meine Anwendungsklasse wie folgt sein
Anwendungsklasse
In der obigen Klasse gibt es ein Override- Verfahren für ActivityResumed von ActivityLifecycleCallbacks
Wenn alle Aktivitätsinstanzen gefunden werden, die derzeit auf dem Bildschirm angezeigt werden, überprüfen Sie einfach mit der oben beschriebenen Methode, ob Ihre Aktivität auf dem Bildschirm angezeigt wird oder nicht.
Registrieren Sie Ihre Anwendungsklasse in manifest.xml
Um das Wetter zu überprüfen, ist die Aktivität Vordergrund oder Hintergrund gemäß der obigen Lösung. Rufen Sie die folgende Methode an den Stellen auf, die Sie überprüfen müssen
quelle
Wenn Sie wissen möchten, ob eine Aktivität Ihrer App auf dem Bildschirm sichtbar ist, können Sie Folgendes tun:
Erstellen Sie einfach einen Singleton dieser Klasse und legen Sie ihn in Ihrer Anwendungsinstanz wie folgt fest:
Dann können Sie die isAnyActivityVisible () -Methode Ihrer MyAppActivityCallbacks-Instanz überall verwenden!
quelle
Haben Sie versucht, nicht finish aufzurufen und "android: noHistory =" true "in das Manifest aufzunehmen? Dadurch wird verhindert, dass die Aktivität in den Stapel verschoben wird.
quelle
Ich muss sagen, dass Ihr Workflow nicht normal für Android ist. In Android müssen Sie nicht
finish()
Ihre Aktivität wenn Sie eine andere Aktivität von Intent aus öffnen möchten. Aus praktischen Gründen kann der Benutzer mit Android die Zurück-Taste verwenden, um von der Aktivität zurückzukehren, die Sie für Ihre App geöffnet haben.Lassen Sie das System einfach Ihre Aktivität stoppen und speichern Sie alles, was Sie benötigen, wenn Ihre Aktivität zurückgerufen wird.
quelle
Speichern Sie eine Flagge, wenn Sie angehalten oder fortgesetzt werden. Wenn Sie wieder aufgenommen werden, bedeutet dies, dass Sie im Vordergrund stehen
quelle
Eine mögliche Lösung könnte darin bestehen, ein Flag zu setzen, während der Systemdialog angezeigt wird, und dann in der onStop-Methode des Aktivitätslebenszyklus zu überprüfen, ob das Flag vorhanden ist. Wenn dies der Fall ist, beenden Sie die Aktivität.
Wenn der Systemdialog beispielsweise durch einen Knopfdruck ausgelöst wird, sieht der Listener onclick möglicherweise so aus
und bei Unterbrechung der Aktivität:
quelle
Warum nicht dafür Sendungen verwenden? Die zweite Aktivität (die aktiv sein muss) kann eine lokale Sendung wie folgt senden:
Schreiben Sie dann einen einfachen Empfänger innerhalb der Splash-Aktivität:
und registrieren Sie Ihren neuen Empfänger beim LocalBroadcastManager, um die Sendung Ihrer zweiten Aktivität anzuhören:
HINWEIS: Sie können eine Konstante oder eine Zeichenfolgenressource für die Zeichenfolge "Broadcast-ID" verwenden.
quelle
LocalBroadcastManager
hierWenn Sie
finish()
nur verwenden, um zu vermeiden, dass eine neue App im Stapel (Aufgabe) Ihrer App gestartet wird, können SieIntent.FLAG_ACTIVITY_NEW_TASK
beim Starten einer neuen Anwendung das Flag verwenden und überhaupt nicht aufrufenfinish()
. Laut Dokumentation ist dies das Flag, das zum Implementieren eines Verhaltens im "Launcher" -Stil verwendet werden soll.quelle
Verwenden Sie diese Methoden innerhalb eines
Activity
.isDestroyed()
isFinishing()
Ein häufiger Fehler
AsyncTask
besteht darin, einen starken Verweis auf den HostActivity
(oderFragment
) zu erfassen :Dies ist ein Problem, da
AsyncTask
es die Eltern leicht überleben kannActivity
, z. B. wenn eine Konfigurationsänderung während der Ausführung der Aufgabe .Der richtige Weg, dies zu tun, besteht darin, Ihre Aufgabe zu einer
static
Klasse zu machen , die das übergeordnete Element nicht erfasst und einen schwachen Verweis auf den Host enthältActivity
:quelle
Hier ist eine Lösung mit
Application
Klasse.Sie können es einfach wie folgt verwenden:
Wenn Sie einen Verweis auf die erforderliche Aktivität haben oder den kanonischen Namen der Aktivität verwenden, können Sie herausfinden, ob sie im Vordergrund steht oder nicht. Diese Lösung ist möglicherweise nicht kinderleicht. Daher sind Ihre Kommentare sehr willkommen.
quelle
Ich weiß nicht, warum niemand über sharedPreferences für Aktivität A gesprochen hat und eine SharedPreference wie diese festgelegt hat (zum Beispiel in onPause ()):
Ich denke, dies ist der zuverlässige Weg, um Aktivitäten sichtbar zu machen.
quelle
Wäre
Activity.onWindowFocusChanged(boolean hasFocus)
hier nützlich? Das, plus ein Klasse-Level - Flag, so etwas wie ,isFocused
dassonWindowFocusChanged
Sätze, wäre eine einfache Möglichkeit, an einem beliebigen Stelle in Ihrer Tätigkeit zu sagen , wenn es fokussiert ist oder nicht. Nach dem Lesen der Dokumente sieht es so aus, als würde es in jeder Situation, in der sich die Aktivität nicht direkt im physischen "Vordergrund" befindet, richtig "false" setzen, z. B. wenn ein Dialogfeld angezeigt oder die Benachrichtigungsleiste heruntergezogen wird.Beispiel:
quelle
Wenn Sie EventBus verwenden , wird es als Methode aufgerufen
hasSubscriberForEvent
, mit der überprüft werden kann, ob einActivity
fokussiert ist.quelle
Früher mochte ich,
wenn die Aktivität nicht im Vordergrund steht
wird null zurückgeben. : = P.
quelle