Retrofit和Rxjava结合实践(一)--Retrofit快速上手

好几个月没有搞android的东西,感觉自己拉下很多,正好最近有个新项目,就顺便研究一下现在很火的Retrofit和Rxjava。

这个专题我打算写三篇,分别介绍Retrofit,Rxjava以及如何将两者结合起来。
本篇先介绍比较简单的Retrofit

一. 为什么要使用Retrofit
因为简洁,好用,而且效率高(关于效率这一点,我曾经看到过一个请求耗时的对比,但是对不起各位看官,我搜了好多地方都没有找到这个数据)。

我先写一个”远古时期”我们经常用到的网络请求以及处理流程。
通常我们在网络请求后会再处理UI线程,所以我们往往一个组合是HTTPClient+AsyncTask

一个简单的Client的get请求

       // 使用线程安全的连接管理来创建HttpClient
       ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
       DefaultHttpClient client = new DefaultHttpClient(conMgr, params);

       HttpGet request = new HttpGet(URL);
       HttpResponse response = client.execute(request);
       int httpStatusCode = response.getStatusLine().getStatusCode();
       if (httpStatusCode == HttpStatus.SC_OK) {
           result = EntityUtils.toString(response.getEntity());
       } else {
           throw new HttpException("Error Response:" + response.getStatusLine().toString());
       }

       return result;

最终我们得到了一个result,这里面是我们期望返回的数据(比如是一个json)。
为了让这个json数据为我所用,我们还需要把它转化成一个数据结构,这一步我们通常会使用Gson(相关代码省去不表)。
当然,上面的这个流程,你可以封装到一个类里面,无需每次都写这么多代码。
假设封装后,我们可以通过下面这个方法来调起这个网络请求并结构化数据

UserBean bean = new UserCenter(mContext).getUserInfo(token);

下面我们需要写一个AsyncTask,在它里面发起网络请求并处理数据,一个简单的AsyncTask通常是如下

private class GetUserInfoTask extends AsyncTask<Integer, Integer, UserBean> {
        @Override
        protected Result<UserBean> doInBackground(Integer... params) {
            UserBean bean = new UserBean();
            bean = new UserCenter(mContext).getUserInfo(token);;
            return bean;

        }

        @Override
        protected void onPostExecute(UserBean result) {
            super.onPostExecute(result);
            //TODO 处理返回的数据,显示在UI中
        }
    }

最后,你可以愉快(或者很不耐烦)地调用它了:

new GetUserInfoTask().execute();

而以上的这些,如果用retrofit,我们写出来是这样的(你不需要马上理解这些代码,后面我们会详细讲到):

public interface UserAPIService {
    @GET("user")
    Call<UserBean> getUserInfo(@Query("token") String token);
}

Retrofit appRetrofit = new Retrofit.Builder().baseUrl(url)
.addConverterFactory(GsonConverterFactory.create()).build();
Call<UserBean> call = appRetrofit.create(UserAPIService.class).getUserInfo(token);
call.enqueue(new Callback<UserBean>() {
    @Override
    public void onResponse(Response<UserBean> response) {
        //TODO 处理返回的数据,显示在UI中
    }

    @Override
    public void onFailure(Throwable t) {
        //获取失败的逻辑
    }
});

没了,这就是所有的代码,而且你还可以把其中很多代码封装起来,得到一个更简洁的版本。
我觉得这已经有足够的理由让我们去用retrofit了(反正我是学会后完全不想用asynctask什么的了)

