Retrofit+OKHttp+RxAndroid,图文最详细解释(Kotlin)

发布于:2022-12-06 ⋅ 阅读:(769) ⋅ 点赞:(0)

众所周知,目前市面上最流行的网络请求的方式莫过于Retrofit+OkHttp+RxJava.
首先我们要知道每个框架的作用:
Retrofit: Retrofit 仅负责 网络请求接口的封装
OkHttp:负责请求的过程
RxJava: 负责异步,各种线程之间的切换。
下面我们逐一介绍各个框架的使用,以及组合起来的使用:

一、Retrofit

流程图如下:
在这里插入图片描述

1、上图说明了如下几点:

  1. App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作。
  2. 在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析。所以网络请求的本质仍旧是OkHttp完成的,retrofit只是帮使用者来进行工作简化的,比如配置网络,理数据等工作,提高这一系列操作的复用性。这也就是网上流行的一个不太准确的总结:okhttp是瑞士军刀,retrofit则是将这把瑞士军刀包装成了一个非常好用的指甲钳。

2、Retrofit 对Okhttp做了什么?

Retrofit并没有改变网络请求的本质,也无需改变,因为Okhttp已经足够强大,Retrofit的封装可以说是很强大,里面涉及到一堆的设计模式,可以通过注解直接配置请求,可以使用不同的http客户端,虽然默认是用http ,可以使用不同Json Converter 来序列化数据,同时提供对RxJava的支持,使用Retrofit + OkHttp + RxJava 可以说是目前比较
潮的一套框架,但是需要有比较高的门槛。

3、下面我们来看一下Retrofit的具体使用:

1、导入依赖: module/build.gradle下

dependencies {
    // Retrofit库
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    // Okhttp库
    compile 'com.squareup.okhttp3:okhttp:3.1.2'
    
  }

2、添加网络权限:\src\main\AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>

3、创建用于描述网络请求的接口

Retrofit将Http请求抽象成java接口:采用注解描述网络请求和配置网络请求参数。
1.用动态代理 动态 将该接口的注解“翻译”成一个 Http 请求,最后再执行 Http 请求
2.接口中的每个方法的参数都需要使用注解标注,否则会报错
注解类型:
2.1.网络请求方法:@GET 、@POST 、@PUT、 @DELETE、 @PATH 、@HEAD 、@OPTIONS 、@HTTP
2.2.标记类:@FormUrlEncoded、 @Multipart 、@Streaming
2.3.网络请求参数:@Header 、@hraders 、@URL、 @Body、 @Path 、@Field、 @FieldMap 、@Part 、@PartMap 、@Query 、@QueryMap

3.1、网络请求方法

在这里插入图片描述
@GET、@POST、@PUT、@DELETE、@HEAD
以上方法分别对应 HTTP中的网络请求方式:Retrofit把网络请求的URL分成了两部分
第一部分:在网络请求接口的注解设置

    @GET("openapi.do?name=jack&pwd=123456")
    fun login() : Call<Reception>
  //@GET注解的作用:采用Get方法发送网络请求
  //getCall() = 接收网络请求数据的方法
  //其中返回类型为Call<*>,*是接收数据的类(此类可以自定义)

第二部分:在创建Retrofit实例时通过.baseUrl()设置

 Retrofit.Builder()
            .baseUrl("https://guz.retroft.com/")
            .addConverterFactory(GsonConverterFactory.create())//设置数据解析器
            .build()
// 从上面看出:一个请求的URL可以通过 替换块 和 请求方法的参数 来进行动态的URL更新。
// 替换块是由 被{}包裹起来的字符串构成
// 即:Retrofit支持动态改变网络请求根目录

网络请求的完整Url = 在创建Retrofit实例时通过baseUrl设置 + 3网络请求接口的注解设置

在这里插入图片描述
@HTTP
作用:替换@GET、@POST、@PUT、@DELETE、@HEAD注解及更多功能的拓展。
具体使用:通过属性method,path,hasBody进行设置。

    /**
     * method:网络请求的方法(区分大小写)
     * path:网络请求地址路径
     * hasBody:是否有请求体
     */
    @HTTP(method = "GET", path = "blog/{id}", hasBody = false)
    Call<ResponseBody> getCall(@Path("id") int id);
    // {id} 表示是一个变量
    // method 的值 retrofit 不会做处理,所以要自行保证准确
3.2、标记

在这里插入图片描述
a. @FromUrlEncoded
发送form-encoded的数据,每个键值对需要用@Filed来注解键名,随后的对象需要提供值。
b.@Multipart
发送form-encoded的数据(适用于有文件上传的场景),每个键值对需要用@Part来注解键名,随后的对象需要提供值。
具体使用:

