Retrofit可以简单分成三部分:RetrofitClient,RetrofitApi,RetrofitService。
第一部分api接口,可以根据个人需要灵活定制,我这里用url注解原因在于需动态改变请求的baseUrl,
网上改变baseUrl的方法有几种,我这种属于民间,比较方便的一种。
interface RetrofitApi {
//不带参Get
@GET
Observable<String> requestGet(@Url String url);
//带参Get
@GET
Observable<String> requestGet(@Url String url, @QueryMap HashMap<String,Object> map);
//不带参Post
@POST
Observable<String> requestPost(@Url String url);
//带参Post
@POST
Observable<String> requestPost(@Url String url, @Body RequestBody requestBody);
//表单Post
@FormUrlEncoded
@POST
Observable<String> requestFormPost(@Url String url,@FieldMap HashMap<String,Object> map);
//上传
@Multipart
@POST
Observable<String> upload(@Url String url, @Part MultipartBody.Part part);
//下载
@GET
Observable<ResponseBody> download(@Url String url);
//下载
@GET
Observable<ResponseBody> download(@Url String url,@QueryMap Map<String,Object> map);
}
第二部分是RetrofitClient,获取Retrofit对象,以及配置一些参数,比如
baseUrl OkHttpClient addCallAdapterFactory addConverterFactory等
class RetrofitClient {
private static Retrofit retrofit;
public synchronized static Retrofit getInstance(){
if(retrofit==null){
retrofit = new Retrofit.Builder()
.baseUrl("https://www.ihr360.com/api/")
.client( new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(new HeaderInterceptor())
.addInterceptor(new LogInterceptor())
.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(ConverterFactory.create())
.build();
}
return retrofit;
}
}
当然这里有一些配置,比如OkHttpClient的Interceptor,这里只举一个例子
public class LogInterceptor implements Interceptor {
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request();
//url
HttpUrl url = request.url();
//request.headers
Headers headers = request.headers();
LogUtil.i(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
LogUtil.i(url.toString()+" 请求方式:"+request.method());
LogUtil.i(url.toString()+" 请求header:"+headers.toString());
//requestBody
RequestBody requestBody= request.body();
if(requestBody!=null){
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
String paramsStr = buffer.readUtf8();
LogUtil.i(url.toString()+" 请求body:"+paramsStr);
}else {
LogUtil.i(url.toString()+" 请求body: {}");
}
//response
Response response = chain.proceed(request);
if(response!=null){
//response.headers
Headers responseHeaders = response.headers();
HttpUrl url2 = response.request().url();
LogUtil.i(url2.toString()+" 返回header:"+responseHeaders.toString());
//responseBody
String responseBody = response.peekBody(1024 * 1024).string();
LogUtil.i(url2.toString()+" 返回body:"+responseBody);
}else {
LogUtil.i(url.toString()+" 返回body is empty");
}
LogUtil.i("=======================================================");
return response;
}
}
最后是我们真正调用的RetrofitService。
public class RetrofitService {
protected static RetrofitApi retrofitApi;
public static RetrofitService getInstance() {
if(retrofitApi ==null){
retrofitApi = RetrofitClient.getInstance().create(RetrofitApi.class);
}
return new RetrofitService();
}
//不带参Get
public void requestGet(String path,CallBack<String> callBack){
handString(retrofitApi.requestGet(path),callBack);
}
//带参Get
public void requestGet(String path, HashMap<String,Object> map, CallBack<String> callBack){
handString(retrofitApi.requestGet(path,map),callBack);
}
//不带参Post
public void requestPost(String path,CallBack<String> callBack){
handString(retrofitApi.requestPost(path),callBack);
}
//带参Post
public void requestPost(String path, @NonNull HashMap<String,Object> map, CallBack<String> callBack){
JSONObject json = new JSONObject();
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String, Object> entry:entries){
json.put(entry.getKey(),entry.getValue());
}
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toJSONString());
handString(retrofitApi.requestPost(path,requestBody),callBack);
}
//表单Post
public void requestFormPost(String path,@NonNull HashMap<String,Object> map,CallBack<String> callBack){
handString(retrofitApi.requestFormPost(path,map),callBack);
}
//上传文件
public void uploadFile(String path, File file, CallBack<String> callBack){
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
handString(retrofitApi.upload(path,part),callBack);
}
//下载文件
public void downloadFile(final String url,String fileName, final CallBack<File> callBack){
handFile(retrofitApi.download(url),fileName,callBack);
}
//上传图片
public void uploadImage(String path, File file, CallBack<String> callBack){
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
handString(retrofitApi.upload(path,part),callBack);
}
//下载无缓存图片
public void downloadImage(final String url, final CallBack<Bitmap> callBack){
handBitmap(retrofitApi.download(url),callBack);
}
//下载无缓存图片
public void downloadImage(final String url, Map<String,Object> map, final CallBack<Bitmap> callBack){
handBitmap(retrofitApi.download(url,map),callBack);
}
private void handFile(Observable<ResponseBody> observable, final String fileName, final CallBack<File> callBack) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws Exception {
InputStream is = responseBody.byteStream();
File file = new File(DeviceUtil.getSaveFilePath()+fileName);
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
long progress = 0;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
fos.flush();
progress +=len;
callBack.onProgress(progress/responseBody.contentLength());
}
fos.close();
bis.close();
is.close();
callBack.onResponse(file);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
callBack.onError(throwable);
}
});
}
private void handBitmap(Observable<ResponseBody> observable, final CallBack<Bitmap> callBack) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws Exception {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeStream(responseBody.byteStream(), null, options);
callBack.onResponse(bitmap);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
callBack.onError(throwable);
}
});
}
private void handString(Observable<String> observable, final CallBack<String> callBack){
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String string) throws Exception {
//以前的code
String responseCode = HttpParseUtil.parseString(string, "responseCode");
String error = HttpParseUtil.parseString(string, "error");
String errorMessage = HttpParseUtil.parseString(error, "message");
//后来约定的code
int code = HttpParseUtil.parseIntValue(string, "code");
String message = HttpParseUtil.parseString(string, "message");
if(code==4||"4".equals(responseCode)){
Intent intent = new Intent(PersonnelTreasureApplication.getInstance(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PersonnelTreasureApplication.getInstance().startActivity(intent);
callBack.onError(new Throwable(message));
}else if(code!=0){
callBack.onError(new Throwable(message));
}else if(CheckUtils.isNotEmpty(responseCode)&&!"0".equals(responseCode)){
callBack.onError(new Throwable(errorMessage));
}else {
callBack.onResponse(string);
}
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if(throwable instanceof HttpException) {
HttpException httpException = (HttpException) throwable;
if(httpException.code()==401){
Intent intent = new Intent(PersonnelTreasureApplication.getInstance(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PersonnelTreasureApplication.getInstance().startActivity(intent);
}
}
callBack.onError(throwable);
}
});
}
}
到这里就可以调用请求了,最后怎么改变baseUrl呢。首先第一种,静态改变baseUrl.
public class RetrofitServiceAccount extends RetrofitService {
public static final String baseUrl = "https://passport.ihr360.com/ac/";
public static RetrofitServiceAccount getInstance() {
if(retrofitApi ==null){
retrofitApi = RetrofitClient.getInstance().create(RetrofitApi.class);
}
return new RetrofitServiceAccount();
}
@Override
public void requestGet(String path, CallBack<String> callBack) {
super.requestGet(baseUrl+path, callBack);
}
@Override
public void requestGet(String path, HashMap<String, Object> map, CallBack<String> callBack) {
super.requestGet(baseUrl+path, map, callBack);
}
@Override
public void requestPost(String path, CallBack<String> callBack) {
super.requestPost(baseUrl+path, callBack);
}
@Override
public void requestPost(String path, HashMap<String, Object> map, CallBack<String> callBack) {
super.requestPost(baseUrl+path, map, callBack);
}
@Override
public void uploadFile(String path, File file, CallBack<String> callBack) {
super.uploadFile(baseUrl+path, file, callBack);
}
@Override
public void downloadFile(String url, String fileName, CallBack<File> callBack) {
super.downloadFile(baseUrl+url, fileName, callBack);
}
@Override
public void uploadImage(String path, File file, CallBack<String> callBack) {
super.uploadImage(baseUrl+path, file, callBack);
}
@Override
public void downloadImage(String url, CallBack<Bitmap> callBack) {
super.downloadImage(baseUrl+url, callBack);
}
@Override
public void downloadImage(String url, Map<String, Object> map, CallBack<Bitmap> callBack) {
super.downloadImage(baseUrl+url, map, callBack);
}
}
有时候还要动态改变baseurl,而且是服务端传过来的,没办法写死怎么办呢。一样的道理,先存起来,然后去取就行了。
public class RetrofitServiceBase extends RetrofitService{
public static RetrofitServiceBase getInstance() {
if(retrofitApi ==null){
retrofitApi = RetrofitClient.getInstance().create(RetrofitApi.class);
}
return new RetrofitServiceBase();
}
@Override
public void requestGet(String path, CallBack<String> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.requestGet(baseUrl+path, callBack);
}
@Override
public void requestGet(String path, HashMap<String, Object> map, CallBack<String> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.requestGet(baseUrl+path, map, callBack);
}
@Override
public void requestPost(String path, CallBack<String> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.requestPost(baseUrl+path, callBack);
}
@Override
public void requestPost(String path, HashMap<String, Object> map, CallBack<String> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.requestPost(baseUrl+path, map, callBack);
}
@Override
public void uploadFile(String path, File file, CallBack<String> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.uploadFile(baseUrl+path, file, callBack);
}
@Override
public void downloadFile(String url, String fileName, CallBack<File> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.downloadFile(baseUrl+url, fileName, callBack);
}
@Override
public void uploadImage(String path, File file, CallBack<String> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.uploadImage(baseUrl+path, file, callBack);
}
@Override
public void downloadImage(String url, CallBack<Bitmap> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.downloadImage(baseUrl+url, callBack);
}
@Override
public void downloadImage(String url, Map<String, Object> map, CallBack<Bitmap> callBack) {
String baseUrl = SharedPreferencesHelper.getInstance().getBaseUrl();
super.downloadImage(baseUrl+url, map, callBack);
}
}