Вы можете попробовать использовать CompletableFuture
. В реализации вашего интерфейса:
class MyImplementation implements MyInterface {
@Override
List<FirebaseVisionFace> getFaceList() {
final CompletableFuture<List<FirebaseVisionFace>> future = new CompletableFuture<>();
final DetectorOfSomeKindYouDidNotSpecifyAbove detector = // ... get detector
detector.detectInImage(image)
.addOnSuccessListener(
new OnSuccessListener<List<FirebaseVisionFace>>() {
@Override
public void onSuccess(List<FirebaseVisionFace> faces) {
// Task completed successfully
future.complete(faces);
}
})
.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Task failed with an exception
future.completeExceptionally(e);
}
});
try {
return future.get(); // blocks until completion by one of the listeners above
} catch (final RuntimeException throwMe) {
throw throwMe;
} catch (final InterruptedException interruptedException) {
Thread.currentThread().interrupt();
throw new IllegalStateException(interruptedException.getMessage(), interruptedException);
} catch (final Exception everythingElse) {
throw new IllegalStateException(everythingElse.getMessage(), everythingElse);
}
}
}
Мой код обработки ошибок выше глуп для краткости. Весь код выше не проверен и списан с манжеты. Я предполагаю, что слушатели вызываются, когда все обнаружение сделано, и вызываются один раз. Я также предполагаю, что вызван только один из слушателей, а не оба. Я также предполагаю, что они вызываются другим потоком.
И наконец, обратите внимание, что (как вы, кажется, знаете) интерфейс, подобный тому, который вы пытаетесь реализовать, по сути устранит все преимущества асинхронность, происходящая в его базовой реализации.
Надеюсь, это, по крайней мере, укажет вам правильное направление!