Retrofit+Rxjava-CallAdapterFacto

作者: MonkeyLei | 来源:发表于2019-08-01 17:22 被阅读8次

    练习地址 FanChael/RxNet

    上一篇我们瞄了瞄MonkeyLei:Retrofit+Rxjava-ConverterFactory-篇一-先了解一下 ,深的东西现在还没有搞,只能说不简单,o( ̄︶ ̄)o Then,我们继续看看Retrofit 2.3.0 API 官方API的解释如下:

       public interface CallAdapter<R,T>
    Adapts a Call with response type R into the type of T. Instances are created by a factory which is installed into the Retrofit instance.
    

    解释:这是一个相应类型R的适配器。该实例是被安装到Retrofit实例里面的CallAdapter.Factory所创建的..强行理解一把.

    CallAdapter.Factory有几个方法,很重要,后面自定义也是关乎:

    image

    **--然后看CallAdapter - **这个一开始看,有点老火,后面跟着做下自定义实践就会清晰一些

    image

    **---再看Call<T> - **了解这个,一方面我们再定义的时候可以包装这个Call,同时或许还能联想到RxJava怎么实现的子线程,UI线程的无缝切换的....当然可能还需要看点源码,心里才能较好的确定!

    image

    上面看完就看完了,反正是懵的,_ Then,我们再来瞟一眼那个RxJavaCallAdapterFactory那个源码吧,先瞟了再说:

    1. RxJavaCallAdapterFactory.java
    image image

    2. 然后到 RxJavaCallAdapter.java

    image

    3. 然后到 Observable.java 方法

    这个方法里面有熟悉的身影,like如下:

    image

    然后小萌新暂时跟不动了。。。 大概知道了上面三个东东,然后就可以尝试自定义个了呀。。然后自己实现CustomCall的一些个方法,进而封装类似Observable的功能,还能实现子线程,UI线程的切换(我想应该可以滴)。。。。

    自定义一下看看

    CustomCallAdapterFactory.java

      package com.hl.rxnettest;
    
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    
    import retrofit2.CallAdapter;
    import retrofit2.Retrofit;
    
    public class CustomCallAdapterFactory extends CallAdapter.Factory{
        /**
         * Returns an instance which creates synchronous observables that do not operate on any scheduler
         * by default.
         */
        public static CustomCallAdapterFactory create() {
            return new CustomCallAdapterFactory();
        }
    
        @Nullable
        @Override
        public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
            Class<?> rawObservableType = getRawType(returnType);
            // com.hl.rxnettest.CustomCall<java.lang.String>
            Log.e("test2", "get returnType=" + returnType);
            if (rawObservableType == CustomCall.class && returnType instanceof ParameterizedType) {
                // class com.hl.rxnettest.CustomCall
                Log.e("test2", "get rawObservableType=" + rawObservableType);
                Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
                // class java.lang.String
                Log.e("test2", "get observableType=" + observableType);
                return new CustomCallAdapter(observableType);
            }
            return null;
        }
    }
    
    

    看如下就知道我们到底要做什么了..就是酱紫的关系...

    image

    CustomCallAdapter.java

    package com.hl.rxnettest;
    
    import android.util.Log;
    
    import java.lang.reflect.Type;
    
    import retrofit2.Call;
    import retrofit2.CallAdapter;
    
    class CustomCallAdapter implements CallAdapter<R, Object> {
        private final Type responseType;
    
        public CustomCallAdapter(Type responseType){
            Log.e("test2", "CustomCallAdapter responseType=" + responseType);
            this.responseType = responseType;
        }
    
        @Override
        public Type responseType() {
            return responseType;
        }
    
        @Override
        public CustomCall<R> adapt(Call<R> call) {
            Log.e("test2", "CustomCallAdapter adapt");
            return new CustomCall<>(call);
        }
    }
    
    

    如下简单记录一波...

    image

    CustomCall.java - 小萌新搞了一个get,一个enqueue方法,供用户调用。这里就像RxJava的Observable...

      package com.hl.rxnettest;
    
    import java.io.IOException;
    
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    
    public class CustomCall<R> {
        public final Call<R> call;
    
        public CustomCall(Call<R> call) {
            this.call = call;
        }
    
        public R get() throws IOException {
            return (R)"获取数据呀!";//call.execute().body();
        }
    
        public void enqueue(final Callback<R> _call){
            call.enqueue(new Callback<R>() {
                @Override
                public void onResponse(Call<R> call, Response<R> response) {
                    _call.onResponse(call, response);
                }
    
                @Override
                public void onFailure(Call<R> call, Throwable t) {
                    _call.onFailure(call, t);
                }
            });
        }
    }
    
    

    这样我们就简单的自定义了这个东东,然后就可以使用起来了: - 不用管是否能调用,假接口也行。。

          @POST("users/{user}/repos")
        fun listReposStringCustomCall(@Path("user") user: String, @Body data: String): CustomCall<String>
    
    image
           // 自定义CustomCallAdapterFactory,类似RxJavaCallAdapterFactory,针对线程切换进行了优雅的处理!
            var reposStringCustomCall = gitHubService.listReposStringCustomCall("FanChael", "s-requestBodyConverter")
            // 直接获取数据
            var result = reposStringCustomCall.get();
            Log.e("CustomCall", "result=" + result);
            // CustomCall增加异步获取数据的方法enqueue->内部就是调用了Call的异步方法而已
            reposStringCustomCall.enqueue(object : Callback<String>{
                override fun onResponse(call: Call<String>, response: Response<String>){
                    if (response.isSuccessful) {
                        // response.body() -> String
                        // Log.e("reposString-onResponse", response.body())
                    } else {
                        Log.e("CustomCall-onResponse", "请求错误了!")
                    }
                }
                override fun onFailure(call: Call<String>, t: Throwable){
                    Log.e("CustomCall-onFailure", t.message)
                }
            })
    
    

    然后跑起来就完事了:

    image

    鉴于上一篇,我们的Convert简单入门,然后这里我们也设置了, 所以了,这个转换器相关的一些东西,在Retrofit.java源码里面有身影,有一个链表专门存储这个转换器,所以有很多转换器添加。小萌新之前好像说只有最后一个生效,哈哈,这里纠正下,我太菜了哈!不过小萌新一般还是有冗余的说的:

    image

    小萌新以这样的方式去搞搞了,感觉对这个越来越熟悉一些了,不再很陌生的样子。算是总体过了过。。后面的话,就是结合RxJava来对具体使用做一些入门分析。 然后拉通整个过程。。。 至于深入的细节,等整体拉通之后再逐渐搞起来! 最后才是自己封装一下之前项目的一些东西,虽然之前也做了一些经验性封装,但是感觉不太得劲....总是不是那么肯定或者好,而且很多功能都木有!

    先这样吧。。。网友的也推荐下吧,,我是参考了一些,然后自己也看了一些官方,然后才做了一番实践和乱七八糟的感悟...

    Retrofit2自定义CallAdapter

    shusheng007:秒懂Retrofit2之CallAdapter

    Retrofit 2.3.0 API

    相关文章

      网友评论

        本文标题:Retrofit+Rxjava-CallAdapterFacto

        本文链接:https://www.haomeiwen.com/subject/blycdctx.html