Retrofit+Rxjava-CallAdapterFacto
练习地址 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那个源码吧,先瞟了再说:
image image2. 然后到 RxJavaCallAdapter.java
image3. 然后到 Observable.java 方法
这个方法里面有熟悉的身影,like如下:
image然后小萌新暂时跟不动了。。。 大概知道了上面三个东东,然后就可以尝试自定义个了呀。。然后自己实现CustomCall的一些个方法,进而封装类似Observable的功能,还能实现子线程,UI线程的切换(我想应该可以滴)。。。。
自定义一下看看
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;
}
}
看如下就知道我们到底要做什么了..就是酱紫的关系...
imagepackage 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);
}
}
如下简单记录一波...
imageCustomCall.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来对具体使用做一些入门分析。 然后拉通整个过程。。。 至于深入的细节,等整体拉通之后再逐渐搞起来! 最后才是自己封装一下之前项目的一些东西,虽然之前也做了一些经验性封装,但是感觉不太得劲....总是不是那么肯定或者好,而且很多功能都木有!
先这样吧。。。网友的也推荐下吧,,我是参考了一些,然后自己也看了一些官方,然后才做了一番实践和乱七八糟的感悟...