Android 网络请求之Retrofit
2021-07-08 本文已影响0人
xulj100
前言
Retrofit是一个RESTful的Http网络请求框架的封装。注意这里并没有说它是网络请求框架,主要原因在于网络请求的工作并不是Retrofit来完成的。
Retrofit 2.0开始内置OkHttp,前者专注于接口的封装,后者专注于网络请求的高效,二者分工协作。
使用步骤
1、 添加Retrofit库的依赖
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
2、创建 用于描述网络请求 的接口
public interface ApiService {
String HOST = "http://www.wanandroid.com";
@GET("banner/json")
Observable<BannerEntity> getBannerList();
@GET("article/list/{page}/json")
Observable<HomeEntity> getHomePageList(@Path("page") int page);
}
3、创建Retrofit实例
public class RetrofitHelper {
private ApiService apiService;
private static final int DEFAULT_TIMEOUT = 20;
private volatile static RetrofitHelper instance = null;
private Retrofit.Builder builder;
public static RetrofitHelper getInstance() {
if (instance == null) {
synchronized (RetrofitHelper.class) {
if (instance == null)
instance = new RetrofitHelper();
}
}
return instance;
}
private RetrofitHelper() {
builder = new Retrofit.Builder();
}
private OkHttpClient getClient() {
String PATH_DATA = BaseApplication.getInstance().getCacheDir().getAbsolutePath() + File.separator + "data";
String PATH_CACHE = PATH_DATA + "/NetCache";
File cacheFile = new File(PATH_CACHE);
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.addNetworkInterceptor(getInterceptor());
builder.addInterceptor(getInterceptor());
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(loggingInterceptor);
builder.cache(cache);
//设置超时
builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
//错误重连
builder.retryOnConnectionFailure(true);
//cookie认证
builder.cookieJar(new CookiesManager());
return builder.build();
}
private Interceptor getInterceptor() {
Interceptor cacheInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!CommonUtils.isNetworkConnected()) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (CommonUtils.isNetworkConnected()) {
int maxAge = 0;
// 有网络时, 不缓存, 最大保存时长为0
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Pragma")
.build();
} else {
// 无网络时,设置超时为4周
int maxStale = 60 * 60 * 24 * 28;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
}
return response;
}
};
return cacheInterceptor;
}
public ApiService getApiService(String url) {
builder.baseUrl(url)
.client(getClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
apiService = builder.build().create(ApiService.class);
return apiService;
}
private HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Logger.d("net log ==", message);
}
});
}
4、发送请求
RetrofitHelper.getInstance().getApiService(Constants.ANDROID_URL).bannerList
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<BannerEntity>() {
override fun onSuccess(bean: BannerEntity) {
if (bean.errorCode == 0) {
mView?.setBanner(bean)
}
}
override fun onFail(e: Throwable) {
Log.e(tag, e.message)
}
})
public abstract class BaseObserver<T> implements Observer<T> {
public abstract void onSuccess(T t);
public abstract void onFail(Throwable e);
@Override
public void onSubscribe(@NonNull Disposable d) {}
@Override
public void onNext(@NonNull T t) {
onSuccess(t);
}
@Override
public void onError(@NonNull Throwable e) {
onFail(e);
}
@Override
public void onComplete() {
}
}