public interface GetRequest_Interface {
        /**
         *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
         * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
         */
        @POST("/form")
        @FormUrlEncoded
        Call<ResponseBody> testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);
         
        /**
         * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
         * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
         */
        @POST("/form")
        @Multipart
        Call<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);

}

// 具体使用
       GetRequest_Interface service = retrofit.create(GetRequest_Interface.class);
        // @FormUrlEncoded 
        Call<ResponseBody> call1 = service.testFormUrlEncoded1("Carson", 24);
        
        //  @Multipart
        RequestBody name = RequestBody.create(textType, "Carson");
        RequestBody age = RequestBody.create(textType, "24");

        MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
        Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);
3.3、网络请求参数

在这里插入图片描述
a. @Headers
作用:添加请求头 &添加不固定的请求头

//@Header
@GET("user")
Call<user> getUser(@Header("Authorization") String authorization)

// @Headers
@Headers("Authorization: authorization")
@GET("user")
Call<User> getUser()

b.@Body
作用:以 Post方式 传递 自定义数据类型 给服务器
特别注意:如果提交的是一个Map,那么作用相当于 @Field
不过Map要经过 FormBody.Builder 类处理成为符合 Okhttp 格式的表单,如:

FormBody.Builder builder = new FormBody.Builder();
builder.add("key","value");

 给大家举个例子,看一下,body的用法:
    @POST("api/demo/login")
    fun getPersonInfo(@Body requestBody: RequestBody): Observable<Response<LoginBean>>
    这个地方参数为RequestBody,所以后面的入参我们得想办法转换成questBody的形式
    

c. @Field & @FieldMap
作用:发送Post请求时提交请求的表单字段
使用:与 @FormUrlEncoded 注解配合使用

public interface GetRequest_Interface {
        /**
         *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
         * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
         */
        @POST("/form")
        @FormUrlEncoded
        Call<ResponseBody> testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);

/**
         * Map的key作为表单的键
         */
        @POST("/form")
        @FormUrlEncoded
        Call<ResponseBody> testFormUrlEncoded2(@FieldMap Map<String, Object> map);

}

// 具体使用
         // @Field
        Call<ResponseBody> call1 = service.testFormUrlEncoded1("Carson", 24);

        // @FieldMap
        // 实现的效果与上面相同,但要传入Map
        Map<String, Object> map = new HashMap<>();
        map.put("username", "Carson");
        map.put("age", 24);
        Call<ResponseBody> call2 = service.testFormUrlEncoded2(map);

d.@Part & @PartMap
1.作用:发送 Post请求时提交请求的表单字段
2.与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于有文件上传的场景
3.使用:与 @Multipart 注解配合使用

public interface GetRequest_Interface {

          /**
         * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
         * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
         */
        @POST("/form")
        @Multipart
        Call<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);

        /**
         * PartMap 注解支持一个Map作为参数,支持 {@link RequestBody } 类型,
         * 如果有其它的类型,会被{@link retrofit2.Converter}转换,如后面会介绍的 使用{@link com.google.gson.Gson} 的 {@link retrofit2.converter.gson.GsonRequestBodyConverter}
         * 所以{@link MultipartBody.Part} 就不适用了,所以文件只能用<b> @Part MultipartBody.Part </b>
         */
        @POST("/form")
        @Multipart
        Call<ResponseBody> testFileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);

        @POST("/form")
        @Multipart
        Call<ResponseBody> testFileUpload3(@PartMap Map<String, RequestBody> args);
}

// 具体使用  :https://javajgs.com/archives/75280
 MediaType textType = MediaType.parse("text/plain");
        RequestBody name = RequestBody.create(textType, "Carson");
        RequestBody age = RequestBody.create(textType, "24");
        RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容");

        // @Part
        MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
        Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);
        ResponseBodyPrinter.printResponseBody(call3);

        // @PartMap
        // 实现和上面同样的效果
        Map<String, RequestBody> fileUpload2Args = new HashMap<>();
        fileUpload2Args.put("name", name);
        fileUpload2Args.put("age", age);
        //这里并不会被当成文件,因为没有文件名(包含在Content-Disposition请求头中),但上面的 filePart 有
        //fileUpload2Args.put("file", file);
        Call<ResponseBody> call4 = service.testFileUpload2(fileUpload2Args, filePart); //单独处理文件
        ResponseBodyPrinter.printResponseBody(call4);
}



e. @Query和@QueryMap
1.作用:用于@GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)
如:url = http://www.println.net/?cate=android,其中,Query = cate
2.使用:配置时只需要在接口方法中增加一个参数即可

   @GET("/")    
   Call<String> cate(@Query("cate") String cate);
}

