너무 피곤해서 코드만 보고 의식의 흐름대로 작성해본 것. 주관이 많이 들어갔기때문에 100% 신뢰해서는 안된다.
전제 : retrofit 이 리턴해주는 Single 을 옵저버블로 변환해 사용중(우리 프로젝트 구조의 특성상 이렇게 했다)
1. Retrofit 은 인터페이스로 정의한 API 를 기반으로, 어노테이션 프로세서를 이용해? 뚝딱뚝딱 어떤 클래스 를 만들어낸다.
// Retrofit.class
// 여기서 T 는 클래스 (Something::class.java)
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
2. 만들어진 클래스 내부에서 어떤 메서드가 ServiceMethod 객체를 만들고, 이를 OkHttpCall 로 감싼 후 ServiceMethod.adapt(okHttpCall) 를 리턴한다.
3. 여기서 호출되는 ServiceMethod.adapt() 메서드는 RxJava2CallAdapter 일거라는 킹리적 갓심이 든다.
4. RxJava2CallAdapter 의 adapt 메서드를 살펴보면 여기서 옵저버블을 만든다.
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call); // 당연히 비동기로 할테니까 여기겠지
Observable<?> observable;
// 생략
}
5. CallExecuteObservable 클래스를 살펴보면 아래쪽에 CallDisposable 정의가 있다.
private static final class CallDisposable implements Disposable {
private final Call<?> call;
private volatile boolean disposed;
CallDisposable(Call<?> call) {
this.call = call;
}
@Override public void dispose() {
disposed = true;
call.cancel();
}
@Override public boolean isDisposed() {
return disposed;
}
}
6. 해당 옵저버블을 구독 시작하면 아래의 메서드가 불리며 위에 정의된 CallDisposable 로 감싼 후 옵저버에게 전달하는 코드를 볼 수 있다.
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallDisposable disposable = new CallDisposable(call);
observer.onSubscribe(disposable);
// 생략
}
7. 옵저버블이 dispose 되면 당연히 콜이 캔슬될거라는 결론에 도달한다.
'Android > 지식저장소' 카테고리의 다른 글
[Android] 간단한 그리기 및 지우기 with S-Pen (1) | 2021.05.14 |
---|---|
[Android] ConstraintLayout Helper - Group (0) | 2021.01.11 |
[Android] 점선 그리기(Dotted line) (0) | 2021.01.04 |
[Android] BaseSavedState 를 이용하여 View 에 상태 저장하기 (0) | 2020.09.15 |
[Android] RecyclerView 에서 엣지 스크롤 이펙트 숨기기 (0) | 2020.09.09 |