Android知识进阶(遥远的重头开始)

Retrofit+Rxjava-CallAdapterFacto

2019-08-01  本文已影响8人  MonkeyLei

练习地址 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

上一篇下一篇

猜你喜欢

热点阅读