// 其使用方式同 @Field与@FieldMap,这里不作过多描述

f. @Path
作用:URL地址的缺省值
使用:

public interface GetRequest_Interface {

        @GET("users/{user}/repos")
        Call<ResponseBody>  getBlog(@Path("user") String user );
        // 访问的API是:https://api.github.com/users/{user}/repos
        // 在发起请求时, {user} 会被替换为方法的第一个参数 user(被@Path注解作用)
    }

g. @Url
作用:直接传入一个请求的 URL变量 用于URL设置
使用:

public interface GetRequest_Interface {

        @GET
        Call<ResponseBody> testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll);
       // 当有URL注解时,@GET传入的URL就可以省略
       // 当GET、POST...HTTP等方法中没有设置Url时,则必须使用 {@link Url}提供

}

在这里插入图片描述

4、创建Retrofit实例

     var retrofit : Retrofit? = null
    init{
        val build = OkHttpClient.Builder().build()
        retrofit = Retrofit.Builder()
            .baseUrl(AppConfig.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(build)
            .build()
    }

    //创建单例模式,来获取retrofit
    companion object{
      private  val retrofit : RetrofitTest by lazy {
            RetrofitTest()
        }
       //单例模式获取接口实例
        fun<T> createService(service:Class<T>) : T? {
            return retrofit.retrofit?.create(service)
        }
    }

a.关于数据解析器(Converter)
1.Retrofit支持多种数据解析方式
2.使用时需要在Gradle添加依赖
数据解析器:Gson,Jackson,Simple XML,Protobuf,Moshi ,Wire ,Scalars
b.关于网络请求适配器(CallAdapter
Retrofit支持多种网络请求适配器方式:guava、Java8和rxjava
使用时如使用的是 Android 默认的 CallAdapter,则不需要添加网络请求适配器的依赖,否则需要按照需求进行添加Retrofit 提供的 CallAdapter
网络请求适配器:guava,java8,rxjava

5、创建网络请求接口实例

interface TestService {
        @GET
        fun login(@Body requestBody: RequestBody) : Call<Reception>
}


 //创建接口实例化
        val createService = RetrofitTest.createService(TestService::class.java)

        //创建接口实例化
        val createService = RetrofitTest.createService(TestService::class.java)
        //对 发送请求 进行封装
        var myCall = createService?.login1()

6、发送网络请求

	//发送网络请求,并处理请求后的结果
        myCall?.enqueue(object : Callback<Reception>{
            override fun onResponse(
                call: retrofit2.Call<Reception>,
                response: Response<Reception>
            ) {
                TODO("Not yet implemented")
            }

            override fun onFailure(call: retrofit2.Call<Reception>, t: Throwable) {
                TODO("Not yet implemented")
            }

        })
    }

二、OkHttp

概况详解:

OkHttp主要是负责请求过程的,其实就是一个请求的客户端,所以要配置一个OkHttpClient.
OkHttpClient支持HTTP/2,允许所有同一个主机地址的请求共享同一个socket连接
连接池减少请求延时
透明的GZIP压缩减少响应数据的大小
缓存响应内容,避免一些完全重复的请求

在这里就不过多讲解OkHttp的使用,主要讲一下怎样配合Retrifit的使用,:

  //******** 一、 创建 httpClient 对象***********

            OkHttpClient httpClient = new OkHttpClient.Builder()
                    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)  //链接超时时间
                    .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) //读取超时时间
                    .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS) //上传超时时间
                    .addInterceptor(logging)//设置需要打印的log
                    .addInterceptor(headerInterceptor()) //设置头部拦截器
                    .build();

 //打印请求log
        val logging = HttpLoggingInterceptor()
        logging.level = if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor.Level.BODY
        } else {
            HttpLoggingInterceptor.Level.NONE
        }


    /**
     * 设置拦截器  :[https://www.cnblogs.com/Robin132929/p/12151889.html]
     */
    private fun headerInterceptor() : Interceptor{
        return Interceptor { chain ->
            var request = chain.request()
            //TODO 根据项目适配调整
            request = request.newBuilder()
                .addHeader("key","value")
                .build()
            chain.proceed(request)
        }
    }

//其实在retrofit中使用很简单,只需要配置一个客户端即可,代码如下:
        retrofit = Retrofit.Builder().client(httpClient).build()

三、RxJava && RxAndroid

一、RxJava是什么?

