zoukankan      html  css  js  c++  java
  • Android 网络请求Retrofit + RxJava*

    一、背景

    经常看到项目用Retrofit+RxJava+RxAndroid的框架,为了看懂项目的结构。现在来了解一下,Retrofit: Retrofit是Square 公司开发的一款正对Android 网络请求的框架。底层基于OkHttp 实现,OkHttp 已经得到了google 官方的认可OkHttp: 也是Square 开源的网络请求库

    RxJava:RxJava 在 GitHub 主页上的自我介绍是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,概括得非常精准。总之就是让异步操作变得非常简单。

    各自的职责:Retrofit 负责请求的数据和请求的结果,使用接口的方式呈现,OkHttp 负责请求的过程,RxJava 负责异步,各种线程之间的切换RxJava + Retrofit + okHttp 已成为当前Android 网络请求最流行的方式。

    二、Retrofit 写一个网络请求

    1,首先,要使用Retrofit ,你肯定需要把它的包引入,在你的build.gradle文件中添加如下配置:

    compile 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit 
     compile 'com.google.code.gson:gson:2.6.2'//Gson 库 
    //下面两个是RxJava 和RxAndroid 
    compile 'io.reactivex:rxjava:1.1.0' 
    compile 'io.reactivex:rxandroid:1.1.0'  
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'//转换器,请求结果转换成Model 
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'//配合Rxjava 使用

    2,创建一个Retrofit 实例,并且完成相关的配置

    public static final String BASE_URL = "https://api.douban.com/v2/movie/";
    Retrofit retrofit = new Retrofit.Builder() 
           .baseUrl(BASE_URL) 
           .addConverterFactory(GsonConverterFactory.create())
           .build();
    说明:配置了接口的baseUrl和一个converter,GsonConverterFactory 是默认提供的Gson 转换器,Retrofit 也支持其他的一些转换器,详情请看官网

    3,创建一个 接口 ,代码如下:

    public interface MovieService { 
    
     //获取豆瓣Top250 榜单 
     @GET("top250")
     Call<MovieSubject> getTop250(@Query("start") int start,@Query("count")int count);
    
    }
    说明:定义了一个方法getTop250,使用get请求方式,加上@GET 标签,标签后面是这个接口的 尾址top250,完整的地址应该是 baseUrl+尾址 ,参数 使用@Query标签,如果参数多的话可以用@QueryMap标签,接收一个Map

    4,用Retrofit 创建 接口实例 MoiveService,并且调用接口中的方法进行网络请求,代码如下:

    //获取接口实例
    MovieService MovieService movieService = retrofit.create(MovieService.class); 
    //调用方法得到一个Call 
    Call<MovieSubject> call = movieService.getTop250(0,20);
     //进行网络请求 
    call.enqueue(new Callback<MovieSubject>() {
           @Override 
           public void onResponse(Call<MovieSubject> call, Response<MovieSubject> response) { 
                mMovieAdapter.setMovies(response.body().subjects);     
                mMovieAdapter.notifyDataSetChanged(); 
           } 
          @Override 
          public void onFailure(Call<MovieSubject> call, Throwable t) { 
             t.printStackTrace(); 
          } 
    });

    以上示例是用get方式完成,如果要使用post 方式,我们只需要修改一下接口中的方法定义,如下:

    public interface MovieService { 
            //获取豆瓣Top250 榜单 
           @FormUrlEncoded
           @POST("top250") 
           Call<MovieSubject> getTop250(@Field("start") int start, @Field("count") int count);
    }

    说明:使用POST 请求方式时,只需要更改方法定义的标签,用@POST 标签,参数标签用 @Field 或者@Body或者FieldMap,注意:使用POST 方式时注意2点,1,必须加上 @FormUrlEncoded标签,否则会抛异常。2,使用POST方式时,必须要有参数,否则会抛异常, 源码抛异常的地方如下:

    if (isFormEncoded && !gotField) { 
          throw methodError("Form-encoded method must contain at least one @Field."); 
    }

    以上就是一个使用Retrofit 完成一个网络请求的完整示例,其他标签使用方式请看官网Retrofit官网,官网用法也介绍的比较详细,此外,发现了一篇博客也介绍得比较详细,Retrofit用法详解

    三,配合RxJava 使用

    1, 更改定义的接口,返回值不再是一个Call ,而是返回的一个Observble.

    public interface MovieService { 
        //获取豆瓣Top250 榜单  
        @GET("top250") 
        Observable<MovieSubject> getTop250(@Query("start") int start, @Query("count")int count);
     }

    2,创建Retrofit 的时候添加如下代码

    addCallAdapterFactory(RxJavaCallAdapterFactory.create())

    3,添加转换器Converter(将json 转为JavaBean)

    addConverterFactory(GsonConverterFactory.create())

    4,Activity 或者 Fragment 中传入 Subscriber 建立订阅关系

    Subscription subscription = movieService.getTop250(0,20) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<MovieSubject>() { 
    @Override
     public void onCompleted() { 
    
     } 
    @Override 
    public void onError(Throwable e) { 
    
    } 
    @Override
     public void onNext(MovieSubject movieSubject) { 
            mMovieAdapter.setMovies(movieSubject.subjects); 
            mMovieAdapter.notifyDataSetChanged(); 
       } 
    });
    以上是加入RxJava 后的网络请求,返回不再是一个Call ,而是一个Observable, 在Activity / Fragment 中传入一个Subscriber 建立订阅关系,
    就可以在 onNext 中处理结果了,RxJava 的好处是帮我处理线程之间的切换,我们可以在指定订阅的在哪个线程,观察在哪个线程。我们可以通过操作符进行数据变换。
    整个过程都是链式的,简化逻辑。其中FlatMap 操作符 还可以解除多层嵌套的问题。总之,RxJava 很强大,能帮我处理很多复杂的场景,如果熟练使用的话,那么能提升我们的开发效率。
  • 相关阅读:
    请简单说一下你了解的端口及对应的服务?
    地址解析协议ARP和逆地址解析协议RARP
    IP地址分类
    OSI分层和五层协议
    对象如何晋升到老年代?
    JVM 垃圾回收机制,何时触发 MinorGC 等操作
    什么是引用?
    类加载机制
    Solaris10怎么创建flash archive
    RPC: program not registered (ZT)
  • 原文地址:https://www.cnblogs.com/chenxibobo/p/9590033.html
Copyright © 2011-2022 走看看