带你解惑【Retrofit2 的使用以及配合RxJava的使用】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaxiazaizai01/article/details/70810292

最近刚离职,前几天参加的一个面试被问到对Retrofit的使用是否了解,无奈,,确实没怎么用过。。上网一搜,什么??还没使用Retrofit2你就out了!!!被这几个大字赤裸裸的嘲讽了。好吧,还是先到厕所抽根烟冷静一会,回来开始研究下Retrofit2。
这里写图片描述

刚开始看的时候被这些什么 @Path 、@Query、@QueryMap、@Field、@FieldMap等等这些给搞蒙圈了,就好像刚看RxJava时那些磨人的操作符一样。不知道你是否跟我一样的感受,那么接下来我们就主要说说这些注解的用法,该怎么用。如果这些不了解清楚的话那么也就没法往后继续研究了。勿喷,大鸟请绕道

先说Retrofit2,最后再说retrofit2与RxJava的结合使用。本来想着上来先一通讲解这些个磨人的注解,但是文章刚写一会,本来很简单的问题,反而被越说越复杂了。那就先直截了当的来一个快速入门—retrofit2的使用小案例。

首先,使用retrofit2需要先新建个业务处理请求的接口,这里我们用干货集中营的接口进行演示说明,在这里向干货集中营表示感谢。

public interface NetApiService {

    @GET("{category}/{count}/{page}")
    Call<InfoBean> getAndroidInfos(@Path("category") String category, @Path("count") String count, @Path("page") String page);
}

关于这些@Path 、@Query、@QueryMap、@Field、@FieldMap的使用放到后面讲解。

然后,我们需要在我们的MainActivity里去配置retrofit2

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private InfoAdapter adapter;
    private List<InfoBean.ResultDataBean> lists;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化控件
        iniViews();
        //网络请求
        getNetWorkResponse();
    }

    private void iniViews() {
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new InfoAdapter(this, null);
        recyclerView.setAdapter(adapter);
    }

    private void getNetWorkResponse() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://gank.io/api/data/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        NetApiService service = retrofit.create(NetApiService.class);
        Call<InfoBean> call = service.getAndroidInfos("Android", "10", "1");
        //异步请求
        call.enqueue(new Callback<InfoBean>() {
            @Override
            public void onResponse(Call<InfoBean> call, Response<InfoBean> response) {
                InfoBean infoBean = response.body();
                lists = infoBean.getResults();
                adapter.setRefreshDatas(lists);
            }

            @Override
            public void onFailure(Call<InfoBean> call, Throwable t) {

            }
        });
    }
}

说明:首先是创建一个retrofit2的实例,baseUrl就是配置请求的基本地址,addConverterFactory表示需要用什么解析器来解析返回值,可以看到我们传了个GsonConverterFactory.create()进去,表示用Gson库来进行解析,牵扯到gson解析以及后面要说的与RxJava配合使用,那么,我们需要在我们应用的build.gradle中进行如下配置

compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'

上面例子中我们采用异步加载的方式,有异步就有同步,retrofit2的同步加载请求比较简单,直接就是call.execute(),不过需要注意的是,retrofit2的同步请求不能放在UI线程,会阻塞UI,因此需要放到工作线程中去执行。异步请求可以参考下上面给出的例子。

适配器adapter、布局文件以及实体类这里就不再说了,根据上面的小例子我们得到了干货集中营每天发布的关于Android相关的文章,这里取的是title,请看效果图
这里写图片描述

接下来,我们就来主要介绍下这些@Path 、@Query、@QueryMap、@Field、@FieldMap等等意思以及如何使用

get请求

@Path

如果请求接口中有一个参数字段需要手动为其传值然后直接拼接的话,我们可以用@Path来实现

public interface NetApiService {

    @GET("{category}/{count}/{page}")
    Call<InfoBean> getAndroidInfos(@Path("category") String category, @Path("count") String count, @Path("page") String page);
}

我们进行网络请求一般有get、post、put、delete等请求方式,而这个@Path可以适用于任何一种请求,就是说不但在get请求中可以使用,在post、put … 也都适用。根据上面的代码,我们可以看到@Path的作用就是直接将传进来的值替代这些大括号所表示的内容。

从文章开头给出的代码可以看到http://gank.io/api/data/可以作为基本地址,后面接的是分类(可以为Android或者ios等)、每页显示的数量、第几页等这些参数是需要在请求接口的时候传到服务器的,由于是get请求,所以@GET(“{category}/{count}/{page}”)的意思就很清晰了。

调用方法

Call<InfoBean> call = service.getAndroidInfos("Android", "10", "1");

最终,通过此方式请求得到的url地址就为下面这个地址

http://gank.io/api/data/Android/10/1

@Query

此方式表示的是参数以键值对的方式拼接到请求接口中,即以key=value的形式拼接到url后面。由于干货集中营中没有这种类型的接口,所以,这里我模拟一下,主要是为了解释说明该如何适用

public interface NetApiService {

    @GET("Android/info")
    Call<InfoBean> getAndroidInfo(@Query("tag") String tag, @Query("count") String count, @Query("page") String page);
}

调用方法

Call<InfoBean> call = service.getAndroidInfo("it", "10", "1");

那么,最后得到的url地址就为:

http://gank.io/api/data/Android/info?tag=it&count=10&page=1

① 如果我们有些字段是非必须上传的字段的时候,例如这个tag是非必须字段,我们就可以这样

Call<InfoBean> call = service.getAndroidInfo(null, "10", "1");

最后得到的url地址为

http://gank.io/api/data/Android/info?count=10&page=1

② 如果我们需要上传的字段是key相同,但是value不同,那么我们又该怎么办,你可能会说直接多写几个@Query,这样当然可以,只不过我们还有一种比较简便的方式,例如

public interface NetApiService {

    @GET("Android/info")
    Call<InfoBean> getAndroidInfo(@Query("tag") List<String> name);
}

比如在调用该方法时传进去一个含有两个数据的list集合,那么最后得到的url地址为:

http://gank.io/api/data/Android/info?tag=it&tag=other

@QueryMap

如果我们需要上传的参数比较多的时候,然后我们像上面一样写很多个@Query的话显然很不优雅,并且还容易写错,这时候我们就可以用@QueryMap这种方式将所有的参数放到一个map集合中,然后只需要传递一个map进来就行了

public interface NetApiService {

    @GET("Android/info")
    Call<InfoBean> getAndroidInfo(@QueryMap Map<String, String> map);
}

那么,我们调用的时候就可以这样

Map<String, String> map = new HashMap<>();
        map.put("tag", "IT");
        map.put("count", "10");
        map.put("page", "1");
Call<InfoBean> call2 = service.getAndroidInfo(map);

那么,最后得到的url地址就是

http://gank.io/api/data/Android/info?tag=IT&count=10&page=1

post请求

@Field

今天先写到这里,申请的离职手续下来了,要去办理离职手续了。。回头再补上。未完待续。。。。

参考文章https://blog.csdn.net/duanyy1990/article/details/52139294

猜你喜欢

转载自blog.csdn.net/xiaxiazaizai01/article/details/70810292