Android RetroLamda实现问题

时间:2017-04-16 07:14:21

标签: android java-8 retrolambda

我是Android开发中使用RetroLamda的新手。我了解到,这取决于参数类型来选择方法。我有如下界面:

interface OnCallListener {
  onSuccess(String msg);
  onError(String msg);
}

现在共同实施:

test.SetOnCallListener(new OncallListener(){
  public void onSuccess(String msg){
  ......
  }
  public void onError(String msg){
  .....
  }

});

如何在RetroLamda表达式中处理这种情况,其中两个方法具有相同的输入类型?

1 个答案:

答案 0 :(得分:2)

简短回答

您可以使用默认方法并将您的侦听器子类化为仅负责一种类型的事件。

答案很长

我给出的答案更适合迁移具有相似品质的普通Java监听器:具有多种抽象方法的接口,有时候那些也会包含不必要的样板量,因为用户只会感兴趣处理一个特定事件而不是一次处理所有事件。

将它们与Retrolambda一起使用会带来一些你可能愿意或不愿意接受的权衡。有关此herehere的更多信息。

基本思想:要使侦听器参数成为用lambda实现的有效目标,必须确保无论侦听器目标类是什么,它都应该只有一个抽象方法。 考虑到最初的课程:

public interface CallListener<T> {
  void onSuccess(T result);
  void onError(String errorMsg);
}

它有几个抽象方法,所以为了使它成为lambda的有效赋值目标,我们必须实现&#34;只有一种方法。我们使用默认方法执行此操作:

public class CallListeners {
  public static interface SuccessListener<T> extends CallListener<T> {
    // we implement onError in such way that listener would ignore error event
    default void onError(String _ignore) {}
  }
  public static interface ErrorListener<T> extends CallListener<T> {
    default void onSuccess(T result) {}
  }

  // Methods to "help" compiler infer correct listener type
  public void <T> Call<T> success(SuccessListener<T> listener) {
    return listener;
  }
  public void <T> Call<T> error(ErrorListener<T> listener) {
    return listener;
  }
}

之后,您可以使用以上所有内容:

test.SetOnCallListener(
  CallListeners.success(argument -> /*your implementation here*/));

<强>替代地

您可以创建一个允许插入其方法的各种(可能可重用的)实现的具体类,并且具有实用工厂方法,其中除了一个事件侦听器之外的所有事件都是通过空操作实现的:

public class CallListenerImpl<T> implements CallListener<T> {
  private Consumer<T> success; // java.util.function.Consumer
  private Consumer<String> error;
  public CallListenerImpl(Consumer<? super T> succ, Consumer<String> err) {
    success = succ; error = err;
  }
  void onSuccess(T result) {
    success.accept(result);
  }
  void onError(String err) {
    error.accept(err);
  }

  // Sugary stuffs:
  public static <T> CallListenerImpl<T> success(Consumer<T> succ) {
    return new CallListenerImpl<>(succ, noOp());
  }
  public static <T> CallListenerImpl<T> error(Consumer<String> err) {
    return new CallListenerImpl<>(noOp(), err);
  }
  private static <T> Consumer<T> noOp() {
    return a -> {};
  }
}