这是一款Android 网络请求框架,简单易用
集成步骤
如果你的项目 Gradle 配置是在
7.0 以下
,需要在build.gradle
文件中加入
allprojects { repositories { // JitPack 远程仓库:https://jitpack.io maven { url 'https://jitpack.io' } } }
如果你的 Gradle 配置是
7.0 及以上
,则需要在settings.gradle
文件中加入
dependencyResolutionManagement { repositories { // JitPack 远程仓库:https://jitpack.io maven { url 'https://jitpack.io' } } }
配置完远程仓库后,在项目 app 模块下的
build.gradle
文件中加入远程依赖
android { // 支持 JDK 1.8 compileOptions { targetCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8 } } dependencies { // 网络请求框架:https://github.com/getActivity/EasyHttp implementation 'com.github.getActivity:EasyHttp:13.0' // OkHttp 框架:https://github.com/square/okhttp // noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:3.12.13'}
需要注意的是:由于使用了 Lifecycle 特性,目前框架只支持 AndroidX 的项目集成
框架混淆规则
OkHttp3 框架混淆规则
# OkHttp3 框架混淆规则 -keepattributes Signature -keepattributes *Annotation* -keep class okhttp3.** { *; } -keep interface okhttp3.** { *; } -dontwarn okhttp3.** -dontwarn okio.**
EasyHttp 框架混淆规则
# EasyHttp 框架混淆规则 -keep class com.hjq.http.** {*;}
不混淆实现 OnHttpListener 接口的类
# 必须要加上此规则,否则会导致泛型解析失败 -keep class * implements com.hjq.http.listener.OnHttpListener { *; } -keep class * extends com.hjq.http.model.ResponseClass { *; }
不混淆某个包下的 Bean 类
# 必须要加上此规则,否则可能会导致 Bean 类的字段无法解析成后台返回的字段,xxx 请替换成对应包名 -keep class com.xxx.xxx.xxx.xxx.** { <fields>; }
以上混淆规则,可以在主模块的
proguard-rules.pro
文件中加入
不同网络请求框架之间的对比
功能或细节 | EasyHttp | Retrofit | OkGo |
---|---|---|---|
对应版本 | 13.0 | 2.9.0 | 3.0.4 |
issues 数 | |||
aar 包大小 | 96 KB | 123 KB | 131 KB |
minSdk 要求 | API 14+ | API 21+ | API 14+ |
配置多域名 | ✅ | ❌ | ✅ |
动态 Host | ✅ | ❌ | ❌ |
全局参数 | ✅ | ❌ | ✅ |
日志打印 | ✅ | ❌ | ✅ |
超时重试 | ✅ | ✅ | ✅ |
配置 Http 缓存 | ✅ | ❌ | ✅ |
下载文件校验 | ✅ | ❌ | ❌ |
极速下载 | ✅ | ❌ | ❌ |
下载断点续传 | ✅ | ❌ | ✅ |
上传进度监听 | ✅ | ❌ | ✅ |
Json 参数提交 | ✅ | ❌ | ✅ |
Json 日志打印格式化 | ✅ | ❌ | ❌ |
请求代码定位 | ✅ | ❌ | ❌ |
延迟发起请求 | ✅ | ❌ | ❌ |
分区存储适配 | ✅ | ❌ | ❌ |
上传文件类型 | File / FileContentResolver InputStream / RequestBody | RequestBody | File |
批量上传文件 | ✅ | ❌ | ✅ |
请求生命周期 | 自动管控 | 需要封装 | 需要封装 |
参数传值方式 | 字段名 + 字段值 | 参数名 + 参数值 | 定义 Key + Value |
框架灵活性 | 高 | 低 | 中 |
框架学习成本 | 中 | 高 | 低 |
API 记忆成本 | 低 | 高 | 低 |
接口维护成本 | 低 | 中 | 高 |
框架维护状态 | 维护中 | 维护中 | 停止维护 |
Retrofit 在我看来并不是那么好用,因为很多常用的功能实现起来比较麻烦,动态 Host 要写拦截器,日志打印要写拦截器,就连最常用的添加全局参数也要写拦截器,一个拦截器意味着要写很多代码,如果写得不够严谨还有可能出现 Bug,从而影响整个 OkHttp 请求流程,我经常在想这些功能能不能都用一句代码搞定,因为我觉得这些功能是设计框架的时候本应该考虑的,这便是我做这个框架的初心。
OkGo 其实也存在一些弊端,例如会把参数的 key 引用放到外层去,这样会引发一些问题:
Key 管理问题:这个 key 可能会在外层被使用很多次,这样参数的 key 管理就会变得不可控,后续接口改动可能会出现漏改的风险,尽管这种情况比较少见,但是也不容忽视,而 EasyHttp 没有这个问题,因为 EasyHttp 不会将参数 key 值放置到外层中去。
接口参数注释的问题:站在代码的规范角度上讲,我们应该在代码中注明参数的含义及作用,如果一旦将 key 放到外层,那么每一处调用的地方都需要写一遍注释,而 EasyHttp 是将参数字段化,只需要写一次注释到字段上即可。
接口信息完整信息展示:使用 OkGo 请求网络,只能在调用的地方看到传递的接口参数,而一些被其他地方引用的参数,我们无法很直观的看到,只能通过追踪代码或者查看文档来得知,而 EasyHttp 将一个接口的信息全部通过一个类来管理的,这个类其实就相当于一个接口文档。
接口的动态化配置:除了接口的参数之外,一个接口还有可能单独配置 OkHttpClient 对象、参数的提交方式、接口响应处理方式等,这些用 OkGo 是可以实现,但是每个地方都要写一次,而 EasyHttp 可以直接在 API 类中配置,真正做到一劳永逸。
EasyHttp 采用了 OOP 思想,一个请求代表一个对象,通过类继承和实现的特性来对接口进行动态化配置,几乎涵盖接口开发中所有的功能,使用起来非常简单灵活。而 Retrofit 采用的是注解方式,缺点是灵活性极低,因为注解上面只能放常量,也就会限定你在注解上面的一切参数只能是事先定义好的,这对接口的动态化配置极不利的。
有很多人觉得写一个接口类很麻烦,关于这个问题我后面已经想到一个好方案了,大家可以将 Api 类和 Bean 类写在一起,这样大家就不需要多写一个类了,具体写法示例如下:
public final class XxxApi implements IRequestApi { @Override public String getApi() { return "xxx/xxx"; } private int xxx; public XxxApi setXxx(int xxx) { this.xxx = xxx; return this; } ...... public final static class Bean { private int xyz; public int getXyz() { return xyz; } ...... } }
是不是很机智?这样不仅很好地解决了这一问题,还能将一个接口所有的信息都包裹在这个类中,非常直观,一览如云,妥妥的一箭双雕。
生命周期自动管控介绍
框架可以自动管控请求的生命周期,无需第三方调用者封装和适配,这块其实用到 Jetpack 中的一个 Lifecycle 特性,框架将网络请求和 LifecycleOwner 绑定在一起,当 LifecycleOwner 触发 destroy 时,框架会对绑定的网络请求进行 cancel 处理。相比较传统的写法,这种方式更加简单快捷,同时有 Lifecycle 特性的加持,灵活也会更高,因为我们完全不需要关心请求的主体是 Activity 还是 Fragment,又或者是其他类型的对象。
但并不是完全没有缺点,因为 Lifecycle 特性是 AndroidX 包中的新特性,如果需要使用的话,当前项目必须基于 AndroidX 库开发的才可以集成。
都说代码是最好的老师,具体实现的代码如下:
public final class HttpLifecycleManager implements LifecycleEventObserver { /** * 绑定组件的生命周期 */ public static void register(LifecycleOwner lifecycleOwner) { lifecycleOwner.getLifecycle().addObserver(new HttpLifecycleManager()); } @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (event != Lifecycle.Event.ON_DESTROY) { return; } // 移除监听 source.getLifecycle().removeObserver(this); // 取消请求 EasyHttp.cancelByTag(source); } }
极速下载功能介绍
其实本质上面和极速秒传的原理是差不多的,只不过一个是上传,另一个是下载。而极速上传是将本地文件的 MD5 值和服务器上面的进行比对,如果服务器存在这个 MD5 值的文件,就将这份文件映射一份到这个用户的网盘上面,从而达到了极速秒传的效果。而极速下载也是同理,根据后台给的文件 MD5 值和本地文件进行对比,如果存在这个文件并且 MD5 值一致,证明这个文件和服务器上面的文件是一致的,那么就直接跳过下载,直接回调下载成功监听。
极速秒传和极速下载两者相同的共同点就是,利用缓存来达到极速的效果,只不过一者通过的是服务器的缓存,另一者使用的是本地的缓存,这两者都有一个共同的特点,就是减少服务器的压力,节省用户的等待时间。
代码定位功能介绍
框架会在日志打印中输出在网络请求的代码位置,这样开发者可以直接通过点击 Log 来定位是在哪个类哪行代码,这样可以极大提升我们排查问题的效率,特别是在请求一多且业务复杂的情况下,我相信没有一个人会拒绝这样的功能。
延迟发起请求功能介绍
通常我们都有这样一种需求,就是我们希望发起网络请求,但是希望它不是及时,而是经过一定的延迟才去请求,EasyHttp 针对这种场景进行了考虑并封装,我们可以这样写来做到这种效果:
EasyHttp.post(this) .api(new XxxApi()) .delay(3000) .request(new HttpCallbackProxy<HttpData<XxxBean>>(this) { @Override public void onHttpSuccess(HttpData<XxxBean> result) { } });
欢迎关注我的公众号:莫雨莫语,或者扫描下方二维码,每天为您带来优秀的开源项目
来源:
互联网
本文观点不代表码客-全球程序员交流社区立场,不承担法律责任,文章及观点也不构成任何投资意见。
评论列表