二. 如何使用Retrofit
关于Retrofit原理和使用的文章网上非常多,如果大家想看更多详细的信息,可以去Github看Retrofit的源码(https://github.com/square/retrofit
或者去看官方的使用说明(http://square.github.io/retrofit/
我在下面不会非常详细的讲解Retrofit的原理和API,我只是想通过最少的文字,来教会大家如何使用它。

在开始之前,需要声明一点:网上有很多retrofit的使用说明,但是大都是1.x版本的,跟2.0版本有很大的区别(此篇博客发布时,最新的retrofit版本是2.0.0,我用的也是这个版本)
关于2.0的文章,非常推荐大家去看下面这一篇:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3460.html

首先,要使用Retrofit,我们需要创建一个Retrofit的实例,类似你要创建一个http client的实例是一样的:

Retrofit appRetrofit = new Retrofit.Builder().baseUrl(url)
.addConverterFactory(GsonConverterFactory.create()).build();

其中,baseUrl(url)就是设置我要请求的地址,比如我们的接口都是走的这个域名www.baidu.com/xxx,那这里你就应该url=www.baidu.com
addConverterFactory是一个很神奇的方法,它添加了一个数据的转化器,你可以把response返回的数据设置成很多格式,上面的代码里,我设置返回的数据自动转化成gson,除此之外,你还可以设置:
Gson: com.squareup.retrofit:converter-gson

Jackson: com.squareup.retrofit:converter-jackson

Moshi: com.squareup.retrofit:converter-moshi

Protobuf: com.squareup.retrofit:converter-protobuf

Wire: com.squareup.retrofit:converter-wire

Simple XML: com.squareup.retrofit:converter-simplexml

有上面两个方法后,我们还需要声明一个接口,用来存放各种请求和对应的参数:

public interface UserAPIService {
    @GET("user")
    Call<UserBean> getUserInfo(@Query("token") String token);
}

比如,你现在的接口是www.baidu.com/user?token=xxx,这是一个get请求,那么首先你应该用@GET(“user”)来表明我们要发起的是一个get请求,它的地址是user(www.baidu.com我们已经用baseUrl方法定义过了)
然后我们要定义一个方法用来请求数据,这个方法名随意,这里我们叫getUserInfo
注意这个方法的返回值是固定格式的,它一定是Call<T>, 因为我们之前设置过用gson来解析数据,所以这里T不能是一个基本类型或者String之类的,它应该是一个bean。
然后看它的参数@Query(“token”) String token,这里get最基础的参数,类似www.baidu.com/user?token=xxx这种的我们可以用@Query来表示,除此之外,它还支持:

@Path:如果我们地址中某个路径是动态的,类似下面:

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

@QueryMap:一些复杂的参数,你可以通过map传进来

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

post请求可以用@Body

@POST("users/new")
Call<User> createUser(@Body User user);

这样,对应的接口,返回的数据结构,需要的参数,我们都定义好了。
剩下的就是调用了:

//创建一个UserAPIService的call,然后调用对应的请求
Call<UserBean> call = appRetrofit.create(UserAPIService.class).getUserInfo(token);

//enqueue用来设置一个回调Callback,你可以在Callback里面处理返回的数据,Callback运行在主线程
call.enqueue(new Callback<UserBean>() {
    @Override
    public void onResponse(Response<UserBean> response) {
        //TODO 处理返回的数据,显示在UI中
    }

    @Override
    public void onFailure(Throwable t) {
        //获取失败的逻辑
    }
});

上面的enqueue方法,我们也可以不写,而是在UserAPIService指定一个CallBack,这样的话,UserAPIService就是下面这样:

public interface UserAPIService {
    @GET("user")
    Call<UserBean> getUserInfo(@Query("token") String token, CallBack<UserBean> callBack);
}

那就不需要enqueue了,而是:

//创建一个UserAPIService的call,然后调用对应的请求
Call<UserBean> call = appRetrofit.create(UserAPIService.class).getUserInfo(token, new Callback<UserBean>() {
    @Override
    public void onResponse(Response<UserBean> response) {
        //TODO 处理返回的数据,显示在UI中
    }

    @Override
    public void onFailure(Throwable t) {
        //获取失败的逻辑
    }
});

看起来更简洁了。

以上就是Retrofit的使用教程,相信你很快也可以搭建出来一个基于Retrofit的工程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值