前几天看了有关Retrofi2t的概念,其实光看概念并不能知道多少。概念是一个抽象的东西,我们初次学习还是要有一步步的使用过程。最近又练了一下基本的用法,把一些东西记录下来,逐步一点点的学习使用。
首先导入依赖:
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
前面了解了创建一个Retrofit2:
retrofit = new Retrofit.Builder()
.baseUrl("http://api.avatardata.cn/")
.build();
baseUrl 就是我们自己api的部分。
定义接口:
interface MobileAddressService {
@GET("MobilePlace/LookUp")
Observable<MobileAddress> getMobileAddress1(@Query("key") String key, @Query("mobileNumber") String mobileNumber);
@GET("MobilePlace/LookUp")
Call<MobileAddress> getMobileAddress2(@Query("key") String key, @Query("mobileNumber") String mobileNumber);
@HTTP(method = "GET",
path = "MobilePlace/LookUp",
hasBody = false)
Observable<MobileAddress> getMobileAddress3(@Query("key") String key, @Query("mobileNumber")String mobileNumber);
}
然后通过Retrofit2的对象获取我们的api接口的对象:
MobileAddressService mobileAddressService = retrofit.create(MobileAddressService.class);
最后,通过这个对象调用我们定义的方法:
Call<MobileAddress> call = mobileAddressService.getMobileAddress1("ec47b85086be4dc8b5d941f5abd37a4e", "13021671512");
call.enqueue(new Callback<MobileAddress>() {
@Override
public void onResponse(Call<MobileAddress> call, Response<MobileAddress> response) {
MobileAddress body = response.body();
if(body!=null){
tvRetrofit.setText("普通调整用方式:"+body.getResult().getMobilearea()+"-"+body.getResult().getMobilenumber());
}
}
@Override
public void onFailure(Call<MobileAddress> call, Throwable t) {
Log.e(TAG,"onFailure:"+t.getMessage());
}
});
这样就完成了基本的使用。这里要注意:call.enqueue(new Callback<MobileAddress>());参数是一个回调,保证请求在子线程中调用。
另一种调用方式:
try {
Response<MobileAddress> execute = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
如果直接更新UI则会报错:
Caused by: android.os.NetworkOnMainThreadException
这里还有一个点没有说: 在开头我们说创建Retrofit2 对象,给的代码是:
retrofit = new Retrofit.Builder()
.baseUrl("http://api.avatardata.cn/")
.build();
其实这是最基本的用法,和上一篇中的使用方式是一样的,这样的用法返回的结果只是一个ResponseBody泛型。这样的结果我还要再去处理一次。这次前面的调用返回的结果是一个MobileAddress,这是我们自己定义的一个javaBean 。可以看到在最初添加依赖的时候有两个其他的,其中compile 'com.squareup.retrofit2:converter-gson:2.3.0'就是将我们结果转换为自定义的MobileAddress的。另一个我们从名称可以知道是和RxJava相关的。所以上面创建Retrofit2 的代码是:
retrofit = new Retrofit.Builder()
.baseUrl("http://api.avatardata.cn/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
下面在看集合RxJava的使用:
结合RxJava可以充分发挥 RxJava和Retrofit2的优势。
结合Retrofit2首先我们接口的返回结果就不是原来的样式:
@GET("MobilePlace/LookUp")
Call<MobileAddress> getMobileAddress1(@Query("key") String key, @Query("mobileNumber") String mobileNumber);
修改为:
@GET("MobilePlace/LookUp")
Observable<MobileAddress> getMobileAddress2(@Query("key") String key, @Query("mobileNumber") String mobileNumber);
返回结果是一个Observable,这样就可以直接使用RxJava的链式操作了。
mobileAddressService.getMobileAddress2("ec47b85086be4dc8b5d941f5abd37a4e", "13021671512")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<MobileAddress>() {
@Override
public void accept(MobileAddress mobileAddress) throws Exception {
if(mobileAddress!=null){
tvRetrofit.setText("结果是:"+mobileAddress.getResult().getMobilearea()+"-"+mobileAddress.getResult().getAreacode());
}
Log.e("TAG", "accept1:" + mobileAddress.getError_code());
Log.e("TAG", "accept2:" + mobileAddress.getResult().getMobilearea());
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e("TAG", "throwable:" + throwable.getMessage());
}
});
上面使用RxJava 的链式操作,在io线程执行方法,最后切换到AndroidSchedulers.mainThread() 后更新UI。代码的确看起来舒服多了。对于RxJava 的用法,需要的话就要自己学学了。自己正在学习使用,还没来得及总结。
这样就完整的完成了一次Retrofit2 的使用。
采用@path注释的方式请求:@path方式定义一个请求,只是定义接口的部分有区别,调用接口方法的部分和上述一样。
有一点说明,这次使用的接口是:
http://api.avatardata.cn/MobilePlace/LookUp?key=ec47b85086be4dc8b5d941f5abd37a4e&mobileNumber=13021671512
这是一种传统接口调用,Retrofit2最方便使用的是
RESTful 形式的接口,这里我们能看到,我们在baseUrl中写了http://api.avatardata.cn/,然后在api接口的
注解中使用了:
@GET("MobilePlace/LookUp")
Observable<MobileAddress> getMobileAddress2(@Query("key") String key, @Query("mobileNumber") String mobileNumber);
我们自己只是把需要的参数传递到方法中,Retrofit2帮我们把参数进行了拼接。也达到了同样的效果。
对于接口的定义还有一点,Retrofit 都采用注解的方式来定义Http请求的。对应:@GET、@POST、@PUT、@DELETE、@HEAD,分别对应 HTTP中的网络请求方式。有一个@HTTP 这是用来替换@GET、@POST、@DELETE、@HEAD 操作的。具体使用的过程通过method、path、hasBody来设置@HTTP(method="GET",path = "path",hasBody = "false"),其中method 表示请求方式,path 是请求的路径,hasBody 表示是否有请求体。
由于目前没有相关post方式的接口,后续再继续学习研究Retrofit2的post相关用法。