Retrofit是Square开发的一个用于网络请求的开源库,内部封装了okhttp,并且和RxAndroid完美的兼容,使得Android的开发效率增加不少的同时也使代码变得清晰易读。
retrofit可以很方便的使用Maven和Gradle依赖,在1.x时retrofit默认是没有引入okhttp作为http client,需要手动的依赖。但是2.0版本已经将okhttp作为retrofit的默认http client,引入retrofit2只需要在gradle中配置
compile 'com.squareup.retrofit2:retrofit:2.0.0'
如果你不想使用retrofit2中自带的okhttp,你也可以导入你自己的okhttp,为了避免导入冲突可以按下面的依赖:
compile ('com.squareup.retrofit2:retrofit:2.0.0') {
exclude module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.2.0'
retrofit2默认没有导入gson,需要gson作为转换器:
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
与RxAndroid使用需要依赖:
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'
compile 'io.reactivex:rxandroid:1.0.1'
Http Get请求参数:
@GET("group/users")
Call> groupList(@Query("id") int groupId)
;
等同于
@GET("group/users?id=groupId")
多个请求参数
@GET("group/{id}/users")
Call<List> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
用于Post方式传递参数,需要在请求接口方法上添加@FormUrlEncoded,表示以表单的方式传递参数
@FormUrlEncoded
@POST("user/edit")
Call updateUser(@Field("first_name") String first, @Field("last_name") String last) ;
用于URL占位符
@GET("group/{id}/users")
Call> groupList(@Path("id") int groupId)
;
添加http header
@GET("user")
Call getUser(@Header("Authorization") String authorization)
请求体,对象会被自动转化成Json格式
@POST("users/new")
Call<User> createUser(@Body User user);
retrofit2默认的集成了okhttp, okhttp可以设置拦截器,比如个请求添加统一的Header
httpClient.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder().addHeader("Accept", "application/json");
Request request1 = requestBuilder.build();
return chain.proceed(request);
}
});
如果有很多默认的参数需要每次添加时:
@FormUrlEncoded
@POST("/feedback")
Call sendFeedbackSimple(
@Field("osName") String osName,
@Field("osVersion") int osVersion,
@Field("device") String device,
@Field("message") String message,
@Field("userIsATalker") Boolean userIsATalker) ;
private void sendFeedbackFormSimple(@NonNull String message) {
// create the service to make the call, see first Retrofit blog post
FeedbackService taskService = ServiceGenerator.create(FeedbackService.class);
// create flag if message is especially long
boolean userIsATalker = (message.length() > 200);
Call call = taskService.sendFeedbackSimple(
"Android",
android.os.Build.VERSION.SDK_INT,
Build.MODEL,
message,
userIsATalker
);
call.enqueue(new Callback() {
...
});
}
可以写成下面的形式:
@POST("/feedback")
Call sendFeedbackConstant(@Body UserFeedback feedbackObject);
public class UserFeedback {
private String osName = "Android";
private int osVersion = android.os.Build.VERSION.SDK_INT;
private String device = Build.MODEL;
private String message;
private boolean userIsATalker;
public UserFeedback(String message) {
this.message = message;
this.userIsATalker = (message.length() > 200);
}
// getters & setters
// ...
}
private void sendFeedbackFormAdvanced(@NonNull String message) {
FeedbackService taskService = ServiceGenerator.create(FeedbackService.class);
Call call = taskService.sendFeedbackConstant(new UserFeedback(message));
call.enqueue(new Callback() {
...
});
}
首先创建一个工厂类根据不通的api interface 创建其实现。这个解释起来比较抽象,可以看下面的代码:
/**
* Created by cfp on 16-4-18.
*/
public class RetrofitFactory {
public static final String GITHUB_HTTP_URL = "https://api.github.com";
public static final String OTHER_HTTP_URL = "https://yoursite";
//默认超时时间
private final static int DEFAULT_TIMEOUT = 5;
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder githubBuilder = new Retrofit.Builder()
.baseUrl(GITHUB_HTTP_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit.Builder otherBuilder = new Retrofit.Builder()
.baseUrl(OTHER_HTTP_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create());
/**
* 为了防止一个类里放置所有的api,可以根据程序的功能分成不通的模块,把他们存在map中
*/
private static Map, Object> githubApiMap = new HashMap, Object>();
private static Map, Object> otherApiMap = new HashMap, Object>();
/**
* 默认的server为github
*
* @param instanceClass
* @param
* @return
*/
public synchronized static S getInstance(Class instanceClass) {
return getInstance(GITHUB_HTTP_URL, instanceClass);
}
public RetrofitFactory() {
}
public synchronized static S getInstance(String server, Class instanceClass) {
final Retrofit retrofit;
switch (server) {
case GITHUB_HTTP_URL:
if (githubApiMap.containsKey(instanceClass)) {
return (S) githubApiMap.get(instanceClass);
} else {
//添加拦截器,可以给请求添加header
httpClient.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request origin = chain.request();
Request.Builder requestBuilder = origin.newBuilder()
.addHeader("devicetype", "ANDROID");
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
retrofit = githubBuilder.client(httpClient.build()).build();
S instance = retrofit.create(instanceClass);
githubApiMap.put(instanceClass, instance);
return instance;
}
case OTHER_HTTP_URL:
if (otherApiMap.containsKey(instanceClass)) {
return (S) githubApiMap.get(instanceClass);
} else {
retrofit = githubBuilder.client(httpClient.build()).build();
S instance = retrofit.create(instanceClass);
otherApiMap.put(instanceClass, instance);
return instance;
}
default:
return null;
}
}
}
另外就是网络请求的抽象回调类,继承自Subscriber
/**
* 网络请求的回调抽象类
* Created by cfp on 16-5-24.
*/
public abstract class AbsCallBackSubscriber extends Subscriber {
@Override
public void onCompleted() {
//解除注册
if (this.isUnsubscribed()){
this.unsubscribe();
}
onFinish();
}
@Override
public void onError(Throwable e) {
// TODO: 16-5-25 一些错误处理
}
@Override
public void onNext(T t) {
onSuccess(t);
}
public abstract void onFinish();
public abstract void onSuccess(T t);
}
最后是真正的网络请求部分,如果有需求某次请求的错误信息需要单独处理,可以复写
AbsCallBackSubscriber中的onError方法。
RetrofitFactory.getInstance(GithubApi.class).getFollowings(username)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new AbsCallBackSubscriber>() {
@Override
public void onFinish() {
}
@Override
public void onSuccess(List userInfos) {
}
});
最后是接口的interface
/**
* Created by cfp on 16-4-18.
*/
public interface GithubApi {
@GET("/users/{username}")
Observable getUserInfo(@Path("username") String username);
@GET("/users/{username}/following")
Observable> getFollowings(@Path("username") String username);
}
retrofit2 + reAndroid简单的流程用法差不多介绍了,也做了个简单的封装,至于更高级的用法,还需要继续的研究,也希望大家多多交流,指出不足共同进步^v^。
http://www.loongwind.com/archives/242.html
http://xiuweikang.github.io/2016/03/17/Retrofit%E5%88%86%E4%BA%AB/
https://futurestud.io/blog/retrofit-2-upgrade-guide-from-1-9