https://www.jianshu.com/p/5bc866b9cbb9java
最近由于手头上的工做作完了,比较闲,想着作一些优化。看到之前用的那一套网络框架添加一个请求比较麻烦,而且比较难用,因此想改造一下网络框架。如今Android 市面上很火的固然是 Retrofit+RxJava + OkHttp, 功能强大,简单易用,所以选用这套方案来改造网络库。本篇文章是对Retrofit 的基本使用方法作一些简单的介绍。后面会再写一篇 Retrofit + RxJava + OkHttp 的封装过程。如下是正文。react
Retrofit: Retrofit是Square 公司开发的一款正对Android 网络请求的框架。底层基于OkHttp 实现,OkHttp 已经获得了google 官方的承认。Retrofit官网android
OkHttp: 也是Square 开源的网络请求库git
RxJava:RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,归纳得很是精准。总之就是让异步操做变得很是简单。github
各自的职责:Retrofit 负责请求的数据和请求的结果,使用接口的方式呈现,OkHttp 负责请求的过程,RxJava 负责异步,各类线程之间的切换。json
RxJava + Retrofit + okHttp 已成为当前Android 网络请求最流行的方式。api
以获取豆瓣 Top250 榜单为例,地址:https://api.douban.com/v2/movie/缓存
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 也支持其余的一些转换器,详情请看官网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(); } });
以上是异步方式请求,还有同步方式execute(),返回一个Response,代码以下:
Response<MovieSubject> response = call.execute();
以上就是用Retrofit 完成了一个网络请求,获取豆瓣top250 榜单电影,效果图以下:
以上示例是用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用法详解
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 很强大,能帮我处理不少复杂的场景,若是熟练使用的话,那么能提高咱们的开发效率。这里不打算讲RxJava 的内容,若是还不了解RxJava ,或者还对RxJava不熟悉的话,推荐几篇写很优秀的博客。
1,RxJava 的经典文章,扔物线的 给 Android 开发者的 RxJava 详解
2,关于RxJava 友好的文章
3,关于RxJava 友好的文章-进阶
经过OkHttpClient 能够配置不少东西,好比连接超时时间,缓存,拦截器等等。代码以下:
// 建立 OKHttpClient OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//链接超时时间 builder.writeTimeout(DEFAULT_TIME_OUT,TimeUnit.SECONDS);//写操做 超时时间 builder.readTimeout(DEFAULT_TIME_OUT,TimeUnit.SECONDS);//读操做超时时间 // 添加公共参数拦截器 BasicParamsInterceptor basicParamsInterceptor = new BasicParamsInterceptor.Builder() .addHeaderParam("userName","")//添加公共参数 .addHeaderParam("device","") .build(); builder.addInterceptor(basicParamsInterceptor); // 建立Retrofit mRetrofit = new Retrofit.Builder() .client(builder.build()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .baseUrl(ApiConfig.BASE_URL) .build();
以上只是配置了一些简单的项,如,链接超时时间,实际项目中,咱们可能有一些公共的参数,如 ,设备信息,渠道,Token 之类的,每一个接口都须要用,咱们能够写一个拦截器,而后配置到OKHttpClient里,经过 builder.addInterceptor(basicParamsInterceptor) 添加,这样咱们就不用每一个接口都添加这些参数了。缓存也能够经过写一个拦截器来实现(后面文章再讲)。
以上就是Retrofit+RxJava+OkHttp实现网络请求的简单演示,若是每一个接口都这么写的话,代码量太多,并且不优雅。因此还须要咱们封装一下,因为篇幅有限,封装放到下一篇文章。
** Retrofit + RxJava + OkHttp 封装已更新,请看Retrofit + RxJava + OkHttp 让网络请求变的简单-封装篇**
参考博客:
1,Retrofit用法详解
2,基于Retrofit、OkHttp、Gson封装通用网络框架
3, RxJava 与 Retrofit 结合的最佳实践