Android 入门(十二)Retrofit 和 OkHttp

1,046 阅读3分钟

要求:会使用 Retrofit / OkHttp 进行日常开发,复杂功能可以通过搜索和查阅官方文档解决即可

Retrofit 其实是将 OkHttp 再进行了一层封装,这是个三方的库,所以在使用之前我们需要在 build.gradle 加入依赖。

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

还有我们需要进行网络请求,在 manifest 中申请网络权限也是不能省的

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

直接使用 Retrofit

  1. 先获取 Retrofit 对象,由于 Retrofit 实现了 Builder 模式,所以不能跟一般类那样使用 new 操作符得到对象。使用 Builder().build() 方法得到了对象,并且添加了 baseUrl 和 Gson 转换器。
public static final String BASE_URL = "https://www.wanandroid.com";

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();
  1. 创建一个接口,这个接口有个 GET 的注解,这个注解会将字符串与 baseUrl 拼接成一个完成的 api 接口。而 Query 注解是将内容以参数的形式拼接到后面,如:wanandroid.com/wxarticle/l… ,如果参数多的话可以用 @QueryMap 标签,接收一个 Map。
public interface WXArticleService {
    // 获取鸿洋公众号文章,@Query("k") 注解会将内容以参数的形式拼接到
    @GET("wxarticle/list/408/1/json")
    Call<WXArticleBean> getArticle(@Query("k") String key);
}

这个 javaBean 是根据 Json 数据转换得到的,这里推荐一款插件 GsonFormat,可以直接在 AS 中使用。

  1. 用 Retrofit 创建接口实例 wxArticleService,然后加入需要搜索的关键词,进行网络请求。call.enqueue() 是异步方法,call.execute() 则是同步的方式。
// 获取接口实例
WXArticleService wxArticleService = retrofit.create(WXArticleService.class);
// 调用方法得到一个 Call
Call<WXArticleBean> call = wxArticleService.getArticle("Retrofit");
// 进行网络请求
call.enqueue(new Callback<WXArticleBean>() {
    @Override
    public void onResponse(Call<WXArticleBean> call, Response<WXArticleBean> response) {
        // 获取到 response 之后,就可以使用你想要的数据做任何事情
        if (response.body() != null) {
            int count = response.body().getData().getDatas().size();
            for (int i = 0; i < count; i++) {
                Log.d(TAG, "onResponse: " + response.body().getData().getDatas().get(i).getTitle());
            }
        }
    }
    @Override
    public void onFailure(Call<WXArticleBean> call, Throwable t) {
        t.printStackTrace();
    }
});

当然也能使用 POST 方法,说明:使用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."); 
}

最后的结果如下:

结果

配合 RxJava 使用

一般我们进行网络请求都会放在子线程中执行,而 RxJava 就是「异步」的代言词,这两者就很自然的走到了一起。

使用的方法仍然分为三步:

  1. 还是获取 Retrofit 对象
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build();

这次我们加入了一个新的解析器 addCallAdapterFactory 用来解析除默认 Call 对象之外的其他对象,比如 RxJava 中的 Observable 对象。

  1. 创建一个新的接口
public interface WXOfficialAccountsService {
    // 获取 wanandroid 中收藏的所有公众号
    @GET("wxarticle/chapters/json")
    Observable<WXOfficialAccountsBean> getOfficialAccounts();
}

这时候返回的不是一个 Call 对象,而是返回一个 Observable 对象,可以用来建立观察者模式。

  1. 获取接口实例,进行网络请求
// 获取接口实例
WXOfficialAccountsService movieService = retrofit.create(WXOfficialAccountsService.class);
// 订阅
movieService.getOfficialAccounts()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<WXOfficialAccountsBean>() {
            @Override
            public void onSubscribe(Disposable d) {
            }
            @Override
            public void onNext(WXOfficialAccountsBean wxOfficialAccountsBean) {
                int len = wxOfficialAccountsBean.getData().size();
                for (int i = 0; i < len; i++) {
                    String name = wxOfficialAccountsBean.getData().get(i).getName();
                    Log.d(TAG, "作者:" + name);
                }
            }
            @Override
            public void onError(Throwable e) {
            }
            @Override
            public void onComplete() {
            }
        });

加入 RxJava 之后,GET 请求会在 IO 线程中处理,处理完之后结果会主线程中打印出来。

加入 OkHttp 配置

还可以在获取 Retrofit 对象的时候,加入 OkHttp 配置。

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(8, TimeUnit.SECONDS);
builder.writeTimeout(8, TimeUnit.SECONDS);
builder.readTimeout(8, TimeUnit.SECONDS);

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(builder.build())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build();

最后的结果如下:

结果

参考:

Retrofit + RxJava + OkHttp 让网络请求变的简单-基础篇 Retrofit + RxJava + OkHttp 让网络请求变的简单-封装篇