Rx(Reactive Extensions)是一个库,用来处理【事件】和【异步】任务,在很多语言上都有实现,RxJava是Rx在Java上的实现。简单来说,RxJava就是处理异步的一个库,最基本是基于观察者模式来实现的。通过Obserable和Observer的机制,实现所谓响应式的编程体验。它扩展了观察者模式以支持数据/事件序列,并添加了运算符,使您可以声明性地将序列组合在一起,同时抽象化了对低级线程,同步,线程安全和并发数据结构等问题的关注。 2、RxAndroid是基于RxJava适用于Android的封装;官方给的这句大概会让你明白适配封装了啥:More specifically, it provides a Scheduler that schedules on the main thread or any given Looper.(更具体地说,它提供了一个调度程序,在主线程或任何给定的循环机上进行调度)

二、概念

1.Observable 被观察者 ,事件源。是一个抽象类。
------ 1.1 ObservableEmitter 发射器;
2.Observer 观察者,事件接收处理。是一个接口。
3.subscribe 订阅,把被观察者和观察者关联起来。

三、基础使用

1.集成依赖

build.gradle中dependencies 下依赖;代码如下(示例):

dependencies {
    implementation "io.reactivex.rxjava3:rxjava:3.0.12"
    implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
}

2.用法及分析

fun main(){
    RxJavaAndroid.doRxJava()
}

object  RxJavaAndroid {
    fun doRxJava() {
        //通过 Observable.create 创建被观察者,Observable是一个抽象类
        val observalbe = Observable.create(ObservableOnSubscribe<String> { emitter ->
            //发射器发送消息
            emitter.onNext("hello world");
            //通过发射器发射异常
            //emitter.onError(new Throwable("模拟一个异常"));
            //发射完成
            emitter.onComplete();
        })

        //通过 new Observer 创建观察者;Observer是一个 interface
        val observer : Observer<String> = object  : Observer<String>{

            override fun onSubscribe(d: Disposable) {
                //第一个执行的方法
                println("onSubscribe")
            }

            override fun onNext(t: String) {
                println("onNext>>>$t")
            }

            override fun onError(e: Throwable) {
                println("onError>>>${e.message}")
            }

            override fun onComplete() {
                println("onComplete")
            }

        }
        //通过被观察者 Observable 的 subscribe (订阅) 绑定观察者 Observer
        observalbe.subscribe(observer)
    }


}

运行结果如下:
在这里插入图片描述

3、RxJava 流程总结

Observable.create 创建事件源,但并不生产也不发射事件。 2.实现 observer 接口,但此时没有也无法接受到任何发射来的事件。 3.订阅observable.subscribe(observer), , 此时会调用具体 Observable 的实现类中的 subscribeActual 方法, 此时会才会真正触发事件源生产事件,事件源生产出来的事件通过 Emitter 的 的 onNext ,onError ,onComplete 发射给 observer 对应的方法由下游 observer 消费掉。从而完成整个事件流的处理。 4.observer 中的 onSubscribe 在订阅时即被调用,并传回了 Disposable, observer 中可以利用 Disposable 来随时中断事件流的发射。

4、RxJava 的线程调度机制

这里用rxjava的Builder建造者模式来书写代码。

    /**
     * 建造者模式构建RxJava 流式API
     */

    fun  doRxJava2(){
        Observable.create(ObservableOnSubscribe<String> {
           println("我在这里发射文字-这是运行的线程:--${Thread.currentThread().name}")
            it.onNext("相遇就是一辈子!!!")
        }).subscribe(object : Observer<String>{
            override fun onSubscribe(d: Disposable) {

            }

            override fun onNext(t: String) {
                println("我在这里接收到的文字-这是接收到文字运行的线程:--${Thread.currentThread().name}")
            }

            override fun onError(e: Throwable) {
            }

            override fun onComplete() {
            }

        })
    }

运行肯定都是在main线程中,rxjava默认主线程。如下图:
在这里插入图片描述
当我们把.subscribeOn(Schedulers.io()) 加上后线程就会切换到子线程,执行结果如下:
在这里插入图片描述

由此可见RxJava是通过subscribeOn()来控制线程切换的,我们知道RxThreadFactory是用来创建线程的类。IoScheduler 创建和缓存线程池;大概就明白rxjava是通过 Scheduler (调度器)调度这些线程的就可以了。

四、RxJava+okHttp+Retrofit

上面分别一一讲解了RxJava 、 okHttp 、 Retrofit ,接下来我们将三者的优点聚合起来编写一套现在最流行的网络框架。

1、导入依赖

相关版本号,可根据版本需要添加:

    ext.kotlin_version = "1.6.0" //kotlin版本
    ext.okhttp3_version = "3.8.1" //okhttp版本
    ext.retrofit_version = "2.9.0" //retrofit版本
    ext.rx_version = "2.0.9" //rxjava版本
    ext.ra_version = "2.1.1" //rxjava版本
