1.从源码角度看,只需要定义一个CallAdapterFactory 处理结果livedata接受默认的CallAdapterFactory 是DefaultCallAdapterFactory
package retrofit2 ;
import java. io. IOException ;
import java. lang. annotation. Annotation ;
import java. lang. reflect. ParameterizedType ;
import java. lang. reflect. Type ;
import java. util. Objects ;
import java. util. concurrent. Executor ;
import javax. annotation. Nullable ;
import okhttp3. Request ;
import okio. Timeout ;
final class DefaultCallAdapterFactory extends CallAdapter. Factory {
@Nullable
private final Executor callbackExecutor;
DefaultCallAdapterFactory ( @Nullable Executor callbackExecutor) {
this . callbackExecutor = callbackExecutor;
}
@Nullable
public CallAdapter < ? , ? > get ( Type returnType, Annotation [ ] annotations, Retrofit retrofit) {
if ( getRawType ( returnType) != Call . class ) {
return null ;
} else if ( ! ( returnType instanceof ParameterizedType ) ) {
throw new IllegalArgumentException ( "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>" ) ;
} else {
final Type responseType = Utils . getParameterUpperBound ( 0 , ( ParameterizedType ) returnType) ;
final Executor executor = Utils . isAnnotationPresent ( annotations, SkipCallbackExecutor . class ) ? null : this . callbackExecutor;
return new CallAdapter < Object , Call < ? > > ( ) {
public Type responseType ( ) {
return responseType;
}
public Call < Object > adapt ( Call < Object > call) {
return ( Call ) ( executor == null ? call : new ExecutorCallbackCall ( executor, call) ) ;
}
} ;
}
}
static final class ExecutorCallbackCall < T > implements Call < T > {
final Executor callbackExecutor;
final Call < T > delegate;
ExecutorCallbackCall ( Executor callbackExecutor, Call < T > delegate) {
this . callbackExecutor = callbackExecutor;
this . delegate = delegate;
}
public void enqueue ( final Callback < T > callback) {
Objects . requireNonNull ( callback, "callback == null" ) ;
this . delegate. enqueue ( new Callback < T > ( ) {
public void onResponse ( Call < T > call, Response < T > response) {
ExecutorCallbackCall . this . callbackExecutor. execute ( ( ) -> {
if ( ExecutorCallbackCall . this . delegate. isCanceled ( ) ) {
callback. onFailure ( ExecutorCallbackCall . this , new IOException ( "Canceled" ) ) ;
} else {
callback. onResponse ( ExecutorCallbackCall . this , response) ;
}
} ) ;
}
public void onFailure ( Call < T > call, Throwable t) {
ExecutorCallbackCall . this . callbackExecutor. execute ( ( ) -> {
callback. onFailure ( ExecutorCallbackCall . this , t) ;
} ) ;
}
} ) ;
}
public boolean isExecuted ( ) {
return this . delegate. isExecuted ( ) ;
}
public Response < T > execute ( ) throws IOException {
return this . delegate. execute ( ) ;
}
public void cancel ( ) {
this . delegate. cancel ( ) ;
}
public boolean isCanceled ( ) {
return this . delegate. isCanceled ( ) ;
}
public Call < T > clone ( ) {
return new ExecutorCallbackCall ( this . callbackExecutor, this . delegate. clone ( ) ) ;
}
public Request request ( ) {
return this . delegate. request ( ) ;
}
public Timeout timeout ( ) {
return this . delegate. timeout ( ) ;
}
}
}
综上需要重写这块get 方法以及CallAdapter
class BaseRes< T> (
var `data `: T? ,
var errorCode: Int,
var errorMsg: String
)
package com. example. myapplication
import androidx. lifecycle. LiveData
import retrofit2. CallAdapter
import retrofit2. CallAdapter. Factory
import retrofit2. Retrofit
import java. lang. reflect. ParameterizedType
import java. lang. reflect. Type
class LiveDataConverterFactory : Factory ( ) {
override fun get (
returnType: Type,
annotations: Array< out Annotation> ,
retrofit: Retrofit
) : CallAdapter< * , * > ? {
if ( getRawType ( returnType) != LiveData:: class . java) return null
val observableType = getParameterUpperBound ( 0 , returnType as ParameterizedType)
val rawType = getRawType ( observableType)
if ( rawType != BaseRes:: class . java) {
throw IllegalArgumentException ( "type must be BaseRes" )
}
if ( observableType ! is ParameterizedType) {
throw IllegalArgumentException ( "resource must be parameterized" )
}
return LiveDataCallAdapter< Any> ( observableType)
}
}
package com. example. myapplication
import androidx. lifecycle. LiveData
import retrofit2. Call
import retrofit2. CallAdapter
import retrofit2. Callback
import retrofit2. Response
import java. lang. reflect. Type
import java. util. concurrent. atomic. AtomicBoolean
class LiveDataCallAdapter< T> ( private val responseType: Type) : CallAdapter< T, LiveData< T> > {
override fun adapt ( call: Call< T> ) : LiveData< T> {
return object : LiveData< T> ( ) {
private val started = AtomicBoolean ( false )
override fun onActive ( ) {
super . onActive ( )
if ( started. compareAndSet ( false , true ) ) {
call. enqueue ( object : Callback< T> {
override fun onFailure ( call: Call< T> , t: Throwable) {
val value = BaseRes< T> ( null , - 1 , t. message ?: "" ) as T
postValue ( value)
}
override fun onResponse ( call: Call< T> , response: Response< T> ) {
postValue ( response. body ( ) )
}
} )
}
}
}
}
override fun responseType ( ) = responseType
}
interface BannerService {
@GET ( "/banner/json" )
fun listRepos ( ) : LiveData< BaseRes< List< Data> > >
}
package com. example. myapplication
import okhttp3. OkHttpClient
import retrofit2. Retrofit
import retrofit2. converter. moshi. MoshiConverterFactory
class RetrofitUtils {
companion object {
private var BaseURL = "https://www.wanandroid.com/"
fun getHttp ( ) : Retrofit {
return Retrofit. Builder ( ) . baseUrl ( BaseURL) . client ( initClient ( ) )
. addConverterFactory ( MoshiConverterFactory. create ( ) )
. addCallAdapterFactory ( LiveDataConverterFactory ( ) )
. build ( )
}
private fun initClient ( ) : OkHttpClient {
val newBuilder = OkHttpClient ( ) . newBuilder ( )
return newBuilder. build ( )
}
}
}
val bannerModel = ViewModelProvider ( this ) [ NetModel:: class . java]
bannerModel. loadData ( ) . observe ( this ) {
println ( "获取的数据 ${ it. data } " )
Picasso. get ( ) . load ( it. data? . get ( 0 ) !! . imagePath) . into ( inflate. iv)
}