网络请求框架封装(OkHttp3+Retrofit+loading的封装)


  • Retrofit的Github链接
    点此链接到Github
  • AVLoadingIndicatorView的Github链接(封装到请求框架中,请求过程中的loading样式框(不停转的那个))
    点此链接到Github


  • post请求封装后的的效果展示(在任意需要网络请求的地方)

RestClient.builder().url("/sign_in").loader(getContext()).params("account", mEmail.getText().toString()).params("password", mPassword.getText().toString()).success(new ISuccess(){@Overridepublic void onSuccess(){//请求成功的处理逻辑}}).error(new IError(){@Overridepublic void onError(){//请求错误的处理逻辑}}).failure(new IFailure(){@overridepublic void onFailure(){//请求失败的处理逻辑}}.build().post();
  • 引入依赖
  //网络请求依赖api 'com.squareup.okio:okio:1.13.0'api 'com.squareup.okhttp3:okhttp:3.8.1'api 'com.squareup.retrofit2:retrofit:2.3.0'api 'com.squareup.retrofit2:converter-scalars:2.3.0'// loader依赖api 'com.wang.avi:library:2.1.3'
  • 网络框架结构

  • loading封装结构

  • Loader的封装

  • 1.新建LoaderStyle即loading的样式,建立一个枚举类
public enum LoaderStyle{BallPulseIndicator,BallGridPulseIndicator,BallClipRotateIndicator,BallClipRotatePulseIndicator,SquareSpinIndicator,BallClipRotateMultipleIndicator,BallPulseRiseIndicator,BallRotateIndicator,CubeTransitionIndicator,BallZigZagIndicator...
}
  • 2.新建LoaderCreator,通过映射,拿到需要的样式图标。
public final class LoaderCreator{private static final WeakHashMap<String, Indicator> LOADING_MAP = new WeakHashMap<>();static AVLoadingIndicatorView create(String type, Context context){final AVLoadingIndicatorView avLoadingIndicatorView = new AVLoadingIndicatorView(context);if (LOADING_MAP.get(type) == null){final Indicator indicator = getIndicator(type);LOADING_MAP.put(type, indicator);}avLoadingIndicatorView.setIndicator(LOADING_MAP.get(type));return avLoadingIndicatorView;}private static Indicator getIndicator(String name){if (name == null||name.isEmpty()){return null;}final StringBuilder drawableClassName = new StringBuilder();if (!name.contains(".")){final String defaultPackageName = AVLoadingIndicatorView.class.getPackage().getName();drawableClassName.append(defaultPackageName).append(".indicators").append(".");}drawableClassName.append(name);try {final Class<?> drawableClass = Class.forName(drawableClassName.toString());return (Indicator) drawableClass.newInstance();} catch (Exception e) {e.printStackTrace();return null;}}
}
  • 3.新建MyLoader,通过映射得到的图标,显示到屏幕上。
public class MyLoader{private static final int LOADER_SIZE_SCALE=8;private static final int LOADER_OFFSET_SCALE=10;private static final ArrayList<AppCompatDialog> LOADERS=new ArrayList<>();private static final String DEFAULT_LOADER=LoaderStyle.BallSpinFadeLoaderIndicator.name();public static void showLoading(Context context,Enum<LoaderStyle> styleEnum){showLoading(context,styleEnum.name());}public static void showLoading(Context context,String type){final AppCompatDialog dialog=new AppCompatDialog(context, R.style.dialog);final AVLoadingIndicatorView avLoadingIndicatorView=LoaderCreator.create(type,context);dialog.setContentView(avLoadingIndicatorView);int deviceWidth= DimenUtil.getScreenWidth();int deviceHeight=DimenUtil.getScreenHeight();final Window dialogWindow=dialog.getWindow();if (dialogWindow!=null){WindowManager.LayoutParams lp=dialogWindow.getAttributes();lp.width=deviceWidth/LOADER_SIZE_SCALE;lp.height=deviceHeight/LOADER_SIZE_SCALE;lp.height=lp.height+deviceHeight/LOADER_OFFSET_SCALE;lp.gravity= Gravity.CENTER;}LOADERS.add(dialog);dialog.show();}public static void showLoading(Context context){showLoading(context,DEFAULT_LOADER);}public static void stopLoading(){for (AppCompatDialog dialog:LOADERS){if (dialog!=null){if (dialog!=null){dialog.cancel();}}}}
}
  • RestClient封装

  • 1.先建立Retrofit请求必须要的接口文件RestService(泛式封装)

public interface RestService{@GETCall<String> get(@Url String url, @QueryMap Map<String, Object> params);@FormUrlEncoded@POSTCall<String> post(@Url String url, @FieldMap Map<String, Object> params);@POSTCall<String> postRaw(@Url String url, @Body RequestBody body);@FormUrlEncoded@PUTCall<String> put(@Url String url, @FieldMap Map<String, Object> params);@PUTCall<String> putRaw(@Url String url, @Body RequestBody body);@DELETECall<String> delete(@Url String url, @QueryMap Map<String, Object> params);@Streaming@GETCall<ResponseBody> download(@Url String url, @QueryMap Map<String, Object> params);@Multipart@POSTCall<String> upload(@Url String url, @Part MultipartBody.Part file);
}
  • 2.新建HttpMethod的枚举类
public enum HttpMethod{GET,POST,POST_RAW,PUT,PUT_RAW,DELETE,UPLOAD
}
  • 3.新建RestCreator类,将RetrofitService的接口实例化,然后用来进行网络请求。(静态内部类实现线程安全的单例模式)
public class RestCreator{// 参数的单例模式private static final class ParamsHolder{private static final WeakHashMap<String, Object> PARAMS = new WeakHashMap<>();}public static WeakHashMap<String, Object> getParams(){return ParamsHolder.PARAMS;}// 对外释放RestService的实例public static RestService getRestService(){return RestServiceHolder.REST_SRVICE;}private static final class RetrofitHolder{private static final String BASE_URL = "http://www.baidu.com/"private static final Retrofit RETROFIT_CLIENT = new Retrofit.Builder().baseUrl(BASE_URL).client(OKHttpHolder.OK_HTTP_CLIENT).addConverterFactory(ScalarsConverterFactory.create()).build();}private static final class OKHttpHolder {private static final int TIME_OUT = 60;private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder().connectTimeout(TIME_OUT, TimeUnit.SECONDS).build();}private static final class RestServiceHolder{private static final RestService REST_SERVICE = RetrofitHolder.RETROFIT_HOLDER.create(RestService.class);}
}
  • 4.根据获取到的参数数据,组装之后进行网络请求(使用建造者模式进行数据的组装)先建立callback的回调接口
public interface ISuccess {void onSuccess(String response);
}
public interface IError {void onError(int Code, String msg);
}
public interface IFailure {void onFailure();
}
public interface IRequest {void onRequestStart();void onRequestEnd();
}
  • 5.新建RequestCallbacks实现Callback的接口,即处理网络请求的回调
public class RequestCallbacks implements Callback<String>{private final IRequest REQUEST;private final ISuccess SUCCESS;private final IFailure FAILURE;private final IError ERROR;private final LoaderStyle LOADER_STYLE;public RequestCallbacks(IRequest request, ISuccess success, IFailure failure, IError error, LoaderStyle loaderStyle){this.REQUEST = request;this.SUCCESS = success;this.FAILURE = failure;this.ERROR = error;this.LOADER_STYLE = loaderStyle;}@Overridepublic void onResponse(Call<String> call, Response<String> response) {if (response.isSuccessful()) {if (call.isExecuted()) {if (SUCCESS != null) {SUCCESS.onSuccess(response.body());}}} else {if (ERROR != null) {ERROR.onError(response.code(), response.message());}}stopLoader();}@Overridepublic void onFailure(Call<String> call, Throwable t) {if (FAILURE != null) {FAILURE.onFailure();}if (REQUEST != null) {REQUEST.onRequestEnd();}stopLoader();}private void stopLoader() {if (LOADER_STYLE != null) {LatteLoader.stopLoading();}}
}
  • 6.新建RestClient类,就是将传入的数据进行组装然后用之前实例化的RestService对象进行网络请求。
public class RestClient{private final String URL;private static final WeakHashMap<String, Object> PARAMS = RestCreator.getParams();private final IRequest REQUEST;private final String DOWNLOAD_DIR;private final String EXTENSION;private final String NAME;private final ISuccess SUCCESS;private final IFailure FAILURE;private final IError ERROR;private final RequestBody BODY;private final LoaderStyle LOADER_STYLE;private final File FILE;private final Context CONTEXT;public RestClient(String url,Map<String, Object> params,IRequest request,String download_dir,String extension,String name,ISuccess success,IFailure failure,IError error,RequestBody body,LoaderStyle loaderStyle,File file,Context context) {this.URL = url;PARAMS.putAll(params);this.REQUEST = request;this.DOWNLOAD_DIR = download_dir;this.EXTENSION = extension;this.NAME = name;this.SUCCESS = success;this.FAILURE = failure;this.ERROR = error;this.BODY = body;this.LOADER_STYLE = loaderStyle;this.FILE = file;this.CONTEXT = context;}public static RestClientBuilder builder() {return new RestClientBuilder();}private void request(HttpMethod method){final RestService service = RestCreator.getRestService();Call<String> call = null;if(REQUEST != null){REQUEST.onRequestStart();}if (LOADER_STYLE != null) {LatteLoader.showLoading(CONTEXT, LOADER_STYLE);}switch (method) {case GET:call = service.get(URL, PARAMS);break;case POST:call = service.post(URL, PARAMS);break;case POST_RAW:call = service.postRaw(URL, BODY);break;case PUT:call = service.put(URL, PARAMS);break;case PUT_RAW:call = service.putRaw(URL, BODY);break;case DELETE:call = service.delete(URL, PARAMS);break;case UPLOAD:final RequestBody requestBody = RequestBody.create(MediaType.parse(MultipartBody.FORM.toString()), FILE);final MultipartBody.Part body = MultipartBody.Part.createFormData("file", FILE.getName(), requestBody);call = RestCreator.getRestService().upload(URL, body);break;default:break;}if (call != null) {call.enqueue(getRequestCallback());}RestCreator.getParams().clear();}private Callback<String> getRequestCallback() {return new RequestCallbacks(REQUEST,SUCCESS,FAILURE,ERROR,LOADER_STYLE);}public final void get() {request(HttpMethod.GET);}public final void post() {if (BODY == null) {request(HttpMethod.POST);} else {if (PARAMS.isEmpty()) {throw new RuntimeException("params must be null");}request(HttpMethod.POST_RAW);}}public final void put() {if (BODY == null) {request(HttpMethod.PUT);} else {if (PARAMS.isEmpty()) {throw new RuntimeException("params must be null");}request(HttpMethod.PUT_RAW);}}public final void delete() {request(HttpMethod.DELETE);}public final void upload() {request(HttpMethod.UPLOAD);}
}
  • 7.新建RestClientBuilder,就是RestClient的建造者类
public class RestClientBuilder {private String mUrl = null;private static final Map<String, Object> PARAMS = RestCreator.getParams();private IRequest mIRequest = null;private String mDownloadDir = null;private String mExtension = null;private String mName = null;private ISuccess mISuccess = null;private IFailure mIFailure = null;private IError mIError = null;private RequestBody mBody = null;private LoaderStyle mLoaderStyle = null;private File mFile = null;private Context mContext = null;RestClientBuilder() {}public final RestClientBuilder url(String url) {this.mUrl = url;return this;}public final RestClientBuilder params(WeakHashMap<String, Object> params) {PARAMS.putAll(params);return this;}public final RestClientBuilder params(String key, Object value) {PARAMS.put(key, value);return this;}public final RestClientBuilder file(File file) {this.mFile = file;return this;}public final RestClientBuilder file(String file) {this.mFile = new File(file);return this;}public final RestClientBuilder raw(String raw) {this.mBody = RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), raw);return this;}public final RestClientBuilder dir(String dir) {this.mDownloadDir = dir;return this;}public final RestClientBuilder extension(String extension) {this.mExtension = extension;return this;}public final RestClientBuilder name(String name) {this.mName = name;return this;}public final RestClientBuilder onRequest(IRequest iRequest) {this.mIRequest = iRequest;return this;}public final RestClientBuilder success(ISuccess iSuccess) {this.mISuccess = iSuccess;return this;}public final RestClientBuilder failure(IFailure iFailure) {this.mIFailure = iFailure;return this;}public final RestClientBuilder error(IError iError) {this.mIError = iError;return this;}public final RestClientBuilder loader(Context context, LoaderStyle style) {this.mContext = context;this.mLoaderStyle = style;return this;}public final RestClientBuilder loader(Context context) {this.mContext = context;this.mLoaderStyle = LoaderStyle.BallSpinFadeLoaderIndicator;return this;}public final RestClient build() {return new RestClient(mUrl, PARAMS, mIRequest, mDownloadDir, mExtension, mName, mISuccess, mIFailure, mIError, mBody, mLoaderStyle, mFile, mContext);}}
  • 8.小结
    至此网络框架告一段落,其中的download没有写全,调用方式就是开头写的那样。

Android肝帝战纪之网络请求框架封装(Retrofit的封装)相关推荐

  1. Android肝帝战纪之ObjectBox移动数据库框架探究与实现

    ObjectBox移动数据库框架 ObjectBox Github链接: 点击此处链接到Github 介绍 ObjectBox是移动端数据库框架,灵感来自于NoSql,速度非常快,号称是市面上最快的移 ...

  2. Android肝帝战纪之字体图标库(iconify)的简单使用

    字体图标库(iconify)的简单使用 本文介绍字体图标库简单的封装和使用(以集成Fontawesome为例): Iconify的GIithub链接 点此链接到Github 导入依赖 //在app级别 ...

  3. Android肝帝战纪之基于上篇单Activity+多Fragment框架,开发电商式导航栏,多Fragment切换

    电商式导航栏,多Fragment切换 本文默认在已经搭建好的框架上进行开发 点此链接到上一篇基础框架的搭建 界面构思示意图 设计思路 在底部的LinearLayout中添加相应的图标,然后设置tag绑 ...

  4. Android肝帝战纪之Fragmentation的使用(单Activity+多Fragment设计)

    #单Activity+多Fragment设计(Fragmentation的使用)# 本文介绍使用Fragmentation库打造单Activity+多Fragment的App基础架构: Fragmen ...

  5. Android网络请求框架之Retrofit(二)

    前面一篇文章介绍了Retrofit的基本用法,没有看过的童鞋可以移步:Android网络请求框架之Retrofit(一),现在我们来继续介绍Retrofit配合RxJava.RxAndroid的用法. ...

  6. android post请求_Vue 网络请求框架 axios 使用教程

    点击上方"代码集中营",设为星标 优秀文章,第一时间送达! 前期回顾 1. Vue 学习入门指南 2. Vue 入门环境搭建 3. Visual Studio Code 使用指南 ...

  7. Retrofit网络请求框架使用简析——Android网络请求框架(四)

    题记:-- 很累,累到想要放弃,但是放弃之后将会是一无所有,又不能放弃, 唯有坚持,唯有给自忆打气,才能更勇敢的走下去,因为无路可退,只能前行, 时光一去不复返,每一天都不可追回,所以要更珍惜每一存光 ...

  8. okhttp的应用详解与源码解析--android网络请求框架发展史

    乘5G之势,借物联网之风,Android未来亦可期,Android优势在于开放,手机.平板.车载设备.智能家居等都是Android的舞台,Google不倒,Android不灭,本专栏的同步视频教程已经 ...

  9. Android RxJava应用:优雅实现网络请求轮询(无条件)

    前言 Rxjava,由于其基于事件流的链式调用.逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎. 今天,我将为大家带来 Rxjava创建操作符的常见开发应用场景:轮询需求 ...

最新文章

  1. 【Android 内存优化】Bitmap 图像尺寸缩小 ( 设置 Options 参数 | inJustDecodeBounds | inSampleSize | 工具类实现 )
  2. Python小练习2:pandas.Dataframe使用方法示例demo
  3. python数据科学实践 常象宇_Python数据科学实践
  4. 存储池与存储卷,使用virt-install创建虚拟机
  5. php时间函数引入,PHP日期和时间函数的使用示例详解
  6. 技术中台构建思路及进展_半年中台实践思考:落地中台,贵在其神,活用其形...
  7. C++编程问题--注意指针参数的传递
  8. 中国老工业基地吉林对外贸易重回历史高水平
  9. Xilinx_Vivado_2019.1下载和安装教程
  10. log4j日志设置error级别以上
  11. SAI:Switch Abstraction Interface
  12. 11.5 走出来的就业路——《逆袭大学》连载
  13. c语言苹果大小分级,苹果品质分级标准您知道吗?
  14. 网站建设费用贵和便宜有什么区别?
  15. (转自博客园-雲霏霏)5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task
  16. 宏批量替换多个word指定文字
  17. Maven resources compiler: Maven project configuration required for module ‘XXX‘ isn‘t available.
  18. iso8583协议说明
  19. exsi rh2288hv5 驱动_华为RH2288H服务器引导ServiceCD安装Windows Server操作系统
  20. 创建一个IntelliJ Idea文件模板,将光标放在文件中的特定位置

热门文章

  1. IOS开发百度地图API
  2. Ant Design + react-drag-listview实现Table拖拽变换列位置
  3. 通过AI,领略皮影戏艺术 | MixLab人工智能
  4. win10蓝牙android上网,Win10系统如何共享安卓手机蓝牙上网(非热点)
  5. aliases节点解析
  6. php中如何过滤关键字,PHP - 过滤关键字
  7. JAVA学习 API_day11(属性集, 函数式编程, stream流)
  8. 京东数据库智能运维平台建设之路
  9. android10全面屏手势 操作图,丨系统设计丨ZUI 10加入更多全面屏手势
  10. Talk to AI,揭秘背后的语音识别数据