Android网络编程Retrofit+Rxjava用法详解

xiaoxiao2021-02-28  135

一.简介

Retrofit是是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可,大量的app都采用OkHttp做网络请求,其源码详见OkHttp Github。

 

二.贴代码

1.首先在gradle中添加如下配置

 

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引入进来了

 

2.在manifest中添加网络权限

 

<uses-permission android:name="android.permission.INTERNET" />

 

3.写个接口FactoryInters,用来封装get post方法

①这是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);

 

4.新建类RetrofitBase,用来具体实现get post方法

全局参数:

 

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; }

4.LogInterceptor类

public class LogInterceptor implements Interceptor { private static final Charset UTF8 = Charset.forName("UTF-8"); public enum Level { NONE, BASIC, HEADERS, BODY } public interface Logger { void log(String message); int INFO = 800; Logger DEFAULT = new Logger() { @Override public void log(String message) { Platform.get().log(INFO, message, null); } }; } public LogInterceptor() { this(Logger.DEFAULT); } public LogInterceptor(Logger logger) { this.logger = logger; } private final Logger logger; private volatile Level level = Level.BODY; /** * Change the level at which this interceptor logs. */ public LogInterceptor setLevel(Level level) { if (level == null) throw new NullPointerException("level == null. Use Level.NONE instead."); this.level = level; return this; } @Override public Response intercept(Interceptor.Chain chain) throws IOException { Level level = this.level; Request request = chain.request(); if (level == Level.NONE) { return chain.proceed(request); } boolean logBody = level == Level.BODY; boolean logHeaders = logBody || level == Level.HEADERS; RequestBody requestBody = request.body(); boolean hasRequestBody = requestBody != null; String requestStartMessage = request.method() + ' ' + request.url(); if (!logHeaders && hasRequestBody) { requestStartMessage += " (" + requestBody.contentLength() + "-byte body)"; } logger.log(requestStartMessage); if (logHeaders) { if (!logBody || !hasRequestBody) { logger.log("--> END " + request.method()); } else if (bodyEncoded(request.headers())) { logger.log("--> END " + request.method() + " (encoded body omitted)"); } else if (request.body() instanceof MultipartBody) { //如果是MultipartBody,会log出一大推乱码的东东 } else { Buffer buffer = new Buffer(); requestBody.writeTo(buffer); Charset charset = UTF8; MediaType contentType = requestBody.contentType(); if (contentType != null) { contentType.charset(UTF8); } logger.log(buffer.readString(charset)); // logger.log(request.method() + " (" + requestBody.contentLength() + "-byte body)"); } } long startNs = System.nanoTime(); Response response = chain.proceed(request); long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs); logger.log(response.code() + ' ' + response.message() + " (" + tookMs + "ms" + ')'); return response; } private boolean bodyEncoded(Headers headers) { String contentEncoding = headers.get("Content-Encoding"); return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity"); } private static String protocol(Protocol protocol) { return protocol == Protocol.HTTP_1_0 ? "HTTP/1.0" : "HTTP/1.1"; } }

5.MyGsonConverterFactory类

 

 

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); //请求 } }

6.自定义请求类:JsonRequestBodyConverter

 

 

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); } }

7.自定义响应类:JsonResponseBodyConverter

 

 

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; } }

8.封装的解析类SubListenerHelper

 

 

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; } }

9.ServerResponse类

解析统一的格式

{"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 + '}'; } }

 

转载请注明原文地址: https://www.6miu.com/read-35467.html

最新回复(0)