Retrofit是是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可,大量的app都采用OkHttp做网络请求,其源码详见OkHttp Github。
compile 'com.google.code.gson:gson:2.6.2' compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2' compile 'io.reactivex:rxjava:1.1.0' compile 'io.reactivex:rxandroid:1.1.0'
这样就将Retrofit+RxJava引入进来了
<uses-permission android:name="android.permission.INTERNET" />
①这是get方法,一会在RetrofitBase中调用
@GET Observable<JSONObject> getData( @Url String url, @QueryMap Map<String, Object> params);
②这是post方法,一会在RetrofitBase中调用
@FormUrlEncoded @POST Observable<JSONObject> postData( @Url String url, @FieldMap Map<String, Object> params);
③这是上传文件的方法
有两种写法:使用@MultiPart注解,@Part注解文件入参,则文件入参类型应是List< okhttp3.MultipartBody.Part>;
不使用@Multipart注解,直接使用@Body注解文件入参,则文件入参类型应是okhttp3.MultipartBody
@Multipart @POST Observable<JSONObject> uploadFiles( @Url String url, @PartMap() Map<String, RequestBody> strParams, @Part() List<MultipartBody.Part> fileParams);
全局参数:
private static final String TAG = RetrofitBase.class.getSimpleName(); protected static String BASEURL = Config.SERVER_ADDRESS; private static final long TIMEOUT = 5 * 1000; private FactoryInters service; private Retrofit retrofit; private Gson gson; private JsonParser jsonParser;
初始化
private RetrofitBase() { retrofit = new Retrofit.Builder() .baseUrl(BASEURL) .client(client()) //增加返回值为Gson的支持(自定义MyGsonConverterFactory) .addConverterFactory(MyGsonConverterFactory.create()) //增加返回值为Oservable<T>的支持 .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); service = retrofit.create(FactoryInters.class); gson = new GsonBuilder().setPrettyPrinting().create(); jsonParser = new JsonParser(); } private static class SingletonHolder { private static final RetrofitBase INSTENCE = new RetrofitBase(); } public static RetrofitBase getInstance() { return SingletonHolder.INSTENCE; }获得连接
private OkHttpClient client() { LauncherTrust launcherTrust = new LauncherTrust(); OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS) .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS) .sslSocketFactory(sslSocketFactory(launcherTrust), launcherTrust) .hostnameVerifier(new AllowAllHostnameVerifier()) .addInterceptor(interceptor) .retryOnConnectionFailure(false)//失败重连 .build(); return okHttpClient; } private SSLSocketFactory sslSocketFactory(LauncherTrust launcherTrust) { try { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{launcherTrust}, new SecureRandom()); return sslContext.getSocketFactory(); } catch (NoSuchAlgorithmException | KeyManagementException e) { e.printStackTrace(); } return null; } static class LauncherTrust implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } LogInterceptor interceptor = new LogInterceptor(new LogInterceptor.Logger() { @Override public void log(String message) { Log.i(TAG, message); } });重点!!!
get方法
public void getData(String url, Map<String, Object> params, SubListenerHelper listener) { Log.d(TAG, "[get请求参数] = \n" + gson.toJson(jsonParser.parse(gson.toJson(params)))); service.getData(url, params) .compose(schedulersTransformer()) .subscribe(listener); }post方法
public void postData(String url, Map<String, Object> params, SubListenerHelper listener) { Log.d(TAG, "[post请求参数] = \n" + gson.toJson(jsonParser.parse(gson.toJson(params)))); service.postData(url, params) .compose(schedulersTransformer()) .subscribe(listener); }上传文件
public void uploadFiles(String url, Map<String, RequestBody> strParams, List<MultipartBody.Part> fileParams, SubListenerHelper subscriberHelper) { service.uploadFiles(url, strParams, fileParams) .compose(schedulersTransformer()) .subscribe(subscriberHelper); }
Observable
Observable.Transformer schedulersTransformer() { return new Observable.Transformer() { @Override public Object call(Object observable) { return ((Observable) observable) .subscribeOn(Schedulers.io())//执行在io线程 .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread());//主线程显示 } }; }
上传文件时将map转成List
public static List<MultipartBody.Part> fileList2PartList(Map<String, File> fileMap) { List<MultipartBody.Part> partList = new ArrayList<>(fileMap.size()); for (Map.Entry<String, File> entry : fileMap.entrySet()) { String fileKey = entry.getKey(); File file = entry.getValue(); RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file); MultipartBody.Part part = MultipartBody.Part.createFormData(fileKey, file.getName(), requestBody); partList.add(part); } return partList; }
public class MyGsonConverterFactory extends Converter.Factory { private static final String TAG = MyGsonConverterFactory.class.getSimpleName(); private final Gson gson; public static MyGsonConverterFactory create() { return create(new Gson()); } public static MyGsonConverterFactory create(Gson gson) { return new MyGsonConverterFactory(gson); } private MyGsonConverterFactory(Gson gson) { if (gson == null) throw new NullPointerException("gson == null"); this.gson = gson; } /** * 响应 * * @param type * @param annotations * @param retrofit * @return */ @Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); Log.i(TAG, "responseBodyConverter"); return new JsonResponseBodyConverter(gson, adapter); } /** * 请求 * * @param type * @param parameterAnnotations * @param methodAnnotations * @param retrofit * @return */ @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); Log.i(TAG, "requestBodyConverter"); return new JsonRequestBodyConverter<>(gson, adapter); //请求 } }
public class JsonRequestBodyConverter<T> implements Converter<T, RequestBody> { private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); private static final String TAG = JsonRequestBodyConverter.class.getSimpleName(); private Gson gson; private TypeAdapter<T> adapter; public JsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public RequestBody convert(T value) throws IOException { Log.i(TAG, "convert(T value)"); String result = URLEncoder.encode(EncryptUtil.encryptByPublicKey(value.toString()), "utf-8"); String postBody = gson.toJson(result); //对象转化成json Log.i(TAG, "转化后的数据:" + postBody); return RequestBody.create(MEDIA_TYPE, postBody); } }
public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { private static final String TAG = JsonResponseBodyConverter.class.getSimpleName(); private final Gson mGson;//gson对象 private final TypeAdapter<JSONObject> adapter; public JsonResponseBodyConverter(Gson gson, TypeAdapter<JSONObject> adapter) { this.mGson = gson; this.adapter = adapter; } @Override public T convert(ResponseBody responseBody) throws IOException { Log.i(TAG, "ResponseBody"); String responseString = responseBody.string(); String result = EncryptUtil.decryptByPublicKey(responseString);//解密 Log.i(TAG, "解密的服务器数据:" + result); JSONObject data = null; try { data = new JSONObject(result); } catch (JSONException e) { Log.i(TAG, "e:" + e); e.printStackTrace(); } return (T) data; } }
public abstract class SubListenerHelper extends Subscriber<JSONObject> { private static final String TAG = SubListenerHelper.class.getSimpleName(); private boolean toastInfo = false; public abstract void onSuccess(JSONObject oriData, ServerResponse response); public abstract void onFailure(Throwable e); public abstract void onFinish(); @Override public void onNext(JSONObject data) { ServerResponse response = ServerResponse.parseFromVolleyResponse(data); Log.i(TAG, "onNext data=" + data); //提示信息 if (!response.isSuccess) { if (toastInfo) { //如果服务器返回的status状态不为1,就弹出服务器给的吐司 if (!TextUtils.isEmpty(response.msg)) { Toast.makeText(AppContext.getContext(), response.msg, Toast.LENGTH_SHORT).show(); } else if (!TextUtils.isEmpty(response.error)) { Toast.makeText(AppContext.getContext(), response.error, Toast.LENGTH_SHORT).show(); } } } if (null != response) { onSuccess(data, response); } } @Override public void onError(Throwable e) { Log.i(TAG, "onError e=" + e); onFailure(e); } @Override public void onCompleted() { onFinish(); } public SubListenerHelper setToastInfo(boolean toastInfo) { this.toastInfo = toastInfo; return this; } }
解析统一的格式
{"error":"E00000000","msg":"成功(没有异常)","status":"1"}
这是我的返回格式,不同格式可根据需求改代码
public class ServerResponse { public static final int STATUS_SUCCESS = 1; public boolean isSuccess; public JSONObject data; public String error; public String msg; public int status; //对网络返回的json数据进行解析 public static ServerResponse parseFromVolleyResponse(JSONObject object) { ServerResponse result = new ServerResponse(); if (object != null) { result.status = object.optInt("status"); result.isSuccess = result.status == STATUS_SUCCESS; result.error = object.optString("error"); result.msg = object.optString("msg"); //如果是数据就不能用result.data----object result.data = object.optJSONObject("data"); } return result; } @Override public String toString() { return "ServerResponse{" + "data=" + data + ", error='" + error + '\'' + ", msg='" + msg + '\'' + ", status=" + status + '}'; } }