//Retrofit
implementation "com.squareup.okhttp3:logging-interceptor:${okhttp3_version}"
  implementation "com.squareup.retrofit2:retrofit:${retrofit_version}"
  implementation "com.squareup.retrofit2:converter-gson:${retrofit_version}"
  implementation "com.squareup.retrofit2:adapter-rxjava2:${retrofit_version}"
//RxJava
implementation "io.reactivex.rxjava2:rxjava:${rx_version}"  

2、建立retrofit工厂类,并且加上我们需要的一些拦截,日志等。

class RetrofitFactory {
    val retrofit : Retrofit = TODO()
    init {
        //打印请求log
        //        setlevel用来设置日志打印的级别,共包括了四个级别:NONE,BASIC,HEADER,BODY
        //        BASEIC:请求/响应行
        //        HEADER:请求/响应行 + 头
        //        BODY:请求/响应行 + 头 + 体
        val logging = HttpLoggingInterceptor()
        logging.level = if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor.Level.BODY
        } else {
            HttpLoggingInterceptor.Level.NONE
        }
        val okHttpclient  =  OkHttpClient.Builder()
            .addInterceptor(logging)
            .addInterceptor(headerInterceptor())
            .build()

        retrofit = Retrofit.Builder()
            .baseUrl(AppConfig.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(okHttpclient)
            .build()
    }



    /**
     * 拦截头部
     */
    private fun headerInterceptor() : Interceptor{
        return Interceptor { chain ->
            var request = chain.request()
            request = request.newBuilder()
                .addHeader("key","value")
                .build()
            chain.proceed(request)
        }
    }

    companion object{
        // Double check
        private val instances : RetrofitFactory by lazy {
            RetrofitFactory()
        }
        fun <T> createService(service :Class<T>) : T {
            return instances.retrofit.create(service)
        }

        /**
         * 在RetrofitFactory文件中加入针对Observable的扩展函数
         */
        fun <T> Observable<Response<T>>.executeResult(subscriber: ResultObserver<T>){
            this.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber)
        }
    }
}

我们使用lazy委托的方式实现单例,见委托。这样我们在每一次想要获取到retrofit接口时,直接调用RetrofitFactory.createService(apiInterface)即可。

3、引入了Rxjava

先自定义一个全局网络请求的Observer,封装网络请求的各种情况,成功,失败,完成等等。

abstract class ResultObserver<T> : Observer<Response<T>>{

    override fun onSubscribe(d: Disposable) {
        if (!d.isDisposed){
            onRequestStart()
        }
    }

    override fun onNext(t: Response<T>) {
        onResquestEnd()
        if (t.isSuccessful){
            try {
                onSuccess(t.body())
            }catch (e : Exception){
                e.printStackTrace()
            }
        }else{
            try {
                onBusinessFail(t.code(),t.message())
            }catch (e : Exception){
                e.printStackTrace()
            }

        }
    }


    override fun onError(e: Throwable) {
       onResquestEnd()
        if (e is ConnectException
            || e is TimeoutException
            ||  e is NetworkErrorException
            || e  is UnknownHostException){
            onFailure(e,true)
        }else{
            onFailure(e,false)
        }
    }



    override fun onComplete() {
        TODO("Not yet implemented")
    }




    /**
     *  请求开始
     */
    open fun onRequestStart(){}

    /**
     * 请求结束
     */
    open fun onResquestEnd(){}

    /**
     * 返回成功
     */
    @Throws(Exception::class)
    abstract fun onSuccess(requst : T?)

    /**
     * 返回失败
     */
    @Throws(Exception::class)
    abstract fun onFailure(e : Throwable,isNetWorkError : Boolean)

    /**
     * 业务错误:->返回成功了,但是code错误
*/
@Throws(Exception::class)
open fun onBusinessFail(code:Int,message : String) {
    }

}

首先是继承Observer,复写四个接口方法:onSubscribeonNextonError``onComplete。然后加入了使用需要复写的请求结果业务方法:成功onSuccess,失败onFailure。以及给出了一些定制化选项:开始请求onRequestStart,请求结束onRequestEnd,业务错误onBusinessFail

4、调接口请求网络

        RetrofitFactory.createService(UserService::class.java).getPersonInfo()
            .executeResult(object : ResultObserver<User>(){
                override fun onSuccess(requst: User?) {
                    TODO("Not yet implemented")
                }

                override fun onFailure(e: Throwable, isNetWorkError: Boolean) {
                    TODO("Not yet implemented")
                }
            })
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到