您的位置:首页 > 移动开发 > Android开发

Android 中 Retrofit 结合 RxJava使用

2016-08-30 12:13 567 查看


Retrofit 简单使用

Retrofit 目前最新版本是 2.0.0-beta4 ,相比于 1.x 版本,一些 api 有较大变动,因此建议直接通过官方文档和示例进行学习,下面是一个比较基础的 Retrofit 使用示例


添加依赖

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'


一般使用 Retrofit 会将 json 数据直接解析转换成 java 对象,因此需要用到 json 解析库作为转换器,官方提供了一些常用的 json 解析库的支持,详情可以在 Retrofit官网 了解到,这里我使用了 Gson 作为转换器。


编写 API

Retrofit 使用注解绑定 URL 链接,这里我直接使用官方例子中的 URL 来做演示,完整链接是:https://api.github.com/repos/square/retrofit/contributors 通过浏览器打开这个链接可以看到一串
json 数据,下面就根据这个 URL 来编写一个 接口
public interface GitHub {

@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(@Path("owner") String owner,@Path("repo") String repo);
}


简单分析下这段代码

首先创建了一个接口类 GitHub.java,然后在其中定义了一个方法 contributors()

注解 @GET 表示通过 GET 方式访问这个链接,后面是一个需要根据不同 owner 和 repo 来构造的 URL路径,因为主站的地址往往是不变的,比如 https://api.github.com/ 这个是固定的,称为 EndPoint,可以统一指定,所以这里只需要要变动的 URL 路径。这里需要根据不同的 owner 和 repo 来构造不同的 URL,所以用括号 {} 表示这是一个参数,需要通过 contributors
方法的参数来确定,Retrofit 还提供了很多不同的注解,比如使用 POST 方式的 @POST,或者添加请求头的 @Headers,详情参见官网

第一个参数是 String 类型的 owner,对应 URL 链接中的 {owner},也就是说,在使用这个方法时传入的参数 owner 最终会被用来替换到链接中的 {owner} 从而构造制定的 URL,同理,另一个参数就不解释了

返回类型是 Call< List< Contributor > >,注意这里的 List < Contributor > 是一个 Contributor 类型的集合,Contributor.java 是自定义的 javabean 类,也就是 json 数据转换成的 java 对象的类型,下面会讲到 Contributor 类的编写。


编写模型

因为这里使用了 github 的 json 数据,所以先看看返回的数据具有哪些属性: 



可以看到,这里返回的是一个 json 数组,单个 json 对象中包含许多属性,这里为了简便,只选用其中几个属性做演示,写出来的 Contributor.java 类如下:
public class Contributor {
private String login;
private int id;
private int contributions;

public Contributor(String login, int id, int contributions) {
this.login = login;
this.id = id;
this.contributions = contributions;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getContributions() {
return contributions;
}

public void setContributions(int contributions) {
this.contributions = contributions;
}
}


网络请求

在 AndroidManifest.xml 文件中添加网络权限
<uses-permission android:name="android.permission.Internet"/>

Android 中网络请求不能在主线程中进行,因此新建一个线程类来执行网络请求:
private class Simple extends Thread{

@Override
public void run() {
super.run();

Retrofit retrofit=new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())//添加 Gson 转换器
.build();

GitHub gitHub=retrofit.create(GitHub.class);

Call<List<Contributor>> call=gitHub.contributors("square", "retrofit");

try {
List<Contributor> list=call.execute().body();
for (Contributor c:list){
Log.i("TAG",c.getLogin()+"  "+c.getId()+"  "+c.getContributions());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
上面这段代码很简单,就不做解释。运行效果如下图: 



可见,通过这些代码,就完成了网络请求和数据转换,使用起来是相当方便快捷。关于 Retrofit 更详细的使用方法,可以参考 Retrofit 使用示例


Retrofit 结合 RxJava 使用

RxJava 的概念和基础使用就不多讲,参考 文章开始处提到的文章就够了,这里主要介绍 Retrofit 和 RxJava 结合使用。

在上面 Retrofit 简单使用的实例中,网络请求时 ,因为 Android 中网络请求不能在主线程中进行,因此需要异步操作,而单纯使用 Retrofit 的话,就需要新建线程或使用 AsyncTask 来异步执行,这样的话就会很麻烦。因此,使用 RxJava 来解决异步的问题,下面的实例是对 Retrofit 使用示例的改进,将异步操作用 RxJava 来实现


添加依赖

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'

compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'

compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'


以上这几个是必备的依赖,前两个是 Retrofit 和 Gson 的依赖,第三个是 Retrofit 中 RxJava 转换器的依赖,最后两个就是 RxJava 和 Rx Android 的依赖


编写 API

使用 RxJava 的情况下,接口文件稍有修改,接口中的方法的返回类型不再是 Call 而是 Observable 类型:
public interface GitHub {

@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(@Path("owner") String owner,@Path("repo") String repo);

//使用 RxJava 的方法,返回一个 Observable
@GET("/repos/{owner}/{repo}/contributors")
Observable<List<Contributor>> RxContributors(@Path("owner") String owner,@Path("repo") String repo);
}


结合 RxJava 使用的 接口就定义好了,模型类不需要变动,接下来直接进行网络请求


网络请求

使用 RxJava 的 Retrofit 可以直接在 主线程中编写,而不需要像上面那样新建线程了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Retrofit retrofit=new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())//添加 json 转换器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加 RxJava 适配器
.build();

GitHub gitHub=retrofit.create(GitHub.class);
gitHub.RxContributors("square","retrofit")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Contributor>>() {
@Override
public void onCompleted() {
Log.i("TAG","onCompleted");
}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(List<Contributor> contributors) {
for (Contributor c:contributors){
Log.i("TAG","RxJava-->"+c.getLogin()+"  "+c.getId()+"  "+c.getContributions());
}
}
});
}


可以看到,上面的代码是在 onCreate() 方法中运行的,在创建Retrofit 实例时指定了 json 转换器和RxJava 适配器。在执行接口中的 RxContributors() 方法时指定了在 io 线程进行网络操作,并在主线程返回结果,使用起来相当方便,运行效果如下图: 

打印同上
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: