使用 java 7 未来改造 2

问题描述 投票:0回答:1

有没有办法将Retrofit 2与java 7 futures(而不是java 8 completablefutures)一起使用?

类似于

的东西
interface MyService {
  GET("somepath")
  Future<User> getUser()
}
java retrofit2 future
1个回答
0
投票

您应该能够创建类似于 Java8CallAdapterFactory.java 的适配器。它看起来像:

public class Java7CallAdapterFactory extends CallAdapter.Factory {

    public static Java7CallAdapterFactory create() {
        return new Java7CallAdapterFactory();
    }

    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        // TODO: Check type of returnType and innerType, null checks, etc ...
        Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType);
        return new BodyCallAdapter<R>(responseType);
    }

    private static final class BodyCallAdapter<R> implements CallAdapter<R, Future<R>> {
        private final Type responseType;

        BodyCallAdapter(Type responseType) {
            this.responseType = responseType;
        }

        @Override public Type responseType() {
            return responseType;
        }

        @Override public Future<R> adapt(final Call<R> call) {
            final Java7Future<R> future = new Java7Future<>(call);

            call.enqueue(new Callback<R>() {
                @Override 
                public void onResponse(Call<R> call, Response<R> response) {
                    if (response.isSuccessful()) {
                        future.complete(response.body());
                    } // TODO: else
                }

                @Override 
                public void onFailure(Call<R> call, Throwable t) {
                    // TODO
                }
            });

            return future;
        }
    }

    private static class Java7Future<R> implements Future<R> {
        private Call<R> call;
        private boolean completed = false;
        private R value;

        public Java7Future(Call<R> call) {
            this.call = call;
        }

        public void complete(R result) {
            completed = true;
            value = result;
        }

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            if (call != null) {
                call.cancel();
            }
            return false;
        }

        @Override
        public boolean isCancelled() {
            return call == null || call.isCanceled();
        }

        @Override
        public boolean isDone() {
            return completed;
        }

        @Override
        public R get() {
            if (isCancelled()) {
                throw new CancellationException();
            } else {
                // TODO: wait
                return value;
            }
        }

        @Override
        public R get(long timeout, @NonNull TimeUnit unit) {
            // TODO: wait
            return get();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.