Ihre Frage ist faszinierend, aber die angenommene Antwort liefert Ihnen leider falsche Mittel.
Das Problem mit Ihrer Frage ist das der API. Sie versuchen, Rückrufe auf eine Weise zu verwenden, für die sie nicht vorgesehen sind. Ein Callback soll per Definition ein Mittel bieten, etwas asynchron zu tun. Es ist mehr wie eine Spezifikation dessen, was zu tun ist, wenn etwas passiert (in Zukunft). Eine synchrone Methode wie getCustomToken()
, die etwas zurückgibt, das ein Ergebnis einer inhärent asynchronen Operation wie onSuccess()
ist, impliziert eine grundlegende Trennung.
Während Rückrufe zu behandeln, ist es wichtig zu verstehen, die Bedeutung von Fortsetzungen: Maßnahmen ergreifen, wenn bestimmte Ereignisse von Interesse passieren. Beachten Sie, dass diese Ereignisse möglicherweise nicht einmal auftreten. Sie geben jedoch im Code die Aktionen an, die ausgeführt werden sollen, wenn diese Ereignisse auftreten. Daher ist der Fortsetzungsstil eine Verschiebung vom prozeduralen Stil.
Was zur Komplexität des Datenflusses beiträgt, ist die Syntax der anonymen inneren Klassen. Du tendierst zu denken: "Oh, warum kann ich nicht einfach von hier zurückkehren, was onSuccess()
zurückgibt?Immerhin ist der Code richtig hier. "Aber stellen Sie sich vor, dass Java keine inneren Klassen hatte (und wie Sie vielleicht wissen, kann (anonyme) innere Klasse leicht durch eine Klasse ersetzt werden, die keine innere Klasse ist) gebraucht haben, wie etwas zu tun ist:
OnSuccessListener listener = new SomeImplementation();
FirebaseAuth.getInstance().createCustomToken(listener);
Nun wird der Code, der Daten (String) zurückgegeben gegangen Sie können sogar visuell Grund dafür, dass in diesem Fall zurück gibt es keine Möglichkeit für Ihre Methode eine Zeichenfolge ist. - Es ist einfach nicht da!
Also, ich ermutige Sie zu überlegen, was passieren soll, wenn und wann (in Zukunft) onSuccess()
auf deraufgerufen wird Wenn Sie also in Ihre API, die getCustomToken()
API-Methode (diese gibt eine Token-Zeichenfolge, eine Person
-Instanz vorausgesetzt) geben möchten.
Wenn Sie unbedingt ein solches Verfahren bereitzustellen, müssen Sie
Sollte dokumentieren, dass das zurückgegebene Token null
(oder etwas Sinnvolles wie None
) sein kann, und dass Ihre Kunden wieder versuchen müssen, wenn sie eine gültige wollen Wert.
Sollte einen Listener bereitstellen, der einen Thread-sicheren Container mit Tokens aktualisiert, die von dieser Methode gelesen werden.
Googeln herum, fand ich die Firebase documentation. Dies scheint auch nimmt eine Aktion auf Erfolg vorschlagen (in Fortsetzung Stil):
FirebaseAuth.getInstance().createCustomToken(uid)
.addOnSuccessListener(new OnSuccessListener<String>() {
@Override
public void onSuccess(String customToken) {
// **Send token back to client**
}
});
Das andere Problem mit dem Versuch, eine solche API zur Verfügung zu stellen die scheinbare Komplexität des Codes für etwas trivial ist. Der Datenfluss ist ziemlich komplex und schwer zu verstehen.
Wenn Blockierung Ihnen als Lösung akzeptabel ist, dann vielleicht können Sie den Callable-Future-Stil verwenden, in dem Sie eine Callable
passieren und dann später eine get()
auf dem Future
tun, die blockieren können. Aber ich bin mir nicht sicher, ob das hier eine gute Designwahl ist.
Nein, wenn ich 'onSuccess' Rückgabeobjekt in' String' ändere, erhält es einen Kompilierfehler: 'Der Rückgabetyp ist nicht kompatibel mit OnSuccessListener – Richard
Endgültige Variable zu einem Containerobjekt außerhalb des Aufrufs bereitstellen aber innerhalb der Methode, lassen Sie den Listener das Token in diesen Container schreiben, dann herausholen und zurückgeben. – Thomas