Ich versuche zu verhindern, dass die Aktivität zweimal geladen wird, wenn ich die Taste unmittelbar nach dem ersten Klick zweimal drücke.
Ich habe eine Aktivität, die beispielsweise auf Knopfdruck geladen wird
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Load another activity
}
});
Da die zu ladende Aktivität Netzwerkanrufe enthält, dauert das Laden (MVC) etwas länger. Ich zeige zwar eine Ladeansicht dafür, aber wenn ich vorher zweimal auf die Schaltfläche drücke, kann ich sehen, dass die Aktivität zweimal geladen wird.
Weiß jemand, wie man das verhindert?
Antworten:
Deaktivieren Sie im Ereignis-Listener der Schaltfläche die Schaltfläche und zeigen Sie eine andere Aktivität an.
Überschreiben
onResume()
, um die Schaltfläche wieder zu aktivieren.quelle
Fügen Sie dies Ihrer
Activity
Definition inAndroidManifest.xml
...Beispielsweise:
quelle
android:launchMode = "singleTop"
, den Effekt zu erzielen, ohne das Android-Multitasking zu unterbrechen. In der Dokumentation heißt es, dass die meisten Apps diesesingleInstance
Option nicht verwenden sollten .Sie können die Absichtsflags wie folgt verwenden.
Dadurch wird nur eine Aktivität oben im Verlaufsstapel geöffnet.
quelle
android:launchMode = "singleTop"
diese Weise wird es gelöst, ohne dass das Flag zu jeder Absicht hinzugefügt werden muss.Da SO es mir nicht erlaubt, andere Antworten zu kommentieren, muss ich diesen Thread mit einer neuen Antwort verschmutzen.
Häufige Antworten auf das Problem "Aktivität öffnet zweimal" und meine Erfahrungen mit diesen Lösungen (Android 7.1.1):
BEARBEITEN: Dies war zum Starten von Aktivitäten mit startActivity (). Bei Verwendung von startActivityForResult () muss sowohl FLAG_ACTIVITY_SINGLE_TOP als auch FLAG_ACTIVITY_CLEAR_TOP festgelegt werden.
quelle
Es hat nur bei mir funktioniert, wenn
startActivity(intent)
quelle
android:launchMode = "singleInstance"
in der Manifest-Datei Ihres Aktivitäts-Tags hinzuzufügen ?Verwenden Sie singleInstance, um zu vermeiden, dass Aktivitäten zweimal aufgerufen werden.
quelle
Nehmen wir an, @wannik ist richtig, aber wenn wir mehr als eine Schaltfläche haben, die denselben Aktionslistener aufruft, klicke ich fast gleichzeitig auf zwei Schaltflächen, bevor ich mit der nächsten Aktivität beginne ...
Es ist also gut, wenn Sie Feld
private boolean mIsClicked = false;
und im Hörer haben:Und
onResume()
wir müssen den Staat zurückgeben:Was ist der Unterschied zwischen meiner und @ wanniks Antwort?
Wenn Sie im Listener der aufrufenden Ansicht "enabled" auf "false" setzen, wird die andere Schaltfläche, die denselben Listener verwendet, weiterhin aktiviert. Um sicherzugehen, dass die Aktion des Listeners nicht zweimal aufgerufen wird, benötigen Sie etwas Globales, das alle Aufrufe des Listeners deaktiviert (egal, ob es sich um eine neue Instanz handelt oder nicht).
Was ist der Unterschied zwischen meiner Antwort und anderen?
Sie denken richtig, aber sie denken nicht an eine zukünftige Rückkehr zur gleichen Instanz der aufrufenden Aktivität :)
quelle
synchronized(mIsClicked) {...}
, um 100% sicher zu sein.In dieser Situation werde ich mich für eine von zwei Annäherungen entscheiden,
singleTask
in manifest.xml ODER für ein Flag imonResume()
& der AktivitätonDestroy()
Methoden Methoden wählen.Für die erste Lösung: Ich bevorzuge die Verwendung
singleTask
für die Aktivität im Manifest anstelle dersingleInstance
VerwendungsingleInstance
herauszufinden, dass die Aktivität in einigen Fällen eine neue separate Instanz für sich selbst erstellt, was dazu führt, dass in den ausgeführten Apps zwei separate Anwendungsfenster vorhanden sind in bcakground und neben zusätzlichen Speicherzuweisungen, die zu einer sehr schlechten Benutzererfahrung führen würden, wenn der Benutzer die Apps-Ansicht öffnet, um eine App zum Fortsetzen auszuwählen. Der bessere Weg ist also, die Aktivität in der manifest.xml wie folgt zu definieren:Sie können Aktivität einen Modus überprüfen hier .
Für die zweite Lösung müssen Sie lediglich eine statische Variable oder eine Präferenzvariable definieren, zum Beispiel:
und von der anderen Seite, wenn Sie diese Aktivität starten möchten, überprüfen Sie einfach:
quelle
Ich denke, Sie werden das Problem falsch lösen. Im Allgemeinen ist es eine schlechte Idee für eine Aktivität, lang laufende Webanforderungen in einer ihrer Startlebenszyklusmethoden zu stellen (
onCreate()
,onResume()
usw.). Eigentlich sollten diese Methoden einfach verwendet werden, um Objekte zu instanziieren und zu initialisieren, die Ihre Aktivität verwenden wird, und sollten daher relativ schnell sein.Wenn Sie eine Webanforderung ausführen müssen, führen Sie dies in einem Hintergrundthread Ihrer neu gestarteten Aktivität aus (und zeigen Sie den Ladedialog in der neuen Aktivität an). Sobald der Hintergrundanforderungsthread abgeschlossen ist, kann er die Aktivität aktualisieren und den Dialog ausblenden.
Dies bedeutet dann, dass Ihre neue Aktivität sofort gestartet werden sollte und der Doppelklick nicht möglich sein sollte.
quelle
Hoffe das hilft:
quelle
Eine andere sehr sehr einfache Lösung, wenn Sie keine Verwendung wünschen,
onActivityResult()
ist das Deaktivieren der Schaltfläche für 2 Sekunden (oder die gewünschte Zeit), ist nicht ideal, kann aber teilweise das Problem in einigen Fällen lösen und der Code ist einfach:quelle
Behalten Sie einfach ein Flag in der Schaltfläche onClick-Methode bei:
public boolean oneTimeLoadActivity = false;
quelle
// Variable zur Verfolgung der Ereigniszeit
2.In onClick überprüfen Sie, ob, wenn die aktuelle Zeit und der Unterschied zwischen der letzten Klickzeit weniger als 1 Sekunde betragen, nichts unternommen wird (Rückkehr), sonst klicken Sie auf ein Klickereignis
quelle
Wenn Sie onActivityResult verwenden, können Sie eine Variable zum Speichern des Status verwenden.
Funktioniert auch beim Drücken der Zurück-Taste, da der Anforderungscode bei einem Ereignis zurückgegeben wird.
quelle
Fügen Sie den Startmodus als einzelne Aufgabe im Manifest hinzu, um zu vermeiden, dass die Aktivität beim Klicken zweimal geöffnet wird
quelle
quelle
Verwenden Sie eine
flag
Variable, setzen Sie sieto true
. Überprüfen Sie , ob sie wahr istreturn
, und führen Sie einen Aktivitätsaufruf aus.Sie können auch setClickable (false) verwenden, um den Aktivitätsaufruf auszuführen
quelle
perform click; wait; flg = false;
denn wenn wir zurückkommenSie können einfach startActivityForResult überschreiben und die Instanzvariable verwenden:
quelle
Sie können dies auch versuchen
quelle