├── easyRequest ├── .gitignore ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── cloudling │ │ │ └── request │ │ │ ├── type │ │ │ ├── Method.java │ │ │ ├── RequestType.java │ │ │ ├── MockRequestCallbackType.java │ │ │ ├── OriginalCallback.java │ │ │ └── TransformCallbackType.java │ │ │ ├── network │ │ │ ├── DefaultRequest.java │ │ │ ├── DefaultParam.java │ │ │ ├── OriginalTransformListener.java │ │ │ ├── RequestParam.java │ │ │ ├── NetworkConfig.java │ │ │ ├── EasyRequest.java │ │ │ └── BaseRequest.java │ │ │ ├── cache │ │ │ ├── TimeUnit.java │ │ │ ├── CacheType.java │ │ │ ├── CacheValue.java │ │ │ ├── ReadCacheType.java │ │ │ ├── BaseCacheImpl.java │ │ │ ├── CacheHelper.java │ │ │ ├── DefaultCacheImpl.java │ │ │ └── AesHelper.java │ │ │ ├── listener │ │ │ ├── WholeRequestListener.java │ │ │ ├── WholeConverterListener.java │ │ │ ├── TimeoutListener.java │ │ │ ├── ILog.java │ │ │ ├── RequestListener.java │ │ │ ├── ConverterListener.java │ │ │ ├── MockRequest.java │ │ │ ├── TransformListener.java │ │ │ └── SupportCallback.java │ │ │ ├── service │ │ │ ├── base │ │ │ │ ├── BaseMicroService.java │ │ │ │ ├── BaseSingleService.java │ │ │ │ └── BaseService.java │ │ │ ├── DefaultMicroService.java │ │ │ └── DefaultSingleService.java │ │ │ └── delegate │ │ │ ├── RequestDelegate.java │ │ │ └── OkHttpDelegate.java │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── cloudling │ │ │ └── request │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── cloudling │ │ └── request │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── local.properties ├── gradle.properties ├── gradlew.bat ├── gradlew └── README.md /easyRequest/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':easyRequest' 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linpeixu/EasyRequest/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /easyRequest/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/type/Method.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.type; 2 | 3 | /** 4 | * 描述: 请求方法 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public enum Method { 9 | GET, 10 | POST, 11 | PUT, 12 | DELETE 13 | } 14 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Dec 08 17:36:38 CST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/type/RequestType.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.type; 2 | 3 | /** 4 | * 描述: 请求方法 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | * 8 | * @deprecated 推荐使用 {@link Method} 9 | */ 10 | public enum RequestType { 11 | GET, 12 | POST, 13 | PUT, 14 | DELETE 15 | } 16 | -------------------------------------------------------------------------------- /local.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Thu Dec 23 17:53:36 CST 2021 8 | sdk.dir=D\:\\android-sdk 9 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/type/MockRequestCallbackType.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.type; 2 | 3 | /** 4 | * 描述: 模拟请求结果回调类型 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public enum MockRequestCallbackType { 9 | /** 10 | * 成功 11 | */ 12 | SUCCESS, 13 | /** 14 | * 失败 15 | */ 16 | FAIL 17 | } 18 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/type/OriginalCallback.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.type; 2 | 3 | /** 4 | * 描述: 原始的回调类型(网络请求回调成功或失败) 5 | * 作者: 1966353889@qq.com 6 | * 日期: 2021/12/30 7 | */ 8 | public enum OriginalCallback { 9 | /** 10 | * 成功 11 | */ 12 | SUCCESS, 13 | /** 14 | * 失败 15 | */ 16 | FAILURE 17 | } 18 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/network/DefaultRequest.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.network; 2 | 3 | /** 4 | * 描述: 默认请求回调参数为String的Builder 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public final class DefaultRequest { 9 | public static BaseRequest.Builder create() { 10 | return new BaseRequest.Builder(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/TimeUnit.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | /** 4 | * 描述: 时间单位 5 | * 联系: 1966353889@qq.com 6 | * 日期: 2022/1/6 7 | */ 8 | public enum TimeUnit { 9 | /** 10 | * 天 11 | */ 12 | DAYS, 13 | /** 14 | * 时 15 | */ 16 | HOURS, 17 | /** 18 | * 分 19 | */ 20 | MINUTES, 21 | /** 22 | * 秒 23 | */ 24 | SECONDS 25 | } 26 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/WholeRequestListener.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | /** 4 | * 描述: 请求结果监听(带请求开始和结束回调) 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public interface WholeRequestListener extends RequestListener{ 9 | /** 10 | * 请求开始回调 11 | */ 12 | void requestBefore(); 13 | 14 | /** 15 | * 请求结束回调 16 | */ 17 | void requestAfter(); 18 | } 19 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/type/TransformCallbackType.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.type; 2 | 3 | /** 4 | * 描述: 请求结果转换回调类型(可强制将请求结果回调为成功,失败) 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public enum TransformCallbackType { 9 | /** 10 | * 成功 11 | */ 12 | SUCCESS, 13 | /** 14 | * 失败 15 | */ 16 | FAIL, 17 | /** 18 | * 默认(跟随网络请求回调) 19 | */ 20 | DEFAULT 21 | } 22 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/WholeConverterListener.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | /** 4 | * 描述: 请求结果监听(带请求开始和结束回调) 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public interface WholeConverterListener extends ConverterListener { 9 | /** 10 | * 请求开始回调 11 | */ 12 | void requestBefore(); 13 | 14 | /** 15 | * 请求结束回调 16 | */ 17 | void requestAfter(); 18 | } 19 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/network/DefaultParam.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.network; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | /** 6 | * 描述: 创建默认的构建请求参数 7 | * 联系:1966353889@qq.com 8 | * 日期: 2022/2/12 9 | */ 10 | public class DefaultParam extends RequestParam> { 11 | @Override 12 | public LinkedHashMap initParam() { 13 | return new LinkedHashMap<>(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/service/base/BaseMicroService.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.service.base; 2 | 3 | /** 4 | * 描述: 微服务接口请求服务基类(不同环境继承该类设置不同的host) 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/3 7 | */ 8 | public abstract class BaseMicroService extends BaseService { 9 | public BaseMicroService() { 10 | super(); 11 | } 12 | 13 | @Override 14 | public final String setHost() { 15 | return null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/TimeoutListener.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | 4 | /** 5 | * 描述: 接口超时配置 6 | * 联系:1966353889@qq.com 7 | * 日期: 2021/12/3 8 | */ 9 | public interface TimeoutListener { 10 | /** 11 | * 连接超时时间 12 | */ 13 | long connectTimeout(); 14 | 15 | /** 16 | * 读取超时时间 17 | */ 18 | long readTimeout(); 19 | 20 | /** 21 | * 写入超时时间 22 | */ 23 | long writeTimeout(); 24 | 25 | } -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/ILog.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | /** 4 | * 描述: 日志输出接口 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public interface ILog { 9 | void onLogVerbose(String TAG, String log); 10 | 11 | void onLogDebug(String TAG, String log); 12 | 13 | void onLogInfo(String TAG, String log); 14 | 15 | void onLogWarn(String TAG, String log); 16 | 17 | void onLogError(String TAG, String log); 18 | } 19 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/RequestListener.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | /** 4 | * 描述: 请求结果监听 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public interface RequestListener { 9 | /** 10 | * 成功 11 | * 12 | * @param result 回调参数 13 | */ 14 | void onSuccess(String result); 15 | 16 | /** 17 | * 失败 18 | * 19 | * @param result 回调参数 20 | */ 21 | void onFail(String result); 22 | } 23 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/ConverterListener.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | /** 4 | * 描述: 请求结果监听(带请求开始和结束回调) 5 | * 联系:1966353889@qq.com 6 | * 日期: 2021/12/29 7 | */ 8 | public interface ConverterListener { 9 | /** 10 | * 成功 11 | * 12 | * @param result 回调参数 13 | */ 14 | void onSuccess(S result); 15 | 16 | /** 17 | * 失败 18 | * 19 | * @param result 回调参数 20 | */ 21 | void onFail(F result); 22 | } 23 | -------------------------------------------------------------------------------- /easyRequest/src/test/java/com/cloudling/request/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/service/base/BaseSingleService.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.service.base; 2 | 3 | import android.util.ArrayMap; 4 | 5 | /** 6 | * 描述: 单服务接口请求服务基类(不同环境继承该类设置不同的host) 7 | * 联系:1966353889@qq.com 8 | * 日期: 2021/12/3 9 | */ 10 | public abstract class BaseSingleService extends BaseService { 11 | public BaseSingleService() { 12 | super(); 13 | } 14 | 15 | @Override 16 | public final ArrayMap setMicroConfig() { 17 | return null; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/MockRequest.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | import com.cloudling.request.type.MockRequestCallbackType; 4 | 5 | /** 6 | * 描述: 模拟请求配置 7 | * 联系:1966353889@qq.com 8 | * 日期: 2021/12/29 9 | */ 10 | public interface MockRequest { 11 | /** 12 | * 请求时长 13 | */ 14 | int requestDuration(); 15 | 16 | /** 17 | * 模拟请求结果回调类型 18 | */ 19 | MockRequestCallbackType callbackType(); 20 | 21 | /** 22 | * 模拟请求结果返回值 23 | */ 24 | String result(); 25 | } 26 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/TransformListener.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | import com.cloudling.request.type.TransformCallbackType; 4 | 5 | /** 6 | * 描述: 请求结果转换 7 | * 联系:1966353889@qq.com 8 | * 日期: 2021/12/29 9 | */ 10 | public interface TransformListener { 11 | /** 12 | * 转换请求结果(可对请求回调参数做包装) 13 | * 14 | * @param result 回调参数 15 | */ 16 | String onTransformResult(String result); 17 | 18 | /** 19 | * 是否将结果转成成功 20 | */ 21 | TransformCallbackType callbackType(); 22 | } 23 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/CacheType.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | /** 4 | * 描述: 缓存(或读取缓存)类型(设置什么时候需要缓存数据或读取缓存) 5 | * 联系: 1966353889@qq.com 6 | * 日期: 2022/1/7 7 | */ 8 | public enum CacheType { 9 | /** 10 | * 不缓存 11 | */ 12 | NO, 13 | /** 14 | * 默认(跟随网络请求回调成功或失败缓存对应类型的数据) 15 | */ 16 | DEFAULT, 17 | /** 18 | * 缓存成功(原始网络请求成功)的数据或读取成功(原始网络请求成功)的缓存数据 19 | */ 20 | SOURCE_SUCCESS, 21 | /** 22 | * 缓存失败(原始网络请求失败)的数据或读取失败(原始网络请求失败)的缓存数据 23 | */ 24 | SOURCE_FAIL, 25 | } 26 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/network/OriginalTransformListener.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.network; 2 | 3 | import com.cloudling.request.listener.TransformListener; 4 | import com.cloudling.request.type.OriginalCallback; 5 | 6 | /** 7 | * 描述: 请求结果转换(带原始的回调类型(网络请求回调成功或失败)) 8 | * 联系:1966353889@qq.com 9 | * 日期: 2021/12/30 10 | */ 11 | public abstract class OriginalTransformListener implements TransformListener { 12 | public abstract String onTransformResult(OriginalCallback type, String result); 13 | 14 | @Override 15 | public final String onTransformResult(String result) { 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/CacheValue.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | /** 4 | * 描述: 5 | * 作者: lpx 6 | * 日期: 2022/1/6 7 | */ 8 | @Deprecated 9 | public class CacheValue { 10 | /** 11 | * 写入时当前时间 12 | */ 13 | private final long writeTimeMillis; 14 | /** 15 | * 缓存的时长 16 | */ 17 | private final long saveDuration; 18 | /** 19 | * 缓存的内容 20 | */ 21 | private final String value; 22 | 23 | public CacheValue(long saveDuration, String value) { 24 | writeTimeMillis = System.currentTimeMillis(); 25 | this.saveDuration = saveDuration; 26 | this.value = value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/network/RequestParam.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.network; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 描述: 返回构建请求参数 7 | * 联系:1966353889@qq.com 8 | * 日期: 2021/12/29 9 | */ 10 | public abstract class RequestParam> { 11 | private final MapType param; 12 | 13 | public RequestParam() { 14 | param = initParam(); 15 | } 16 | 17 | public abstract MapType initParam(); 18 | 19 | public RequestParam put(String key, Object value) { 20 | param.put(key, value); 21 | return this; 22 | } 23 | 24 | public MapType build() { 25 | return param; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/delegate/RequestDelegate.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.delegate; 2 | 3 | import com.cloudling.request.network.BaseRequest; 4 | 5 | /** 6 | * 描述: 请求代理 7 | * 联系:1966353889@qq.com 8 | * 日期: 2021/12/29 9 | */ 10 | public interface RequestDelegate { 11 | /** 12 | * 发起请求 13 | */ 14 | void request(BaseRequest config); 15 | 16 | /** 17 | * 移除请求 18 | */ 19 | void remove(BaseRequest config); 20 | 21 | /** 22 | * 通过tag移除请求 23 | */ 24 | void removeByTag(String TAG); 25 | 26 | /** 27 | * 通过uuid移除请求 28 | */ 29 | void removeByUUID(String uuid); 30 | 31 | /** 32 | * 是否禁用代理 33 | */ 34 | boolean isDisableProxy(); 35 | } 36 | -------------------------------------------------------------------------------- /easyRequest/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/service/DefaultMicroService.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.service; 2 | 3 | import com.cloudling.request.service.base.BaseService; 4 | 5 | /** 6 | * 描述: 微服务接口默认请求服务基类(已实现默认超时时间,不同环境继承该类设置不同的host) 7 | * 联系:1966353889@qq.com 8 | * 日期: 2021/12/3 9 | */ 10 | public abstract class DefaultMicroService extends BaseService { 11 | public DefaultMicroService() { 12 | super(); 13 | } 14 | 15 | @Override 16 | public final String setHost() { 17 | return null; 18 | } 19 | 20 | @Override 21 | public final long connectTimeout() { 22 | return 20; 23 | } 24 | 25 | @Override 26 | public final long readTimeout() { 27 | return 20; 28 | } 29 | 30 | @Override 31 | public final long writeTimeout() { 32 | return 20; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /easyRequest/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | } 4 | android { 5 | compileSdk 30 6 | 7 | defaultConfig { 8 | minSdk 21 9 | minSdk 21 10 | targetSdk 30 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | compileOptions { 24 | sourceCompatibility JavaVersion.VERSION_1_8 25 | targetCompatibility JavaVersion.VERSION_1_8 26 | } 27 | } 28 | 29 | dependencies { 30 | api 'com.squareup.okhttp3:okhttp:4.9.3' 31 | api 'com.gitlab.linpeixu:BaseConverterFactory:1.0.2' 32 | } -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/service/DefaultSingleService.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.service; 2 | 3 | import android.util.ArrayMap; 4 | 5 | import com.cloudling.request.service.base.BaseService; 6 | 7 | /** 8 | * 描述: 单服务接口默认请求服务基类(已实现默认超时时间,不同环境继承该类设置不同的host) 9 | * 联系:1966353889@qq.com 10 | * 日期: 2021/12/3 11 | */ 12 | public abstract class DefaultSingleService extends BaseService { 13 | public DefaultSingleService() { 14 | super(); 15 | } 16 | 17 | @Override 18 | public final ArrayMap setMicroConfig() { 19 | return null; 20 | } 21 | 22 | @Override 23 | public final long connectTimeout() { 24 | return 20; 25 | } 26 | 27 | @Override 28 | public final long readTimeout() { 29 | return 20; 30 | } 31 | 32 | @Override 33 | public final long writeTimeout() { 34 | return 20; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /easyRequest/src/androidTest/java/com/cloudling/request/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.cloudling.request", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/ReadCacheType.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | /** 4 | * 描述: 读取缓存类型(设置什么时候需要读取什么样的缓存数据) 5 | * 联系: 1966353889@qq.com 6 | * 日期: 2022/1/7 7 | */ 8 | public enum ReadCacheType { 9 | /** 10 | * 不读取 11 | */ 12 | NO, 13 | /** 14 | * 默认(跟随网络请求回调成功或失败读取对应类型的缓存数据) 15 | */ 16 | DEFAULT, 17 | /** 18 | * 当前网络请求成功时读取成功(原始网络请求成功)的缓存数据 19 | */ 20 | READ_SUCCESS_AFTER_SUCCESS, 21 | /** 22 | * 当网络请求成功时读取失败(原始网络请求失败)的缓存数据 23 | */ 24 | READ_FAIL_AFTER_SUCCESS, 25 | /** 26 | * 当前网络请求失败时读取成功(原始网络请求成功)的缓存数据 27 | */ 28 | READ_SUCCESS_AFTER_FAIL, 29 | /** 30 | * 当网络请求失败时读取失败(原始网络请求失败)的缓存数据 31 | */ 32 | READ_FAIL_AFTER_FAIL, 33 | /** 34 | * 优先读取成功(原始网络请求成功)的缓存数据,没有缓存则发起网络请求 35 | */ 36 | READ_SUCCESS_AT_ONCE, 37 | /** 38 | * 优先读取失败(原始网络请求失败)的缓存数据,没有缓存则发起网络请求 39 | */ 40 | READ_FAIL_AT_ONCE 41 | } 42 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/listener/SupportCallback.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.listener; 2 | 3 | import android.os.Bundle; 4 | import android.util.ArrayMap; 5 | 6 | import com.cloudling.request.service.base.BaseService; 7 | 8 | /** 9 | * 描述: 接口请求支持回调 10 | * 联系:1966353889@qq.com 11 | * 日期: 2021/12/3 12 | */ 13 | public interface SupportCallback { 14 | /** 15 | * 设置当前接口请求服务类 16 | */ 17 | void setService(BaseService service); 18 | 19 | /** 20 | * 设置当前接口请求服务类 21 | */ 22 | void setService(BaseService service, boolean isDisableProxy); 23 | 24 | /** 25 | * 设置请求头 26 | */ 27 | void headers(ArrayMap headers); 28 | 29 | /** 30 | * 设置请求头 31 | */ 32 | void header(String key, Object value); 33 | 34 | /** 35 | * 获取连接超时时间 36 | */ 37 | long getConnectTimeout(); 38 | 39 | /** 40 | * 获取读取超时时间 41 | */ 42 | long getReadTimeout(); 43 | 44 | /** 45 | * 获取写入超时时间 46 | */ 47 | long getWriteTimeout(); 48 | 49 | /** 50 | * 获取host(单服务) 51 | */ 52 | String getHost(); 53 | 54 | /** 55 | * 获取host(微服务) 56 | * 57 | * @param name 微服务服务名 58 | */ 59 | String getHost(String name); 60 | 61 | /** 62 | * 获取配置的请求头 63 | */ 64 | ArrayMap getHeaders(); 65 | 66 | /** 67 | * 用于页面异常关闭保存数据(在Activity对应的生命周期调用) 68 | */ 69 | void onSaveInstanceState(Bundle outState); 70 | 71 | /** 72 | * 用于页面异常关闭恢复数据(在Activity对应的生命周期调用) 73 | */ 74 | void onCreate(Bundle outState); 75 | 76 | /** 77 | * 是否禁用代理 78 | */ 79 | boolean isDisableProxy(); 80 | } 81 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/BaseCacheImpl.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | import android.content.Context; 4 | 5 | import com.cloudling.request.type.OriginalCallback; 6 | 7 | /** 8 | * 描述: 缓存实现约束基类 9 | * 联系: 1966353889@qq.com 10 | * 日期: 2022/1/6 11 | */ 12 | public abstract class BaseCacheImpl { 13 | /** 14 | * 默认保存时长,单位为毫秒(默认值60秒) 15 | */ 16 | protected final long mDefaultDuration = 60 * 1000; 17 | /** 18 | * 上下文 19 | */ 20 | protected Context mContext; 21 | /** 22 | * 最大缓存数量,默认20个 23 | */ 24 | protected int mMaxCacheSize = 20; 25 | 26 | public BaseCacheImpl(Context context) { 27 | mContext = context; 28 | } 29 | 30 | public BaseCacheImpl(Context context, int maxCacheSize) { 31 | mContext = context; 32 | mMaxCacheSize = maxCacheSize; 33 | } 34 | 35 | /** 36 | * 自动清理 37 | */ 38 | public abstract void autoClean(); 39 | 40 | /** 41 | * 新增缓存 42 | * 43 | * @param key 缓存内容的key 44 | * @param value 缓存内容 45 | */ 46 | public abstract void addCache(String key, String value); 47 | 48 | /** 49 | * 新增缓存 50 | * 51 | * @param key 缓存内容的key 52 | * @param value 缓存内容 53 | * @param duration 缓存时长 54 | */ 55 | public abstract void addCache(String key, String value, long duration); 56 | 57 | /** 58 | * 新增缓存 59 | * 60 | * @param key 缓存内容的key 61 | * @param value 缓存内容 62 | * @param duration 缓存时长 63 | * @param timeUnit 时长单位 64 | */ 65 | public abstract void addCache(String key, String value, long duration, TimeUnit timeUnit); 66 | 67 | /** 68 | * 获取缓存 69 | * 70 | * @param key 缓存内容的key 71 | */ 72 | public abstract String getCache(String key); 73 | 74 | /** 75 | * 移除缓存 76 | * 77 | * @param key 缓存内容的key 78 | */ 79 | public abstract void removeCache(String key); 80 | 81 | /** 82 | * 清除全部缓存 83 | */ 84 | public abstract void removeAllCache(); 85 | } 86 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/CacheHelper.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | import android.content.Context; 4 | 5 | import com.cloudling.request.type.OriginalCallback; 6 | 7 | /** 8 | * 描述: 缓存助手 9 | * 联系: 1966353889@qq.com 10 | * 日期: 2022/1/6 11 | */ 12 | public final class CacheHelper { 13 | private Context mContext; 14 | private static CacheHelper mInstance; 15 | private BaseCacheImpl mBaseCacheImpl; 16 | 17 | private CacheHelper() { 18 | } 19 | 20 | public static CacheHelper getInstance() { 21 | if (mInstance == null) { 22 | synchronized (CacheHelper.class) { 23 | if (mInstance == null) { 24 | mInstance = new CacheHelper(); 25 | } 26 | } 27 | } 28 | return mInstance; 29 | } 30 | 31 | public void init(Context context) { 32 | if (mContext == null && context != null) { 33 | mContext = context.getApplicationContext(); 34 | mBaseCacheImpl = new DefaultCacheImpl(mContext); 35 | } 36 | } 37 | 38 | public void init(Context context, BaseCacheImpl baseCacheImpl) { 39 | if (mContext == null && context != null) { 40 | mContext = context.getApplicationContext(); 41 | mBaseCacheImpl = baseCacheImpl; 42 | } 43 | } 44 | 45 | public void addCache(String key, String value) { 46 | if (mBaseCacheImpl != null) { 47 | mBaseCacheImpl.addCache(key, value); 48 | } 49 | } 50 | 51 | public void addCache(String key, String value, long duration) { 52 | if (mBaseCacheImpl != null) { 53 | mBaseCacheImpl.addCache(key, value, duration); 54 | } 55 | } 56 | 57 | public void addCache(String key, String value, long duration, TimeUnit timeUnit) { 58 | if (mBaseCacheImpl != null) { 59 | mBaseCacheImpl.addCache(key, value, duration, timeUnit); 60 | } 61 | } 62 | 63 | public String getCache(String key) { 64 | if (mBaseCacheImpl != null) { 65 | return mBaseCacheImpl.getCache(key); 66 | } 67 | return null; 68 | } 69 | 70 | public void removeCache(String key) { 71 | if (mBaseCacheImpl != null) { 72 | mBaseCacheImpl.removeCache(key); 73 | } 74 | } 75 | 76 | public void removeAllCache() { 77 | if (mBaseCacheImpl != null) { 78 | mBaseCacheImpl.removeAllCache(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/service/base/BaseService.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.service.base; 2 | 3 | import android.text.TextUtils; 4 | import android.util.ArrayMap; 5 | 6 | import com.cloudling.request.listener.TimeoutListener; 7 | 8 | /** 9 | * 描述: 接口请求服务基类 10 | * 联系:1966353889@qq.com 11 | * 日期: 2021/12/3 12 | */ 13 | public abstract class BaseService implements TimeoutListener { 14 | /** 15 | * 连接超时时间 16 | */ 17 | private final long mConnectTimeout; 18 | /** 19 | * 读取超时时间 20 | */ 21 | private final long mReadTimeout; 22 | /** 23 | * 写入超时时间 24 | */ 25 | private final long mWriteTimeout; 26 | /** 27 | * 单服务接口host 28 | */ 29 | private final String mHost; 30 | /** 31 | * 微服务键值对 32 | */ 33 | private final ArrayMap mMicroConfig; 34 | /** 35 | * 请求头 36 | */ 37 | private ArrayMap mHeaders; 38 | 39 | public BaseService() { 40 | /*设置连接超时时间*/ 41 | mConnectTimeout = connectTimeout(); 42 | /*设置读取超时时间*/ 43 | mReadTimeout = readTimeout(); 44 | /*设置写入超时时间*/ 45 | mWriteTimeout = writeTimeout(); 46 | /*设置单服务接口host*/ 47 | mHost = setHost(); 48 | /*设置微服务键值对*/ 49 | mMicroConfig = setMicroConfig(); 50 | /*设置请求头*/ 51 | mHeaders = setHeaders(); 52 | } 53 | 54 | /** 55 | * 设置单服务接口host 56 | */ 57 | public abstract String setHost(); 58 | 59 | /** 60 | * 设置微服务键值对(服务名与对应的Host) 61 | */ 62 | public abstract ArrayMap setMicroConfig(); 63 | 64 | /** 65 | * 设置请求头 66 | */ 67 | public abstract ArrayMap setHeaders(); 68 | 69 | /** 70 | * 获取连接超时时间 71 | */ 72 | public long getConnectTimeout() { 73 | return mConnectTimeout; 74 | } 75 | 76 | /** 77 | * 获取读取超时时间 78 | */ 79 | public long getReadTimeout() { 80 | return mReadTimeout; 81 | } 82 | 83 | /** 84 | * 获取写入超时时间 85 | */ 86 | public long getWriteTimeout() { 87 | return mWriteTimeout; 88 | } 89 | 90 | /** 91 | * 获取host(单服务) 92 | */ 93 | public String getHost() { 94 | return mHost; 95 | } 96 | 97 | /** 98 | * 获取host(微服务) 99 | * 100 | * @param name 微服务服务名 101 | */ 102 | public String getHost(String name) { 103 | return mMicroConfig != null && !TextUtils.isEmpty(name) ? mMicroConfig.get(name) : null; 104 | } 105 | 106 | /** 107 | * 获取微服务配置 108 | */ 109 | public ArrayMap getMicroConfig() { 110 | return mMicroConfig; 111 | } 112 | 113 | /** 114 | * 获取请求头 115 | */ 116 | public ArrayMap getHeaders() { 117 | return mHeaders; 118 | } 119 | 120 | /** 121 | * 设置请求头 122 | */ 123 | public void headers(ArrayMap headers) { 124 | mHeaders = headers; 125 | } 126 | 127 | /** 128 | * 设置请求头 129 | */ 130 | public void header(String key, Object value) { 131 | if (mHeaders == null) { 132 | mHeaders = new ArrayMap<>(); 133 | } 134 | mHeaders.put(key, value); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/network/NetworkConfig.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.network; 2 | 3 | import android.os.Bundle; 4 | import android.text.TextUtils; 5 | import android.util.ArrayMap; 6 | 7 | import com.cloudling.request.listener.SupportCallback; 8 | import com.cloudling.request.service.base.BaseService; 9 | 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | import java.util.Iterator; 14 | import java.util.Map; 15 | 16 | /** 17 | * 描述: 网络请求配置类 18 | * 联系:1966353889@qq.com 19 | * 日期: 2021/12/3 20 | */ 21 | public class NetworkConfig implements SupportCallback { 22 | private static volatile NetworkConfig mInstance; 23 | /** 24 | * 接口请求服务类 25 | */ 26 | private BaseService service; 27 | 28 | /** 29 | * 是否禁用代理 30 | */ 31 | private boolean isDisableProxy; 32 | 33 | private NetworkConfig() { 34 | } 35 | 36 | public static NetworkConfig getInstance() { 37 | if (mInstance == null) { 38 | synchronized (NetworkConfig.class) { 39 | if (mInstance == null) { 40 | mInstance = new NetworkConfig(); 41 | } 42 | } 43 | } 44 | return mInstance; 45 | } 46 | 47 | /** 48 | * 获取当前接口请求服务类 49 | */ 50 | private BaseService getService() { 51 | return service; 52 | } 53 | 54 | /** 55 | * 设置当前接口请求服务类 56 | */ 57 | @Override 58 | public void setService(BaseService service) { 59 | this.service = service; 60 | } 61 | 62 | @Override 63 | public void setService(BaseService service, boolean isDisableProxy) { 64 | this.service = service; 65 | this.isDisableProxy = isDisableProxy; 66 | } 67 | 68 | @Override 69 | public void headers(ArrayMap headers) { 70 | if (getService() != null) { 71 | getService().headers(headers); 72 | } 73 | } 74 | 75 | @Override 76 | public void header(String key, Object value) { 77 | if (getService() != null) { 78 | getService().header(key, value); 79 | } 80 | } 81 | 82 | @Override 83 | public long getConnectTimeout() { 84 | return getService() != null ? getService().getConnectTimeout() : 0; 85 | } 86 | 87 | @Override 88 | public long getReadTimeout() { 89 | return getService() != null ? getService().getReadTimeout() : 0; 90 | } 91 | 92 | @Override 93 | public long getWriteTimeout() { 94 | return getService() != null ? getService().getWriteTimeout() : 0; 95 | } 96 | 97 | @Override 98 | public String getHost() { 99 | return getService() != null ? getService().getHost() : null; 100 | } 101 | 102 | @Override 103 | public String getHost(String name) { 104 | return getService() != null ? getService().getHost(name) : null; 105 | } 106 | 107 | @Override 108 | public ArrayMap getHeaders() { 109 | return getService() != null ? getService().getHeaders() : null; 110 | } 111 | 112 | /** 113 | * 用于页面异常关闭保存数据(在Activity对应的生命周期调用) 114 | */ 115 | @Override 116 | public void onSaveInstanceState(Bundle outState) { 117 | if (outState != null) { 118 | BaseService service = getService(); 119 | if (service != null) { 120 | outState.putString("network_config_host", service.getHost()); 121 | outState.putLong("network_config_connectTimeout", service.getConnectTimeout()); 122 | outState.putLong("network_config_readTimeout", service.getReadTimeout()); 123 | outState.putLong("network_config_writeTimeout", service.getWriteTimeout()); 124 | try { 125 | JSONObject microConfig = new JSONObject(); 126 | JSONObject headers = new JSONObject(); 127 | ArrayMap microConfigMap = service.getMicroConfig(); 128 | ArrayMap headersMap = service.getHeaders(); 129 | if (microConfigMap != null) { 130 | for (Map.Entry entry : microConfigMap.entrySet()) { 131 | microConfig.put(entry.getKey(), entry.getValue()); 132 | } 133 | outState.putString("network_config_micro_config", microConfig.toString()); 134 | } 135 | if (headersMap != null) { 136 | for (Map.Entry entry : headersMap.entrySet()) { 137 | headers.put(entry.getKey(), entry.getValue()); 138 | } 139 | outState.putString("network_config_headers", headers.toString()); 140 | } 141 | } catch (JSONException e) { 142 | e.printStackTrace(); 143 | } 144 | outState.putBoolean("network_config_isDisableProxy", isDisableProxy); 145 | } 146 | } 147 | } 148 | 149 | /** 150 | * 用于页面异常关闭恢复数据(在Activity对应的生命周期调用) 151 | */ 152 | @Override 153 | public void onCreate(Bundle outState) { 154 | if (outState != null) { 155 | BaseService service = getService(); 156 | if (service == null) { 157 | service = new BaseService() { 158 | @Override 159 | public String setHost() { 160 | return outState.getString("network_config_host"); 161 | } 162 | 163 | @Override 164 | public ArrayMap setMicroConfig() { 165 | if (!TextUtils.isEmpty(outState.getString("network_config_micro_config"))) { 166 | try { 167 | ArrayMap map = new ArrayMap<>(); 168 | JSONObject jsonObject = new JSONObject(outState.getString("network_config_micro_config")); 169 | Iterator iterator = jsonObject.keys(); 170 | while (iterator.hasNext()) { 171 | String key = iterator.next(); 172 | map.put(key, jsonObject.getString(key)); 173 | } 174 | return map; 175 | } catch (JSONException e) { 176 | e.printStackTrace(); 177 | } 178 | } 179 | return null; 180 | } 181 | 182 | @Override 183 | public ArrayMap setHeaders() { 184 | if (!TextUtils.isEmpty(outState.getString("network_config_headers"))) { 185 | try { 186 | ArrayMap map = new ArrayMap<>(); 187 | JSONObject jsonObject = new JSONObject(outState.getString("network_config_headers")); 188 | Iterator iterator = jsonObject.keys(); 189 | while (iterator.hasNext()) { 190 | String key = iterator.next(); 191 | map.put(key, jsonObject.getString(key)); 192 | } 193 | return map; 194 | } catch (JSONException e) { 195 | e.printStackTrace(); 196 | } 197 | } 198 | return null; 199 | } 200 | 201 | @Override 202 | public long connectTimeout() { 203 | return outState.getLong("network_config_connectTimeout"); 204 | } 205 | 206 | @Override 207 | public long readTimeout() { 208 | return outState.getLong("network_config_readTimeout"); 209 | } 210 | 211 | @Override 212 | public long writeTimeout() { 213 | return outState.getLong("network_config_writeTimeout"); 214 | } 215 | }; 216 | setService(service, outState.getBoolean("network_config_isDisableProxy")); 217 | } 218 | } 219 | } 220 | 221 | @Override 222 | public boolean isDisableProxy() { 223 | return isDisableProxy; 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/DefaultCacheImpl.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.text.TextUtils; 6 | 7 | import com.cloudling.request.network.EasyRequest; 8 | import com.cloudling.request.type.OriginalCallback; 9 | 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | import java.util.ArrayList; 14 | import java.util.Map; 15 | 16 | /** 17 | * 描述: 默认的缓存实现类 18 | * 联系: 1966353889@qq.com 19 | * 日期: 2022/1/6 20 | */ 21 | public final class DefaultCacheImpl extends BaseCacheImpl implements SharedPreferences.OnSharedPreferenceChangeListener { 22 | private SharedPreferences mPreferences; 23 | 24 | public DefaultCacheImpl(Context context) { 25 | super(context); 26 | if (mContext != null) { 27 | mPreferences = mContext.getSharedPreferences("easy_request_cache", Context.MODE_PRIVATE); 28 | mPreferences.registerOnSharedPreferenceChangeListener(this); 29 | } 30 | autoClean(); 31 | } 32 | 33 | public DefaultCacheImpl(Context context, int maxCacheSize) { 34 | super(context, maxCacheSize); 35 | if (mContext != null) { 36 | mPreferences = mContext.getSharedPreferences("easy_request_cache", Context.MODE_PRIVATE); 37 | mPreferences.registerOnSharedPreferenceChangeListener(this); 38 | } 39 | autoClean(); 40 | } 41 | 42 | @Override 43 | public void autoClean() { 44 | if (mPreferences != null 45 | && mPreferences.getAll() != null 46 | && mPreferences.getAll().size() > 0) { 47 | Map map = mPreferences.getAll(); 48 | ArrayList errorList = new ArrayList<>(); 49 | for (Map.Entry entry : map.entrySet()) { 50 | if (entry.getValue() instanceof String) { 51 | try { 52 | JSONObject jsonObject = new JSONObject((String) entry.getValue()); 53 | long timeMillis = jsonObject.optLong("writeTimeMillis") + jsonObject.optLong("saveDuration"); 54 | if (timeMillis < System.currentTimeMillis()) { 55 | /*缓存的数据已过期*/ 56 | errorList.add(entry.getKey()); 57 | } 58 | } catch (JSONException e) { 59 | e.printStackTrace(); 60 | errorList.add(entry.getKey()); 61 | } 62 | } else { 63 | errorList.add(entry.getKey()); 64 | } 65 | } 66 | if (errorList.size() > 0) { 67 | for (int i = 0, size = errorList.size(); i < size; i++) { 68 | EasyRequest.getInstance().logD("[DefaultCacheImpl-autoClean]\nerrorKey:" + errorList.get(i) + "\n自动清理缓存"); 69 | mPreferences.edit().remove(errorList.get(i)).apply(); 70 | } 71 | } 72 | } 73 | } 74 | 75 | @Override 76 | public void addCache(String key, String value) { 77 | if (isCanOption(key, value)) { 78 | StringBuilder builder = new StringBuilder() 79 | .append("{") 80 | .append("\"writeTimeMillis\":") 81 | .append(System.currentTimeMillis()) 82 | .append(",\"saveDuration\":") 83 | .append(mDefaultDuration) 84 | .append(",\"value\":") 85 | .append("\"") 86 | .append(AesHelper.encryptAsString(value)) 87 | .append("\"}"); 88 | mPreferences.edit().putString(key, builder.toString()).apply(); 89 | } 90 | } 91 | 92 | @Override 93 | public void addCache(String key, String value, long duration) { 94 | if (isCanOption(key, value)) { 95 | StringBuilder builder = new StringBuilder() 96 | .append("{") 97 | .append("\"writeTimeMillis\":") 98 | .append(System.currentTimeMillis()) 99 | .append(",\"saveDuration\":") 100 | .append(duration) 101 | .append(",\"value\":") 102 | .append("\"") 103 | .append(AesHelper.encryptAsString(value)) 104 | .append("\"}"); 105 | mPreferences.edit().putString(key, builder.toString()).apply(); 106 | } 107 | } 108 | 109 | @Override 110 | public void addCache(String key, String value, long duration, TimeUnit timeUnit) { 111 | if (isCanOption(key, value)) { 112 | StringBuilder builder = new StringBuilder() 113 | .append("{") 114 | .append("\"writeTimeMillis\":") 115 | .append(System.currentTimeMillis()) 116 | .append(",\"saveDuration\":") 117 | .append(getSaveDuration(duration, timeUnit)) 118 | .append(",\"value\":") 119 | .append("\"") 120 | .append(AesHelper.encryptAsString(value)) 121 | .append("\"}"); 122 | mPreferences.edit().putString(key, builder.toString()).apply(); 123 | } 124 | } 125 | 126 | @Override 127 | public String getCache(String key) { 128 | if (isCanOption(key)) { 129 | String result = mPreferences.getString(key, null); 130 | if (!TextUtils.isEmpty(result)) { 131 | try { 132 | JSONObject jsonObject = new JSONObject(result); 133 | long timeMillis = jsonObject.optLong("writeTimeMillis") + jsonObject.optLong("saveDuration"); 134 | if (timeMillis < System.currentTimeMillis()) { 135 | /*缓存的数据已过期*/ 136 | EasyRequest.getInstance().logD("[DefaultCacheImpl-getCache]\nkey:" + key + "\n缓存的数据已过期->移除缓存"); 137 | mPreferences.edit().remove(key).apply(); 138 | } else { 139 | return AesHelper.decryptAsString(jsonObject.optString("value")); 140 | } 141 | } catch (JSONException e) { 142 | e.printStackTrace(); 143 | EasyRequest.getInstance().logD("[DefaultCacheImpl-getCache]\nkey:" + key + "\n读取缓存异常:" + e.toString() + "\n移除缓存"); 144 | mPreferences.edit().remove(key).apply(); 145 | } 146 | } else { 147 | EasyRequest.getInstance().logD("[DefaultCacheImpl-getCache]\nkey:" + key + "\n无缓存"); 148 | } 149 | } 150 | return null; 151 | } 152 | 153 | @Override 154 | public void removeCache(String key) { 155 | if (isCanOption(key)) { 156 | mPreferences.edit().remove(key).apply(); 157 | } 158 | } 159 | 160 | @Override 161 | public void removeAllCache() { 162 | if (mPreferences != null) { 163 | mPreferences.edit().clear().apply(); 164 | } 165 | } 166 | 167 | @Override 168 | public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { 169 | if (!TextUtils.isEmpty(key) && mMaxCacheSize > 0 && preferences != null 170 | && preferences.getAll() != null 171 | && preferences.getAll().size() > mMaxCacheSize) { 172 | Map map = preferences.getAll(); 173 | long minTimeMillis = -1; 174 | String targetKey = null; 175 | ArrayList errorList = new ArrayList<>(); 176 | for (Map.Entry entry : map.entrySet()) { 177 | if (entry.getValue() instanceof String) { 178 | try { 179 | JSONObject jsonObject = new JSONObject((String) entry.getValue()); 180 | long writeTimeMillis = jsonObject.optLong("writeTimeMillis"); 181 | if (minTimeMillis == -1 || writeTimeMillis < minTimeMillis) { 182 | minTimeMillis = writeTimeMillis; 183 | targetKey = entry.getKey(); 184 | } 185 | } catch (JSONException e) { 186 | e.printStackTrace(); 187 | errorList.add(entry.getKey()); 188 | } 189 | } else { 190 | errorList.add(entry.getKey()); 191 | } 192 | } 193 | if (targetKey != null) { 194 | EasyRequest.getInstance().logD("[DefaultCacheImpl-onSharedPreferenceChanged]\ntargetKey:" + targetKey + "\n移除初始添加的缓存"); 195 | preferences.edit().remove(targetKey).apply(); 196 | } 197 | if (errorList.size() > 0) { 198 | for (int i = 0, size = errorList.size(); i < size; i++) { 199 | EasyRequest.getInstance().logD("[DefaultCacheImpl-onSharedPreferenceChanged]\nerrorKey:" + errorList.get(i) + "\n移除解析错误的缓存"); 200 | preferences.edit().remove(errorList.get(i)).apply(); 201 | } 202 | } 203 | } 204 | } 205 | 206 | private boolean isCanOption(String key, String value) { 207 | return mPreferences != null && !TextUtils.isEmpty(key) && !TextUtils.isEmpty(value); 208 | } 209 | 210 | private boolean isCanOption(String key) { 211 | return mPreferences != null && !TextUtils.isEmpty(key); 212 | } 213 | 214 | private long getSaveDuration(long duration, TimeUnit timeUnit) { 215 | if (timeUnit != null && duration > 0) { 216 | if (timeUnit == TimeUnit.SECONDS) { 217 | return duration * 1000; 218 | } else if (timeUnit == TimeUnit.MINUTES) { 219 | return duration * 1000 * 60; 220 | } else if (timeUnit == TimeUnit.HOURS) { 221 | return duration * 1000 * 60 * 60; 222 | } else if (timeUnit == TimeUnit.DAYS) { 223 | return duration * 1000 * 60 * 60 * 24; 224 | } 225 | return duration; 226 | } 227 | return mDefaultDuration; 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/delegate/OkHttpDelegate.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.delegate; 2 | 3 | import android.text.TextUtils; 4 | import android.util.ArrayMap; 5 | 6 | import com.cloudling.request.network.BaseRequest; 7 | import com.cloudling.request.network.EasyRequest; 8 | import com.cloudling.request.network.NetworkConfig; 9 | import com.cloudling.request.type.Method; 10 | import com.cloudling.request.type.RequestType; 11 | 12 | import org.apache.http.conn.ConnectTimeoutException; 13 | import org.jetbrains.annotations.NotNull; 14 | import org.json.JSONObject; 15 | 16 | import java.io.IOException; 17 | import java.net.Proxy; 18 | import java.net.SocketTimeoutException; 19 | import java.util.Map; 20 | import java.util.concurrent.ConcurrentHashMap; 21 | import java.util.concurrent.TimeUnit; 22 | 23 | import okhttp3.Call; 24 | import okhttp3.Callback; 25 | import okhttp3.HttpUrl; 26 | import okhttp3.Interceptor; 27 | import okhttp3.MediaType; 28 | import okhttp3.OkHttpClient; 29 | import okhttp3.Request; 30 | import okhttp3.RequestBody; 31 | import okhttp3.Response; 32 | 33 | /** 34 | * 描述: OkHttp请求代理 35 | * 联系:1966353889@qq.com 36 | * 日期: 2021/12/7 37 | */ 38 | public class OkHttpDelegate implements RequestDelegate { 39 | /** 40 | * okHttp请求实例 41 | */ 42 | private OkHttpClient mOkHttpClient; 43 | /** 44 | * 缓存请求 45 | */ 46 | private ConcurrentHashMap> mRequestMap; 47 | 48 | public OkHttpDelegate() { 49 | mRequestMap = new ConcurrentHashMap<>(); 50 | OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); 51 | if (isDisableProxy()) { 52 | builder.proxy(Proxy.NO_PROXY); 53 | } 54 | mOkHttpClient = builder 55 | .connectTimeout(NetworkConfig.getInstance().getConnectTimeout(), TimeUnit.SECONDS) 56 | .readTimeout(NetworkConfig.getInstance().getReadTimeout(), TimeUnit.SECONDS) 57 | .writeTimeout(NetworkConfig.getInstance().getWriteTimeout(), TimeUnit.SECONDS) 58 | .addInterceptor(new Interceptor() { 59 | @Override 60 | public @NotNull 61 | Response intercept(@NotNull Chain chain) throws IOException { 62 | Request.Builder mBuilder = chain.request().newBuilder().removeHeader("Accept-Encoding"); 63 | ArrayMap headersMap = NetworkConfig.getInstance().getHeaders(); 64 | if (headersMap != null) { 65 | for (Map.Entry entry : headersMap.entrySet()) { 66 | if (!TextUtils.isEmpty(entry.getKey()) && entry.getValue() != null) { 67 | mBuilder.header(entry.getKey(), (String) entry.getValue()); 68 | } 69 | } 70 | } 71 | return chain.proceed(mBuilder.build()); 72 | } 73 | }) 74 | .build(); 75 | } 76 | 77 | public OkHttpDelegate(boolean retryOnConnectionFailure) { 78 | mRequestMap = new ConcurrentHashMap<>(); 79 | OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); 80 | if (isDisableProxy()) { 81 | builder.proxy(Proxy.NO_PROXY); 82 | } 83 | mOkHttpClient = builder 84 | .retryOnConnectionFailure(retryOnConnectionFailure) 85 | .connectTimeout(NetworkConfig.getInstance().getConnectTimeout(), TimeUnit.SECONDS) 86 | .readTimeout(NetworkConfig.getInstance().getReadTimeout(), TimeUnit.SECONDS) 87 | .writeTimeout(NetworkConfig.getInstance().getWriteTimeout(), TimeUnit.SECONDS) 88 | .addInterceptor(new Interceptor() { 89 | @Override 90 | public @NotNull 91 | Response intercept(@NotNull Chain chain) throws IOException { 92 | Request.Builder mBuilder = chain.request().newBuilder().removeHeader("Accept-Encoding"); 93 | ArrayMap headersMap = NetworkConfig.getInstance().getHeaders(); 94 | if (headersMap != null) { 95 | for (Map.Entry entry : headersMap.entrySet()) { 96 | if (!TextUtils.isEmpty(entry.getKey()) && entry.getValue() != null) { 97 | mBuilder.header(entry.getKey(), (String) entry.getValue()); 98 | } 99 | } 100 | } 101 | return chain.proceed(mBuilder.build()); 102 | } 103 | }) 104 | .build(); 105 | } 106 | 107 | public OkHttpDelegate(OkHttpClient okHttpClient) { 108 | mRequestMap = new ConcurrentHashMap<>(); 109 | if (okHttpClient != null && okHttpClient.proxy() != Proxy.NO_PROXY && isDisableProxy()) { 110 | this.mOkHttpClient = okHttpClient.newBuilder().proxy(Proxy.NO_PROXY).build(); 111 | } else { 112 | this.mOkHttpClient = okHttpClient; 113 | } 114 | } 115 | 116 | @Override 117 | public void request(BaseRequest config) { 118 | if (config == null) { 119 | return; 120 | } 121 | mRequestMap.put(config.getUUid(), config); 122 | if (config.getListener() != null 123 | && mRequestMap.get(config.getUUid()) != null) { 124 | config.getListener().requestBefore(); 125 | } 126 | Request.Builder builder = new Request.Builder(); 127 | if (config.getMethod() == Method.GET || config.getType() == RequestType.GET) { 128 | if (config.getParams() != null) { 129 | HttpUrl.Builder urlBuilder = HttpUrl.parse(config.getUrl()).newBuilder(); 130 | for (Map.Entry entry : config.getParams().entrySet()) { 131 | urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue())); 132 | } 133 | builder.url(urlBuilder.build()); 134 | } else { 135 | builder.url(config.getUrl()); 136 | } 137 | } else if (config.getType() == RequestType.POST 138 | || config.getType() == RequestType.PUT 139 | || config.getType() == RequestType.DELETE 140 | || config.getMethod() == Method.POST 141 | || config.getMethod() == Method.PUT 142 | || config.getMethod() == Method.DELETE) { 143 | builder.url(config.getUrl()); 144 | RequestBody body; 145 | if (config.getParams() != null) { 146 | MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); 147 | String json = new JSONObject(config.getParams()).toString(); 148 | body = RequestBody.create(mediaType, json); 149 | } else { 150 | body = RequestBody.create(null, ""); 151 | } 152 | if (config.getMethod() == Method.POST || config.getType() == RequestType.POST) { 153 | builder.post(body); 154 | } else if (config.getMethod() == Method.PUT || config.getType() == RequestType.PUT) { 155 | builder.put(body); 156 | } else if (config.getMethod() == Method.DELETE || config.getType() == RequestType.DELETE) { 157 | builder.delete(body); 158 | } 159 | } else { 160 | if (mRequestMap.get(config.getUUid()) != null) { 161 | if (config.getListener() != null) { 162 | String methodName = config.getMethod() != null ? config.getMethod().name() : (config.getType() != null ? config.getType().name() : null); 163 | config.getListener().onFail("未知的请求方法-" + methodName); 164 | config.getListener().requestAfter(); 165 | } 166 | removeByUUID(config.getUUid()); 167 | } 168 | return; 169 | } 170 | Request request = builder.build(); 171 | mOkHttpClient.newCall(request).enqueue(new Callback() { 172 | @Override 173 | public void onFailure(@NotNull Call call, @NotNull IOException e) { 174 | String result; 175 | if (e instanceof SocketTimeoutException) { 176 | /*响应超时*/ 177 | result = "SocketTimeoutException"; 178 | } else if (e instanceof ConnectTimeoutException) { 179 | /*请求超时*/ 180 | result = "ConnectTimeoutException"; 181 | } else { 182 | result = e.toString(); 183 | } 184 | if (mRequestMap.get(config.getUUid()) != null) { 185 | if (config.getListener() != null) { 186 | config.getListener().onFail(result); 187 | config.getListener().requestAfter(); 188 | } 189 | removeByUUID(config.getUUid()); 190 | } else { 191 | EasyRequest.getInstance().logE("[onFailure-no callback]result:" + result); 192 | } 193 | } 194 | 195 | @Override 196 | public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { 197 | String result = response.body() != null ? response.body().string() : null; 198 | if (mRequestMap.get(config.getUUid()) != null) { 199 | if (config.getListener() != null) { 200 | if (response.isSuccessful()) { 201 | config.getListener().onSuccess(result); 202 | } else { 203 | config.getListener().onFail(result); 204 | } 205 | config.getListener().requestAfter(); 206 | } 207 | removeByUUID(config.getUUid()); 208 | } else { 209 | EasyRequest.getInstance().logI("[onResponse-no callback]result:" + result); 210 | } 211 | } 212 | }); 213 | 214 | } 215 | 216 | @Override 217 | public void remove(BaseRequest config) { 218 | if (config != null) { 219 | mRequestMap.remove(config.getUUid()); 220 | } 221 | } 222 | 223 | @Override 224 | public void removeByTag(String TAG) { 225 | if (!TextUtils.isEmpty(TAG)) { 226 | for (String key : mRequestMap.keySet()) { 227 | if (mRequestMap.get(key) != null 228 | && !TextUtils.isEmpty(mRequestMap.get(key).getTAG()) 229 | && mRequestMap.get(key).getTAG().equals(TAG)) { 230 | mRequestMap.remove(key); 231 | } 232 | } 233 | } 234 | } 235 | 236 | @Override 237 | public void removeByUUID(String uuid) { 238 | mRequestMap.remove(uuid); 239 | } 240 | 241 | @Override 242 | public boolean isDisableProxy() { 243 | return NetworkConfig.getInstance().isDisableProxy(); 244 | } 245 | 246 | } 247 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/network/EasyRequest.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.network; 2 | 3 | import android.os.Handler; 4 | import android.os.Looper; 5 | import android.text.TextUtils; 6 | import android.util.Log; 7 | 8 | import com.cloudling.request.BuildConfig; 9 | import com.cloudling.request.cache.AesHelper; 10 | import com.cloudling.request.cache.CacheHelper; 11 | import com.cloudling.request.cache.CacheType; 12 | import com.cloudling.request.cache.ReadCacheType; 13 | import com.cloudling.request.delegate.OkHttpDelegate; 14 | import com.cloudling.request.delegate.RequestDelegate; 15 | import com.cloudling.request.listener.ILog; 16 | import com.cloudling.request.type.MockRequestCallbackType; 17 | import com.cloudling.request.type.OriginalCallback; 18 | 19 | import org.json.JSONArray; 20 | import org.json.JSONObject; 21 | 22 | /** 23 | * 描述: 网络请求发起类(默认通过okhttp实现) 24 | * 联系:1966353889@qq.com 25 | * 日期: 2021/12/7 26 | */ 27 | public class EasyRequest { 28 | private final String TAG = "EasyRequest"; 29 | private static volatile EasyRequest mInstance; 30 | /** 31 | * 请求代理 32 | */ 33 | private RequestDelegate mRequestDelegate; 34 | /** 35 | * 日志输出类 36 | */ 37 | private ILog mILog; 38 | /** 39 | * 是否调试模式 40 | */ 41 | private boolean debug = BuildConfig.DEBUG; 42 | private Handler mHandler; 43 | 44 | private EasyRequest() { 45 | /*默认设置请求代理为okHttp*/ 46 | mRequestDelegate = new OkHttpDelegate(); 47 | mHandler = new Handler(Looper.getMainLooper()); 48 | mILog = new ILog() { 49 | @Override 50 | public void onLogVerbose(String TAG, String log) { 51 | if (debug) { 52 | Log.v(TAG, log); 53 | } 54 | } 55 | 56 | @Override 57 | public void onLogDebug(String TAG, String log) { 58 | if (debug) { 59 | Log.d(TAG, log); 60 | } 61 | } 62 | 63 | @Override 64 | public void onLogInfo(String TAG, String log) { 65 | if (debug) { 66 | Log.i(TAG, log); 67 | } 68 | } 69 | 70 | @Override 71 | public void onLogWarn(String TAG, String log) { 72 | if (debug) { 73 | Log.w(TAG, log); 74 | } 75 | } 76 | 77 | @Override 78 | public void onLogError(String TAG, String log) { 79 | if (debug) { 80 | Log.e(TAG, log); 81 | } 82 | } 83 | }; 84 | } 85 | 86 | public Handler getHandler() { 87 | return mHandler; 88 | } 89 | 90 | /** 91 | * 延时处理任务 92 | */ 93 | private void delayTask(Handler handler, long delayMillis, Runnable runnable) { 94 | if (delayMillis > 0) { 95 | handler.postDelayed(runnable, delayMillis); 96 | } else { 97 | handler.post(runnable); 98 | } 99 | } 100 | 101 | public static EasyRequest getInstance() { 102 | if (mInstance == null) { 103 | synchronized (EasyRequest.class) { 104 | if (mInstance == null) { 105 | mInstance = new EasyRequest(); 106 | } 107 | } 108 | } 109 | return mInstance; 110 | } 111 | 112 | /** 113 | * 设置是否打开调试模式 114 | */ 115 | public void enableDebug(boolean debug) { 116 | this.debug = debug; 117 | if (canPrintLog()) { 118 | logD("[enableDebug]"); 119 | } 120 | } 121 | 122 | /** 123 | * 设置对应的log处理类 124 | */ 125 | public void setILog(ILog log) { 126 | if (log != null) { 127 | mILog = log; 128 | if (canPrintLog()) { 129 | logD("[setILog]"); 130 | } 131 | } 132 | } 133 | 134 | /** 135 | * 设置请求代理 136 | */ 137 | public void setRequestDelegate(RequestDelegate delegate) { 138 | mRequestDelegate = delegate; 139 | if (canPrintLog() && delegate != null) { 140 | logD("[setRequestDelegate]" + delegate.getClass().getName()); 141 | } 142 | } 143 | 144 | /** 145 | * 打印log 146 | */ 147 | public void logV(String log) { 148 | if (canPrintLog()) { 149 | mILog.onLogVerbose(TAG, log); 150 | } 151 | } 152 | 153 | /** 154 | * 打印log 155 | */ 156 | public void logV(String TAG, String log) { 157 | if (canPrintLog()) { 158 | mILog.onLogVerbose(TAG, log); 159 | } 160 | } 161 | 162 | /** 163 | * 打印log 164 | */ 165 | public void logD(String log) { 166 | if (canPrintLog()) { 167 | mILog.onLogDebug(TAG, log); 168 | } 169 | } 170 | 171 | /** 172 | * 打印log 173 | */ 174 | public void logD(String TAG, String log) { 175 | if (canPrintLog()) { 176 | mILog.onLogDebug(TAG, log); 177 | } 178 | } 179 | 180 | /** 181 | * 打印log 182 | */ 183 | public void logI(String log) { 184 | if (canPrintLog()) { 185 | mILog.onLogInfo(TAG, log); 186 | } 187 | } 188 | 189 | /** 190 | * 打印log 191 | */ 192 | public void logI(String TAG, String log) { 193 | if (canPrintLog()) { 194 | mILog.onLogInfo(TAG, log); 195 | } 196 | } 197 | 198 | /** 199 | * 打印log 200 | */ 201 | public void logW(String log) { 202 | if (canPrintLog()) { 203 | mILog.onLogWarn(TAG, log); 204 | } 205 | } 206 | 207 | /** 208 | * 打印log 209 | */ 210 | public void logW(String TAG, String log) { 211 | if (canPrintLog()) { 212 | mILog.onLogWarn(TAG, log); 213 | } 214 | } 215 | 216 | /** 217 | * 打印log 218 | */ 219 | public void logE(String log) { 220 | if (canPrintLog()) { 221 | mILog.onLogError(TAG, log); 222 | } 223 | } 224 | 225 | /** 226 | * 打印log 227 | */ 228 | public void logE(String TAG, String log) { 229 | if (canPrintLog()) { 230 | mILog.onLogError(TAG, log); 231 | } 232 | } 233 | 234 | 235 | /** 236 | * 是否可输出调试日志 237 | */ 238 | public boolean canPrintLog() { 239 | return debug && mILog != null; 240 | } 241 | 242 | /** 243 | * 判断是否为json 244 | */ 245 | public boolean isJson(String result) { 246 | if (TextUtils.isEmpty(result)) { 247 | return false; 248 | } 249 | boolean isJsonObject = true; 250 | boolean isJsonArray = true; 251 | try { 252 | JSONObject jsonObject = new JSONObject(result); 253 | } catch (Exception e) { 254 | isJsonObject = false; 255 | } 256 | try { 257 | JSONArray jsonArray = new JSONArray(result); 258 | } catch (Exception e) { 259 | isJsonArray = false; 260 | } 261 | if (!isJsonObject && !isJsonArray) { 262 | return false; 263 | } 264 | return true; 265 | } 266 | 267 | public void request(BaseRequest config) { 268 | if (canPrintLog() && config != null) { 269 | StringBuilder builder = new StringBuilder(); 270 | builder.append("[request]") 271 | .append("url:") 272 | .append(config.getUrl()) 273 | .append(",method:") 274 | .append(config.getMethod() != null ? config.getMethod().name() : (config.getType() != null ? config.getType().name() : null)) 275 | .append(",params:") 276 | .append(config.params != null ? new JSONObject(config.params).toString() : null); 277 | logD(builder.toString()); 278 | } 279 | if (config != null && config.mockRequest != null && config.getListener() != null) { 280 | /*模拟请求的不允许缓存数据,因为我们缓存的是真实网络请求返回的数据*/ 281 | config.cacheType = CacheType.NO; 282 | /*模拟请求的不允许读取缓存数据,因为取的数据是我们自己配置的*/ 283 | config.readCacheType = ReadCacheType.NO; 284 | delayTask(EasyRequest.getInstance().getHandler(), 0, new Runnable() { 285 | @Override 286 | public void run() { 287 | config.getListener().requestBefore(); 288 | } 289 | }); 290 | delayTask(EasyRequest.getInstance().getHandler(), config.mockRequest.requestDuration() * 1000L, new Runnable() { 291 | @Override 292 | public void run() { 293 | if (config.mockRequest.callbackType() == MockRequestCallbackType.SUCCESS) { 294 | config.getListener().onSuccess(config.mockRequest.result()); 295 | } else if (config.mockRequest.callbackType() == MockRequestCallbackType.FAIL) { 296 | config.getListener().onFail(config.mockRequest.result()); 297 | } 298 | config.getListener().requestAfter(); 299 | } 300 | }); 301 | } else { 302 | if (config != null && (config.readCacheType == ReadCacheType.READ_SUCCESS_AT_ONCE || config.readCacheType == ReadCacheType.READ_FAIL_AT_ONCE)) { 303 | String readKey = AesHelper.encryptAsString(config.getCacheKey() + (config.readCacheType == ReadCacheType.READ_SUCCESS_AT_ONCE ? OriginalCallback.SUCCESS.name() : OriginalCallback.FAILURE.name())); 304 | String cache = CacheHelper.getInstance().getCache(readKey); 305 | EasyRequest.getInstance().logD("[request]\n读取缓存->readKey:" + readKey + "\n读取缓存->cache:" + cache); 306 | if (!TextUtils.isEmpty(cache)) { 307 | EasyRequest.getInstance().logD("[request]\n读取缓存成功"); 308 | /*不允许缓存数据,因为我们已经直接读取缓存的数据*/ 309 | config.cacheType = CacheType.NO; 310 | delayTask(EasyRequest.getInstance().getHandler(), 0, new Runnable() { 311 | @Override 312 | public void run() { 313 | config.getListener().requestBefore(); 314 | if (config.readCacheType == ReadCacheType.READ_SUCCESS_AT_ONCE) { 315 | config.getListener().onSuccess(cache); 316 | } else if (config.readCacheType == ReadCacheType.READ_FAIL_AT_ONCE) { 317 | config.getListener().onFail(cache); 318 | } 319 | config.getListener().requestAfter(); 320 | } 321 | }); 322 | } else { 323 | /*无缓存的数据,直接发起网络请求*/ 324 | mRequestDelegate.request(config); 325 | } 326 | } else { 327 | mRequestDelegate.request(config); 328 | } 329 | } 330 | } 331 | 332 | public void remove(BaseRequest config) { 333 | mRequestDelegate.remove(config); 334 | if (canPrintLog() && config != null) { 335 | StringBuilder builder = new StringBuilder(); 336 | builder.append("[remove]") 337 | .append("url:") 338 | .append(config.getUrl()) 339 | .append(",method:") 340 | .append(config.getMethod() != null ? config.getMethod().name() : (config.getType() != null ? config.getType().name() : null)) 341 | .append(",TAG:") 342 | .append(config.getTAG()) 343 | .append(",uuid:") 344 | .append(config.getUUid()); 345 | logD(builder.toString()); 346 | } 347 | } 348 | 349 | public void removeByTag(String TAG) { 350 | mRequestDelegate.removeByTag(TAG); 351 | if (canPrintLog()) { 352 | StringBuilder builder = new StringBuilder(); 353 | builder.append("[removeByTag]") 354 | .append("TAG:") 355 | .append(TAG); 356 | logD(builder.toString()); 357 | } 358 | } 359 | 360 | public void removeByUUID(String uuid) { 361 | mRequestDelegate.removeByUUID(uuid); 362 | if (canPrintLog()) { 363 | StringBuilder builder = new StringBuilder(); 364 | builder.append("[removeByUUID]") 365 | .append("uuid:") 366 | .append(uuid); 367 | logD(builder.toString()); 368 | } 369 | } 370 | 371 | } 372 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/cache/AesHelper.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.cache; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.ByteArrayInputStream; 6 | import java.io.ByteArrayOutputStream; 7 | import java.io.IOException; 8 | import java.io.UnsupportedEncodingException; 9 | import java.security.InvalidAlgorithmParameterException; 10 | import java.security.InvalidKeyException; 11 | import java.security.NoSuchAlgorithmException; 12 | import java.util.zip.GZIPInputStream; 13 | import java.util.zip.GZIPOutputStream; 14 | 15 | import javax.crypto.BadPaddingException; 16 | import javax.crypto.Cipher; 17 | import javax.crypto.IllegalBlockSizeException; 18 | import javax.crypto.NoSuchPaddingException; 19 | import javax.crypto.spec.IvParameterSpec; 20 | import javax.crypto.spec.SecretKeySpec; 21 | 22 | /** 23 | * 描述: Aes加解密工具 24 | * 联系:1966353889@qq.com 25 | * 日期: 2022/1/4 26 | */ 27 | public final class AesHelper { 28 | private static final String aes_key = "JpWCaGcSOMHG9U42dgAQ9wePE6NqO53b"; 29 | private static final String aes_iv = "rju78Zz6aSofvhX6"; 30 | private static final String encodingFormat = "UTF-8"; 31 | private static final String algorithm = "AES/CBC/PKCS7Padding"; 32 | 33 | /** 34 | * AES加密 35 | * 36 | * @param sSrc 待加密内容 37 | * @return 返回gzip压缩加密后的byte[] 38 | */ 39 | public static byte[] encryptAsByte(String sSrc) { 40 | return TextUtils.isEmpty(sSrc) ? null : aesEncryptAsByte(sSrc, encodingFormat, algorithm, aes_key, aes_iv); 41 | } 42 | 43 | /** 44 | * AES加密 45 | * 46 | * @param sSrc 待加密内容 47 | * @return 返回gzip压缩加密后的byte[] 48 | */ 49 | public static byte[] encryptAsByte(byte[] sSrc) { 50 | return sSrc == null ? null : encryptAsByte(new String(sSrc)); 51 | } 52 | 53 | /** 54 | * AES加密 55 | * 56 | * @param sSrc 待加密内容 57 | * @return 返回gzip压缩加密后的String 58 | */ 59 | public static String encryptAsString(String sSrc) { 60 | return TextUtils.isEmpty(sSrc) ? sSrc : aesEncryptAsString(sSrc, encodingFormat, algorithm, aes_key, aes_iv); 61 | } 62 | 63 | /** 64 | * AES加密 65 | * 66 | * @param sSrc 待加密内容 67 | * @return 返回gzip压缩加密后的String 68 | */ 69 | public static String encryptAsString(byte[] sSrc) { 70 | return sSrc == null ? null : encryptAsString(new String(sSrc)); 71 | } 72 | 73 | /** 74 | * AES解密 75 | * 76 | * @param sSrc 待解密内容 77 | * @return 返回gzip解压缩解密后的byte[] 78 | */ 79 | public static byte[] decryptAsByte(String sSrc) { 80 | return TextUtils.isEmpty(sSrc) ? null : aesDecryptAsByte(sSrc, encodingFormat, algorithm, aes_key, aes_iv); 81 | } 82 | 83 | /** 84 | * AES解密 85 | * 86 | * @param sSrc 待解密内容 87 | * @return 返回gzip解压缩解密后的byte[] 88 | */ 89 | public static byte[] decryptAsByte(byte[] sSrc) { 90 | return sSrc == null ? null : decryptAsByte(new String(sSrc)); 91 | } 92 | 93 | /** 94 | * AES解密 95 | * 96 | * @param sSrc 待解密内容 97 | * @return 返回gzip解压缩解密后的String 98 | */ 99 | public static String decryptAsString(String sSrc) { 100 | return TextUtils.isEmpty(sSrc) ? sSrc : aesDecryptAsString(sSrc, encodingFormat, algorithm, aes_key, aes_iv); 101 | } 102 | 103 | /** 104 | * AES解密 105 | * 106 | * @param sSrc 待解密内容 107 | * @return 返回gzip解压缩解密后的String 108 | */ 109 | public static String decryptAsString(byte[] sSrc) { 110 | return sSrc == null ? null : decryptAsString(new String(sSrc)); 111 | } 112 | 113 | /** 114 | * AES加密 115 | * 116 | * @param sSrc -- 待加密内容 117 | * @param encodingFormat -- 字符串编码方式 118 | * @param algorithm -- 使用的算法 算法/模式/补码方式, 目前支持ECB和CBC模式 119 | * @param sKey -- 加密密钥 120 | * @param ivParameter -- 偏移量,CBC模式时需要 121 | * @return gzip压缩加密后的byte[] 122 | */ 123 | private static byte[] aesEncryptAsByte(String sSrc, String encodingFormat, String algorithm, String sKey, String ivParameter) { 124 | try { 125 | /*algorithm格式必须为"algorithm/mode/padding"或者"algorithm/",意为"算法/加密模式/填充方式*/ 126 | Cipher cipher = Cipher.getInstance(algorithm); 127 | byte[] raw = sKey.getBytes(encodingFormat); 128 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 129 | /*使用CBC模式,需要一个向量iv,可增加加密算法的强度*/ 130 | IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(encodingFormat)); 131 | if (algorithm.contains("CBC")) { 132 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); 133 | } else { 134 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 135 | } 136 | byte[] gzipResult = compressForGzip(sSrc); 137 | return gzipResult != null ? android.util.Base64.encodeToString(cipher.doFinal(gzipResult), android.util.Base64.DEFAULT).getBytes() : null; 138 | } catch (NoSuchAlgorithmException 139 | | NoSuchPaddingException 140 | | UnsupportedEncodingException 141 | | InvalidAlgorithmParameterException 142 | | InvalidKeyException 143 | | BadPaddingException 144 | | IllegalBlockSizeException e) { 145 | e.printStackTrace(); 146 | } 147 | return null; 148 | } 149 | 150 | /** 151 | * AES加密 152 | * 153 | * @param sSrc -- 待加密内容 154 | * @param encodingFormat -- 字符串编码方式 155 | * @param algorithm -- 使用的算法 算法/模式/补码方式, 目前支持ECB和CBC模式 156 | * @param sKey -- 加密密钥 157 | * @param ivParameter -- 偏移量,CBC模式时需要 158 | * @return gzip压缩加密后的byte[] 159 | */ 160 | private static String aesEncryptAsString(String sSrc, String encodingFormat, String algorithm, String sKey, String ivParameter) { 161 | try { 162 | /*algorithm格式必须为"algorithm/mode/padding"或者"algorithm/",意为"算法/加密模式/填充方式*/ 163 | Cipher cipher = Cipher.getInstance(algorithm); 164 | byte[] raw = sKey.getBytes(encodingFormat); 165 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 166 | /*使用CBC模式,需要一个向量iv,可增加加密算法的强度*/ 167 | IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(encodingFormat)); 168 | if (algorithm.contains("CBC")) { 169 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); 170 | } else { 171 | cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 172 | } 173 | byte[] gzipResult = compressForGzip(sSrc); 174 | return gzipResult != null ? android.util.Base64.encodeToString(cipher.doFinal(gzipResult), android.util.Base64.DEFAULT) : null; 175 | } catch (NoSuchAlgorithmException 176 | | NoSuchPaddingException 177 | | UnsupportedEncodingException 178 | | InvalidAlgorithmParameterException 179 | | InvalidKeyException 180 | | BadPaddingException 181 | | IllegalBlockSizeException e) { 182 | e.printStackTrace(); 183 | } 184 | return null; 185 | } 186 | 187 | /** 188 | * AES解密 189 | * 190 | * @param sSrc -- 待解密Base64字符串 191 | * @param encodingFormat -- 字符串编码方式 192 | * @param algorithm -- 使用的算法 算法/模式/补码方式, 目前支持ECB和CBC模式 193 | * @param sKey -- 加密密钥 194 | * @param ivParameter -- 偏移量,CBC模式时需要 195 | * @return 解密后的字符串 196 | */ 197 | private static String aesDecryptAsString(String sSrc, String encodingFormat, String algorithm, String sKey, String ivParameter) { 198 | try { 199 | byte[] raw = sKey.getBytes(encodingFormat); 200 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 201 | /*algorithm格式必须为"algorithm/mode/padding"或者"algorithm/",意为"算法/加密模式/填充方式*/ 202 | Cipher cipher = Cipher.getInstance(algorithm); 203 | IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(encodingFormat)); 204 | if (algorithm.contains("CBC")) { 205 | cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); 206 | } else { 207 | /*ECB模式*/ 208 | cipher.init(Cipher.DECRYPT_MODE, skeySpec); 209 | } 210 | /*先用base64解密*/ 211 | byte[] encrypted1 = android.util.Base64.decode(sSrc, android.util.Base64.DEFAULT); 212 | byte[] original = cipher.doFinal(encrypted1); 213 | return decompressForGzipAsString(original); 214 | } catch (NoSuchAlgorithmException 215 | | NoSuchPaddingException 216 | | UnsupportedEncodingException 217 | | InvalidAlgorithmParameterException 218 | | InvalidKeyException 219 | | BadPaddingException 220 | | IllegalBlockSizeException e) { 221 | e.printStackTrace(); 222 | } 223 | return null; 224 | } 225 | 226 | /** 227 | * AES解密 228 | * 229 | * @param sSrc -- 待解密Base64字符串 230 | * @param encodingFormat -- 字符串编码方式 231 | * @param algorithm -- 使用的算法 算法/模式/补码方式, 目前支持ECB和CBC模式 232 | * @param sKey -- 加密密钥 233 | * @param ivParameter -- 偏移量,CBC模式时需要 234 | * @return 解密后的字符串 235 | */ 236 | private static byte[] aesDecryptAsByte(String sSrc, String encodingFormat, String algorithm, String sKey, String ivParameter) { 237 | try { 238 | byte[] raw = sKey.getBytes(encodingFormat); 239 | SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 240 | /*algorithm格式必须为"algorithm/mode/padding"或者"algorithm/",意为"算法/加密模式/填充方式*/ 241 | Cipher cipher = Cipher.getInstance(algorithm); 242 | IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes(encodingFormat)); 243 | if (algorithm.contains("CBC")) { 244 | cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); 245 | } else { 246 | /*ECB模式*/ 247 | cipher.init(Cipher.DECRYPT_MODE, skeySpec); 248 | } 249 | /*先用base64解密*/ 250 | byte[] encrypted1 = android.util.Base64.decode(sSrc, android.util.Base64.DEFAULT); 251 | byte[] original = cipher.doFinal(encrypted1); 252 | return decompressForGzipAsByte(original); 253 | } catch (NoSuchAlgorithmException 254 | | NoSuchPaddingException 255 | | UnsupportedEncodingException 256 | | InvalidAlgorithmParameterException 257 | | InvalidKeyException 258 | | BadPaddingException 259 | | IllegalBlockSizeException e) { 260 | e.printStackTrace(); 261 | } 262 | return null; 263 | } 264 | 265 | /** 266 | * Gzip 压缩数据 267 | * 268 | * @param unGzipStr 待压缩的字符串 269 | */ 270 | private static byte[] compressForGzip(String unGzipStr) { 271 | if (TextUtils.isEmpty(unGzipStr)) { 272 | return null; 273 | } 274 | try { 275 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 276 | GZIPOutputStream gzip = new GZIPOutputStream(baos); 277 | gzip.write(unGzipStr.getBytes()); 278 | gzip.close(); 279 | byte[] encode = baos.toByteArray(); 280 | baos.flush(); 281 | baos.close(); 282 | return encode; 283 | } catch (IOException e) { 284 | e.printStackTrace(); 285 | } 286 | return null; 287 | } 288 | 289 | /** 290 | * Gzip解压数据 291 | * 292 | * @param gzipStr 待解压的数据 293 | * @return 返回解压后的String 294 | */ 295 | private static String decompressForGzipAsString(byte[] gzipStr) { 296 | if (gzipStr == null) { 297 | return null; 298 | } 299 | try { 300 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 301 | ByteArrayInputStream in = new ByteArrayInputStream(gzipStr); 302 | GZIPInputStream gzip = new GZIPInputStream(in); 303 | byte[] buffer = new byte[1024]; 304 | int n = 0; 305 | while ((n = gzip.read(buffer, 0, buffer.length)) > 0) { 306 | out.write(buffer, 0, n); 307 | } 308 | gzip.close(); 309 | in.close(); 310 | out.close(); 311 | return out.toString(); 312 | } catch (IOException e) { 313 | e.printStackTrace(); 314 | } 315 | return null; 316 | } 317 | 318 | /** 319 | * Gzip解压数据 320 | * 321 | * @param gzipStr 待解压的数据 322 | * @return 返回解压后的byte[] 323 | */ 324 | private static byte[] decompressForGzipAsByte(byte[] gzipStr) { 325 | if (gzipStr == null) { 326 | return null; 327 | } 328 | try { 329 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 330 | ByteArrayInputStream in = new ByteArrayInputStream(gzipStr); 331 | GZIPInputStream gzip = new GZIPInputStream(in); 332 | byte[] buffer = new byte[1024]; 333 | int n = 0; 334 | while ((n = gzip.read(buffer, 0, buffer.length)) > 0) { 335 | out.write(buffer, 0, n); 336 | } 337 | gzip.close(); 338 | in.close(); 339 | out.close(); 340 | return out.toByteArray(); 341 | } catch (IOException e) { 342 | e.printStackTrace(); 343 | } 344 | return null; 345 | } 346 | } 347 | -------------------------------------------------------------------------------- /easyRequest/src/main/java/com/cloudling/request/network/BaseRequest.java: -------------------------------------------------------------------------------- 1 | package com.cloudling.request.network; 2 | 3 | import android.net.Uri; 4 | import android.text.TextUtils; 5 | 6 | import com.cloudling.request.cache.AesHelper; 7 | import com.cloudling.request.cache.CacheHelper; 8 | import com.cloudling.request.cache.CacheType; 9 | import com.cloudling.request.cache.ReadCacheType; 10 | import com.cloudling.request.cache.TimeUnit; 11 | import com.cloudling.request.converter.BaseConverterFactory; 12 | import com.cloudling.request.listener.ConverterListener; 13 | import com.cloudling.request.listener.MockRequest; 14 | import com.cloudling.request.listener.RequestListener; 15 | import com.cloudling.request.listener.TransformListener; 16 | import com.cloudling.request.listener.WholeConverterListener; 17 | import com.cloudling.request.listener.WholeRequestListener; 18 | import com.cloudling.request.type.Method; 19 | import com.cloudling.request.type.OriginalCallback; 20 | import com.cloudling.request.type.RequestType; 21 | import com.cloudling.request.type.TransformCallbackType; 22 | 23 | import java.util.LinkedHashMap; 24 | import java.util.Map; 25 | import java.util.UUID; 26 | 27 | /** 28 | * 描述: 请求配置 29 | * 联系:1966353889@qq.com 30 | * 日期: 2021/12/29 31 | */ 32 | public class BaseRequest { 33 | /** 34 | * 请求类型 35 | */ 36 | RequestType requestType; 37 | /** 38 | * 请求类型 39 | */ 40 | Method method; 41 | /** 42 | * 请求参数 43 | */ 44 | LinkedHashMap params; 45 | /** 46 | * 请求回调(外部设置) 47 | */ 48 | RequestListener requestListener; 49 | /** 50 | * 真正的请求回调 51 | */ 52 | WholeRequestListener realRequestListener; 53 | /** 54 | * 转换请求结果(可对请求回调参数做包装) 55 | */ 56 | TransformListener transformListener; 57 | /** 58 | * 模拟请求配置 59 | */ 60 | MockRequest mockRequest; 61 | /** 62 | * 单服务host 63 | */ 64 | String host; 65 | /** 66 | * 请求path 67 | */ 68 | String path; 69 | /** 70 | * 微服务名(需在BaseService配置) 71 | */ 72 | String name; 73 | /** 74 | * 唯一值 75 | */ 76 | final String uuid; 77 | final String TAG; 78 | final BaseConverterFactory converterFactory; 79 | final ConverterListener converterListener; 80 | /** 81 | * 缓存的类型 82 | */ 83 | CacheType cacheType; 84 | /** 85 | * 缓存时长 86 | */ 87 | long saveDuration; 88 | /** 89 | * 缓存时长的单位 90 | */ 91 | TimeUnit cacheTimeUnit; 92 | /** 93 | * 读取缓存的类型 94 | */ 95 | ReadCacheType readCacheType; 96 | /** 97 | * 缓存的key(未加密) 98 | */ 99 | String cacheKey; 100 | 101 | private BaseRequest(Builder builder) { 102 | uuid = UUID.randomUUID().toString(); 103 | requestType = builder.requestType; 104 | method = builder.method; 105 | params = builder.params; 106 | requestListener = builder.requestListener; 107 | transformListener = builder.transformListener; 108 | mockRequest = builder.mockRequest; 109 | host = builder.host; 110 | path = builder.path; 111 | name = builder.name; 112 | TAG = builder.TAG; 113 | converterFactory = builder.converterFactory; 114 | converterListener = builder.converterListener; 115 | if (builder.cacheType == null) { 116 | cacheType = CacheType.NO; 117 | } else { 118 | cacheType = builder.cacheType; 119 | } 120 | saveDuration = builder.saveDuration; 121 | if (saveDuration != -1 && builder.cacheTimeUnit == null) { 122 | cacheTimeUnit = TimeUnit.SECONDS; 123 | } else { 124 | cacheTimeUnit = builder.cacheTimeUnit; 125 | } 126 | if (builder.readCacheType == null) { 127 | readCacheType = ReadCacheType.NO; 128 | } else { 129 | readCacheType = builder.readCacheType; 130 | } 131 | cacheKey = builder.cacheKey; 132 | if (requestListener != null || converterListener != null) { 133 | realRequestListener = new WholeRequestListener() { 134 | @Override 135 | public void requestBefore() { 136 | if (EasyRequest.getInstance().getHandler() != null) { 137 | EasyRequest.getInstance().getHandler().post(new Runnable() { 138 | @Override 139 | public void run() { 140 | if (requestListener instanceof WholeRequestListener) { 141 | ((WholeRequestListener) requestListener).requestBefore(); 142 | } 143 | if (converterListener instanceof WholeConverterListener) { 144 | ((WholeConverterListener) converterListener).requestBefore(); 145 | } 146 | } 147 | }); 148 | } else { 149 | if (requestListener instanceof WholeRequestListener) { 150 | ((WholeRequestListener) requestListener).requestBefore(); 151 | } 152 | if (converterListener instanceof WholeConverterListener) { 153 | ((WholeConverterListener) converterListener).requestBefore(); 154 | } 155 | } 156 | } 157 | 158 | @Override 159 | public void requestAfter() { 160 | if (EasyRequest.getInstance().getHandler() != null) { 161 | EasyRequest.getInstance().getHandler().post(new Runnable() { 162 | @Override 163 | public void run() { 164 | if (requestListener instanceof WholeRequestListener) { 165 | ((WholeRequestListener) requestListener).requestAfter(); 166 | } 167 | if (converterListener instanceof WholeConverterListener) { 168 | ((WholeConverterListener) converterListener).requestAfter(); 169 | } 170 | } 171 | }); 172 | } else { 173 | if (requestListener instanceof WholeRequestListener) { 174 | ((WholeRequestListener) requestListener).requestAfter(); 175 | } 176 | if (converterListener instanceof WholeConverterListener) { 177 | ((WholeConverterListener) converterListener).requestAfter(); 178 | } 179 | } 180 | } 181 | 182 | @Override 183 | public void onSuccess(String result) { 184 | if (readCacheType == ReadCacheType.DEFAULT || readCacheType == ReadCacheType.READ_SUCCESS_AFTER_SUCCESS || readCacheType == ReadCacheType.READ_FAIL_AFTER_SUCCESS) { 185 | String readKey = AesHelper.encryptAsString(getCacheKey() + (readCacheType == ReadCacheType.READ_FAIL_AFTER_SUCCESS ? OriginalCallback.FAILURE.name() : OriginalCallback.SUCCESS.name())); 186 | String cache = CacheHelper.getInstance().getCache(readKey); 187 | if (cacheType == CacheType.SOURCE_SUCCESS || cacheType == CacheType.DEFAULT) { 188 | String writeKey = AesHelper.encryptAsString(getCacheKey() + OriginalCallback.SUCCESS.name()); 189 | EasyRequest.getInstance().logD("[BaseRequest-onSuccess]\n执行缓存->原始key:" + getCacheKey() + OriginalCallback.SUCCESS.name() + "\n执行缓存->加密key:" + writeKey); 190 | if (saveDuration == -1) { 191 | CacheHelper.getInstance().addCache(writeKey, result); 192 | } else { 193 | CacheHelper.getInstance().addCache(writeKey, result, saveDuration, cacheTimeUnit); 194 | } 195 | } 196 | EasyRequest.getInstance().logD("[BaseRequest-onSuccess]\n读取缓存->readKey:" + readKey + "\n读取缓存->cache:" + cache); 197 | if (!TextUtils.isEmpty(cache)) { 198 | result = cache; 199 | if (readCacheType == ReadCacheType.READ_FAIL_AFTER_SUCCESS) { 200 | /*当前网络请求成功,但是设置了读取失败的缓存数据,所以需要将请求强制转换为失败*/ 201 | /*这里需要注意的是如果设置了transformListener,这里强制转换结果为失败*/ 202 | if (transformListener == null || transformListener.callbackType() != TransformCallbackType.FAIL) { 203 | EasyRequest.getInstance().logD("BaseRequest-[onSuccess]\n读取缓存成功->强制将结果转为fail"); 204 | TransformListener cacheTransformListener = transformListener; 205 | transformListener = new TransformListener() { 206 | @Override 207 | public String onTransformResult(String result) { 208 | return cacheTransformListener == null ? result : cacheTransformListener instanceof OriginalTransformListener ? (((OriginalTransformListener) cacheTransformListener).onTransformResult(OriginalCallback.FAILURE, result)) : cacheTransformListener.onTransformResult(result); 209 | } 210 | 211 | @Override 212 | public TransformCallbackType callbackType() { 213 | return TransformCallbackType.FAIL; 214 | } 215 | }; 216 | } 217 | } 218 | } 219 | } else { 220 | if (cacheType == CacheType.SOURCE_SUCCESS || cacheType == CacheType.DEFAULT) { 221 | String writeKey = AesHelper.encryptAsString(getCacheKey() + OriginalCallback.SUCCESS.name()); 222 | EasyRequest.getInstance().logD("[BaseRequest-onSuccess]\n执行缓存->原始key:" + getCacheKey() + OriginalCallback.SUCCESS.name() + "\n执行缓存->加密key:" + writeKey); 223 | if (saveDuration == -1) { 224 | CacheHelper.getInstance().addCache(writeKey, result); 225 | } else { 226 | CacheHelper.getInstance().addCache(writeKey, result, saveDuration, cacheTimeUnit); 227 | } 228 | } 229 | } 230 | if (EasyRequest.getInstance().getHandler() != null) { 231 | String finalResult = result; 232 | EasyRequest.getInstance().getHandler().post(new Runnable() { 233 | @Override 234 | public void run() { 235 | if (transformListener != null) { 236 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.SUCCESS, finalResult) : transformListener.onTransformResult(finalResult); 237 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 238 | || transformListener.callbackType() == TransformCallbackType.SUCCESS) { 239 | if (requestListener != null) { 240 | requestListener.onSuccess(realResult); 241 | } 242 | if (converterListener != null && converterFactory != null) { 243 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 244 | } 245 | EasyRequest.getInstance().logI("[onSuccess]\nresult:" + realResult); 246 | } else if (transformListener.callbackType() == TransformCallbackType.FAIL) { 247 | if (requestListener != null) { 248 | requestListener.onFail(realResult); 249 | } 250 | if (converterListener != null && converterFactory != null) { 251 | converterListener.onFail(converterFactory.converterFail(realResult)); 252 | } 253 | EasyRequest.getInstance().logE("[onFail]\nresult:" + realResult); 254 | } 255 | } else { 256 | if (requestListener != null) { 257 | requestListener.onSuccess(finalResult); 258 | } 259 | if (converterListener != null && converterFactory != null) { 260 | converterListener.onSuccess(converterFactory.converterSuccess(finalResult)); 261 | } 262 | EasyRequest.getInstance().logI("[onSuccess]\nresult:" + finalResult); 263 | } 264 | } 265 | }); 266 | } else { 267 | if (transformListener != null) { 268 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.SUCCESS, result) : transformListener.onTransformResult(result); 269 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 270 | || transformListener.callbackType() == TransformCallbackType.SUCCESS) { 271 | if (requestListener != null) { 272 | requestListener.onSuccess(realResult); 273 | } 274 | if (converterListener != null && converterFactory != null) { 275 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 276 | } 277 | EasyRequest.getInstance().logI("[BaseRequest-onSuccess]\nresult:" + realResult); 278 | } else if (transformListener.callbackType() == TransformCallbackType.FAIL) { 279 | if (requestListener != null) { 280 | requestListener.onFail(realResult); 281 | } 282 | if (converterListener != null && converterFactory != null) { 283 | converterListener.onFail(converterFactory.converterFail(realResult)); 284 | } 285 | EasyRequest.getInstance().logE("[BaseRequest-onFail]\nresult:" + realResult); 286 | } 287 | } else { 288 | if (requestListener != null) { 289 | requestListener.onSuccess(result); 290 | } 291 | if (converterListener != null && converterFactory != null) { 292 | converterListener.onSuccess(converterFactory.converterSuccess(result)); 293 | } 294 | EasyRequest.getInstance().logI("[BaseRequest-onSuccess]\nresult:" + result); 295 | } 296 | } 297 | } 298 | 299 | @Override 300 | public void onFail(String result) { 301 | if (readCacheType == ReadCacheType.DEFAULT || readCacheType == ReadCacheType.READ_SUCCESS_AFTER_FAIL || readCacheType == ReadCacheType.READ_FAIL_AFTER_FAIL) { 302 | String readKey = AesHelper.encryptAsString(getCacheKey() + (readCacheType == ReadCacheType.READ_SUCCESS_AFTER_FAIL ? OriginalCallback.SUCCESS.name() : OriginalCallback.FAILURE.name())); 303 | String cache = CacheHelper.getInstance().getCache(readKey); 304 | if (cacheType == CacheType.SOURCE_FAIL || cacheType == CacheType.DEFAULT) { 305 | String writeKey = AesHelper.encryptAsString(getCacheKey() + OriginalCallback.FAILURE.name()); 306 | EasyRequest.getInstance().logD("[BaseRequest-onFail]\n执行缓存->原始key:" + getCacheKey() + OriginalCallback.FAILURE.name() + "\n执行缓存->加密key:" + writeKey); 307 | if (saveDuration == -1) { 308 | CacheHelper.getInstance().addCache(writeKey, result); 309 | } else { 310 | CacheHelper.getInstance().addCache(writeKey, result, saveDuration, cacheTimeUnit); 311 | } 312 | } 313 | EasyRequest.getInstance().logD("[BaseRequest-onFail]\n读取缓存->readKey:" + readKey + "\n读取缓存->cache:" + cache); 314 | if (!TextUtils.isEmpty(cache)) { 315 | result = cache; 316 | if (readCacheType == ReadCacheType.READ_SUCCESS_AFTER_FAIL) { 317 | /*当前网络请求失败,但是设置了读取成功的缓存数据,所以需要将请求强制转换为成功*/ 318 | /*这里需要注意的是如果设置了transformListener,这里强制转换结果为成功*/ 319 | if (transformListener == null || transformListener.callbackType() != TransformCallbackType.SUCCESS) { 320 | EasyRequest.getInstance().logD("[BaseRequest-onFail]\n读取缓存成功->强制将结果转为success"); 321 | TransformListener cacheTransformListener = transformListener; 322 | transformListener = new TransformListener() { 323 | @Override 324 | public String onTransformResult(String result) { 325 | return cacheTransformListener == null ? result : cacheTransformListener instanceof OriginalTransformListener ? (((OriginalTransformListener) cacheTransformListener).onTransformResult(OriginalCallback.SUCCESS, result)) : cacheTransformListener.onTransformResult(result); 326 | } 327 | 328 | @Override 329 | public TransformCallbackType callbackType() { 330 | return TransformCallbackType.SUCCESS; 331 | } 332 | }; 333 | } 334 | } 335 | } 336 | } else { 337 | if (cacheType == CacheType.SOURCE_FAIL || cacheType == CacheType.DEFAULT) { 338 | String writeKey = AesHelper.encryptAsString(getCacheKey() + OriginalCallback.FAILURE.name()); 339 | EasyRequest.getInstance().logD("[BaseRequest-onFail]\n执行缓存->原始key:" + getCacheKey() + OriginalCallback.FAILURE.name() + "\n执行缓存->加密key:" + writeKey); 340 | if (saveDuration == -1) { 341 | CacheHelper.getInstance().addCache(writeKey, result); 342 | } else { 343 | CacheHelper.getInstance().addCache(writeKey, result, saveDuration, cacheTimeUnit); 344 | } 345 | } 346 | } 347 | if (EasyRequest.getInstance().getHandler() != null) { 348 | String finalResult = result; 349 | EasyRequest.getInstance().getHandler().post(new Runnable() { 350 | @Override 351 | public void run() { 352 | if (transformListener != null) { 353 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.FAILURE, finalResult) : transformListener.onTransformResult(finalResult); 354 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 355 | || transformListener.callbackType() == TransformCallbackType.FAIL) { 356 | if (requestListener != null) { 357 | requestListener.onFail(realResult); 358 | } 359 | if (converterListener != null && converterFactory != null) { 360 | converterListener.onFail(converterFactory.converterFail(realResult)); 361 | } 362 | EasyRequest.getInstance().logE("[BaseRequest-onFail]\nresult:" + realResult); 363 | } else if (transformListener.callbackType() == TransformCallbackType.SUCCESS) { 364 | if (requestListener != null) { 365 | requestListener.onSuccess(realResult); 366 | } 367 | if (converterListener != null && converterFactory != null) { 368 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 369 | } 370 | EasyRequest.getInstance().logI("[BaseRequest-onSuccess]\nresult:" + realResult); 371 | } 372 | } else { 373 | if (requestListener != null) { 374 | requestListener.onFail(finalResult); 375 | } 376 | if (converterListener != null && converterFactory != null) { 377 | converterListener.onFail(converterFactory.converterFail(finalResult)); 378 | } 379 | EasyRequest.getInstance().logE("[BaseRequest-onFail]\nresult:" + finalResult); 380 | } 381 | } 382 | }); 383 | } else { 384 | if (transformListener != null) { 385 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.FAILURE, result) : transformListener.onTransformResult(result); 386 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 387 | || transformListener.callbackType() == TransformCallbackType.FAIL) { 388 | if (requestListener != null) { 389 | requestListener.onFail(realResult); 390 | } 391 | if (converterListener != null && converterFactory != null) { 392 | converterListener.onFail(converterFactory.converterFail(realResult)); 393 | } 394 | EasyRequest.getInstance().logE("[BaseRequest-onFail]\nresult:" + realResult); 395 | } else if (transformListener.callbackType() == TransformCallbackType.SUCCESS) { 396 | if (requestListener != null) { 397 | requestListener.onSuccess(realResult); 398 | } 399 | if (converterListener != null && converterFactory != null) { 400 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 401 | } 402 | EasyRequest.getInstance().logI("[BaseRequest-onSuccess]\nresult:" + realResult); 403 | } 404 | } else { 405 | if (requestListener != null) { 406 | requestListener.onFail(result); 407 | } 408 | if (converterListener != null && converterFactory != null) { 409 | converterListener.onFail(converterFactory.converterFail(result)); 410 | } 411 | EasyRequest.getInstance().logE("[BaseRequest-onFail]\nresult:" + result); 412 | } 413 | } 414 | } 415 | }; 416 | } 417 | } 418 | 419 | public String getUUid() { 420 | return uuid; 421 | } 422 | 423 | public String getTAG() { 424 | return TAG; 425 | } 426 | 427 | /** 428 | * @deprecated 推荐使用 {@link #getMethod()} 429 | */ 430 | public RequestType getType() { 431 | return requestType; 432 | } 433 | 434 | public Method getMethod() { 435 | return method; 436 | } 437 | 438 | public LinkedHashMap getParams() { 439 | return params; 440 | } 441 | 442 | public WholeRequestListener getListener() { 443 | return realRequestListener; 444 | } 445 | 446 | public String getUrl() { 447 | StringBuilder builder = new StringBuilder(); 448 | if (!TextUtils.isEmpty(name)) { 449 | builder.append(NetworkConfig.getInstance().getHost(name)); 450 | } else { 451 | builder.append(!TextUtils.isEmpty(host) ? host : NetworkConfig.getInstance().getHost()); 452 | } 453 | if (!TextUtils.isEmpty(path)) { 454 | builder.append(path); 455 | } 456 | return builder.toString(); 457 | } 458 | 459 | /** 460 | * 获取用于缓存的key(未加密) 461 | */ 462 | public String getCacheKey() { 463 | if (!TextUtils.isEmpty(cacheKey)) { 464 | return cacheKey; 465 | } 466 | StringBuilder builder = new StringBuilder(); 467 | if (method != null) { 468 | builder.append(method.name()); 469 | } else if (requestType != null) { 470 | builder.append(requestType.name()); 471 | } 472 | if (!TextUtils.isEmpty(name)) { 473 | builder.append(NetworkConfig.getInstance().getHost(name)); 474 | } else { 475 | builder.append(!TextUtils.isEmpty(host) ? host : NetworkConfig.getInstance().getHost()); 476 | } 477 | if (!TextUtils.isEmpty(path)) { 478 | builder.append(path); 479 | } 480 | if (method == Method.GET || requestType == RequestType.GET) { 481 | if (params != null) { 482 | Uri.Builder uriBuilder = Uri.parse(builder.toString()).buildUpon(); 483 | for (Map.Entry entry : params.entrySet()) { 484 | uriBuilder.appendQueryParameter(entry.getKey(), String.valueOf(entry.getValue())); 485 | } 486 | return uriBuilder.build().toString(); 487 | } 488 | } 489 | return builder.toString(); 490 | } 491 | 492 | public static class Builder { 493 | RequestType requestType; 494 | Method method; 495 | LinkedHashMap params; 496 | RequestListener requestListener; 497 | TransformListener transformListener; 498 | MockRequest mockRequest; 499 | String host; 500 | String path; 501 | String name; 502 | String TAG; 503 | BaseConverterFactory converterFactory; 504 | ConverterListener converterListener; 505 | CacheType cacheType; 506 | long saveDuration; 507 | TimeUnit cacheTimeUnit; 508 | ReadCacheType readCacheType; 509 | String cacheKey; 510 | 511 | /** 512 | * @deprecated 推荐使用 {@link Builder#method(Method)} 513 | */ 514 | public Builder type(RequestType requestType) { 515 | this.requestType = requestType; 516 | return this; 517 | } 518 | 519 | public Builder method(Method method) { 520 | this.method = method; 521 | return this; 522 | } 523 | 524 | public Builder params(LinkedHashMap params) { 525 | this.params = params; 526 | return this; 527 | } 528 | 529 | public Builder listener(RequestListener listener) { 530 | this.requestListener = listener; 531 | return this; 532 | } 533 | 534 | public Builder listener(ConverterListener converterListener) { 535 | this.converterListener = converterListener; 536 | return this; 537 | } 538 | 539 | public Builder transformResult(TransformListener listener) { 540 | this.transformListener = listener; 541 | return this; 542 | } 543 | 544 | public Builder mockRequest(MockRequest mockRequest) { 545 | this.mockRequest = mockRequest; 546 | return this; 547 | } 548 | 549 | public Builder host(String host) { 550 | this.host = host; 551 | return this; 552 | } 553 | 554 | public Builder path(String path) { 555 | this.path = path; 556 | return this; 557 | } 558 | 559 | public Builder name(String name) { 560 | this.name = name; 561 | return this; 562 | } 563 | 564 | public Builder tag(String TAG) { 565 | this.TAG = TAG; 566 | return this; 567 | } 568 | 569 | public Builder addConverterFactory(BaseConverterFactory converterFactory) { 570 | this.converterFactory = converterFactory; 571 | return this; 572 | } 573 | 574 | public Builder cache(CacheType cacheType) { 575 | this.cacheType = cacheType; 576 | this.saveDuration = -1; 577 | return this; 578 | } 579 | 580 | public Builder cache(CacheType cacheType, long saveDuration) { 581 | this.cacheType = cacheType; 582 | this.saveDuration = saveDuration; 583 | return this; 584 | } 585 | 586 | public Builder cache(CacheType cacheType, long saveDuration, TimeUnit timeUnit) { 587 | this.cacheType = cacheType; 588 | this.saveDuration = saveDuration; 589 | this.cacheTimeUnit = timeUnit; 590 | return this; 591 | } 592 | 593 | public Builder readCache(ReadCacheType readCacheType) { 594 | this.readCacheType = readCacheType; 595 | return this; 596 | } 597 | 598 | public Builder cacheKey(String cacheKey) { 599 | this.cacheKey = cacheKey; 600 | return this; 601 | } 602 | 603 | public BaseRequest build() { 604 | return new BaseRequest<>(this); 605 | } 606 | } 607 | 608 | 609 | } 610 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 先看接入步骤: 2 | Step 1. Add the JitPack repository to your build file 3 | Add it in your root build.gradle at the end of repositories: 4 | ```java 5 | allprojects { 6 | repositories { 7 | ... 8 | maven { url 'https://jitpack.io' } 9 | } 10 | } 11 | ``` 12 | Step 2. Add the dependency 13 | ```java 14 | dependencies { 15 | implementation 'com.github.linpeixu:EasyRequest:1.2.9' 16 | //或者implementation 'com.gitlab.linpeixu:easyrequest:1.2.9' 17 | } 18 | ``` 19 | 20 | 若编译过程中报Duplicate class错误,可能是你的项目也引入了Okhttp,尝试在module下的gradle文件下 21 | 的android标签里加入如下: 22 | 23 | ```java 24 | configurations { 25 | cleanedAnnotations 26 | compile.exclude group: 'com.squareup.okio' , module:'okio' 27 | compile.exclude group: 'com.squareup.okhttp3' , module:'okhttp' 28 | } 29 | ``` 30 | 若还有报其它Duplicate class错误,则根据具体的报错信息添加对应的configurations即可。 31 | 32 | 添加支持Gson解析Json的步骤 33 | Step 1. 34 | ```java 35 | dependencies { 36 | implementation 'com.gitlab.linpeixu:GsonConverterFactory:1.0.4 ' 37 | //或者implementation 'com.github.linpeixu:GsonConverterFactory:1.0.4' 38 | } 39 | ``` 40 | Step 2. 41 | 发起网络请求设置的回调listener传ConverterListener(S和F为泛型,分别表示请求成功和失败结果经Gson解析后 42 | 的对象类型),假设我们需将成功的结果转为自定义的Person,则使用实例如下: 43 | ```java 44 | EasyRequest.getInstance().request(new BaseRequest.Builder() 45 | .method(EasyRequest.Method.POST) 46 | .name("user")//设置微服务名,对应的host在NetworkConfig设置server时设置 47 | .path("login/") 48 | .params(new RequestParam() 49 | .put("mobile", "13000000000") 50 | .put("password", "123456") 51 | .build()) 52 | //添加Json转换工厂,具体可传的参数详见GsonConverterFactory工程 53 | .addConverterFactory(new TypeClassConverterFactory() { 54 | @Override 55 | public Class getFailClassType() { 56 | return String.class; 57 | } 58 | 59 | @Override 60 | public Type getSuccessType() { 61 | return new TypeToken() { 62 | }.getType(); 63 | } 64 | }) 65 | .listener(new ConverterListener() { 66 | @Override 67 | public void onSuccess(Person result) { 68 | /*请求成功回调,result为接口返回的json数据经Gson解析后的对象*/ 69 | } 70 | 71 | @Override 72 | public void onFail(String result) { 73 | /*请求失败回调,result为接口返回的数据经Gson解析后的对象*/ 74 | } 75 | }) 76 | .build()); 77 | ``` 78 | 79 | 80 | 之前写过一篇[《Android快速集成网络库功能》](https://www.toutiao.com/i6921606978686943752/),思前想后感觉还是有点局限性,只限于接口端采用微服务架构且app端采用retrofit+okhttp+rxjava的网络框架,这对其它对接入单服务接口类型的app端,或者是采用其它网络框架的app端就不适用了,因此就有了这篇文章。 81 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/810e7dff300441938bbd685552b62ad7.jpg?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54mnLueJpw==,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center) 82 | 83 | 我们还是采用跟[《Android快速集成图片加载(支持更换图片加载库)》](https://www.toutiao.com/i6919748293425791500/)一样的方案,可以使用不用的网络请求策略,才实现支持更换网络加载库,最终发起一个请求只需要一行代码,比如: 84 | 85 | 微服务架构的接口: 86 | 87 | ```java 88 | EasyRequest.getInstance().request(new BaseRequest.Builder() 89 | .method(Method.POST) 90 | .name("user")//设置微服务名,对应的host在NetworkConfig设置server时设置 91 | .path("login/") 92 | .params(new RequestParam() 93 | .put("mobile", "13000000000") 94 | .put("password", "123456") 95 | .build()) 96 | .listener(new RequestListener() { 97 | @Override 98 | public void onSuccess(String result) { 99 | /*请求成功回调,result为接口返回的json数据*/ 100 | } 101 | 102 | @Override 103 | public void onFail(String result) { 104 | /*请求失败回调,result为接口返回的数据*/ 105 | } 106 | }) 107 | .build()); 108 | ``` 109 | 110 | 单服务架构的接口: 111 | 112 | ```java 113 | EasyRequest.getInstance().request(DefaultRequest.create() 114 | .method(Method.POST) 115 | .host("https://api.test.com/")//这里需要说明的是,不设置host时框架会去读取NetworkConfig设置的service的host 116 | .path("login/") 117 | .params(new RequestParam() 118 | .put("mobile", "13000000000") 119 | .put("password", "123456") 120 | .build()) 121 | .listener(new RequestListener() { 122 | @Override 123 | public void onSuccess(String result) { 124 | /*请求成功回调,result为接口返回的json数据*/ 125 | } 126 | 127 | @Override 128 | public void onFail(String result) { 129 | /*请求失败回调,result为接口返回的数据*/ 130 | } 131 | }) 132 | .build()); 133 | ``` 134 | 135 | 在任何你想取消一个请求的时候还可通过以下方法来做到: 136 | 137 | ```java 138 | /*config为EasyRequest.getInstance().request的传参*/ 139 | EasyRequest.getInstance().remove(config); 140 | ``` 141 | 142 | ```java 143 | /*tag为创建config设置的tag*/ 144 | EasyRequest.getInstance().removeByTag(tag); 145 | ``` 146 | 147 | ```java 148 | /*uuid为config初始化时自动设置的uuid*/ 149 | EasyRequest.getInstance().removeByUUID(uuid); 150 | ``` 151 | 扩展 152 | 1、我们支持将网络请求的回调进行转换,比如将成功的网络请求强制转为失败、将网络请求返回的json提前处理等,示例如下 153 | ```java 154 | EasyRequest.getInstance().request(DefaultRequest.create() 155 | .method(Method.POST) 156 | .host("https://api.test.com/") 157 | .path("login/") 158 | .params(new RequestParam() 159 | .put("mobile", "13000000000") 160 | .put("password", "123456") 161 | .build()) 162 | .transformResult(new TransformListener() { 163 | @Override 164 | public String onTransformResult(String result) { 165 | /*转换网络请求返回的数据*/ 166 | return "{\"status\":-1,\"message\":\"请求失败\"}"; 167 | } 168 | 169 | @Override 170 | public TransformCallbackType callbackType() { 171 | /*将网络请求结果强制置为失败*/ 172 | return TransformCallbackType.FAIL; 173 | } 174 | }) 175 | .listener(new RequestListener() { 176 | @Override 177 | public void onSuccess(String result) { 178 | /*请求成功回调,result为接口返回的json数据*/ 179 | } 180 | 181 | @Override 182 | public void onFail(String result) { 183 | /*请求失败回调,result为接口返回的数据*/ 184 | } 185 | }) 186 | .build()); 187 | ``` 188 | 2、请求结果转换回调方法支持带原始的回调类型(网络请求回调成功或失败); 189 | 190 | 只需设置transformResult时传OriginalTransformListener,如下 191 | ```java 192 | EasyRequest.getInstance().request(DefaultRequest.create() 193 | .method(Method.POST) 194 | .host("https://api.test.com/") 195 | .path("login/") 196 | .params(new RequestParam() 197 | .put("mobile", "13000000000") 198 | .put("password", "123456") 199 | .build()) 200 | .transformResult(new OriginalTransformListener() { 201 | @Override 202 | public String onTransformResult(OriginalCallback type,String result) { 203 | if(type == OriginalCallback.FAILURE){ 204 | /*转换网络请求返回的数据*/ 205 | return "{\"status\":-1,\"message\":\"请求失败\"}"; 206 | } 207 | return result; 208 | } 209 | 210 | @Override 211 | public TransformCallbackType callbackType() { 212 | return TransformCallbackType.DEFAULT; 213 | } 214 | }) 215 | .listener(new RequestListener() { 216 | @Override 217 | public void onSuccess(String result) { 218 | /*请求成功回调,result为接口返回的json数据*/ 219 | } 220 | 221 | @Override 222 | public void onFail(String result) { 223 | /*请求失败回调,result为接口返回的数据*/ 224 | } 225 | }) 226 | .build()); 227 | ``` 228 | 229 | OriginalTransformListener.java 230 | 231 | ```java 232 | package com.cloudling.request.network; 233 | 234 | import com.cloudling.request.listener.TransformListener; 235 | import com.cloudling.request.type.OriginalCallback; 236 | 237 | /** 238 | * 描述: 请求结果转换(带原始的回调类型(网络请求回调成功或失败)) 239 | * 联系:1966353889@qq.com 240 | * 日期: 2021/12/30 241 | */ 242 | public abstract class OriginalTransformListener implements TransformListener { 243 | public abstract String onTransformResult(OriginalCallback type, String result); 244 | 245 | @Override 246 | public final String onTransformResult(String result) { 247 | return null; 248 | } 249 | } 250 | 251 | ``` 252 | 253 | OriginalCallback.java 254 | 255 | ```java 256 | package com.cloudling.request.type; 257 | 258 | /** 259 | * 描述: 原始的回调类型(网络请求回调成功或失败) 260 | * 作者: 1966353889@qq.com 261 | * 日期: 2021/12/30 262 | */ 263 | public enum OriginalCallback { 264 | /** 265 | * 成功 266 | */ 267 | SUCCESS, 268 | /** 269 | * 失败 270 | */ 271 | FAILURE 272 | } 273 | 274 | ``` 275 | 3、模拟网络请求 276 | 这里需要注意的是,配置模拟网络请求实际上不会发起网络请求,而是直接回调,且优先级大于transformResult 277 | ```java 278 | EasyRequest.getInstance().request(DefaultRequest.create() 279 | .method(Method.POST) 280 | .host("https://api.test.com/") 281 | .path("login/") 282 | .params(new RequestParam() 283 | .put("mobile", "13000000000") 284 | .put("password", "123456") 285 | .build()) 286 | .mockRequest(new MockRequest() { 287 | @Override 288 | public int requestDuration() { 289 | /*配置模拟网络请求的时长*/ 290 | return 1; 291 | } 292 | 293 | @Override 294 | public MockRequestCallbackType callbackType() { 295 | /*配置模拟网络请求成功*/ 296 | return MockRequestCallbackType.SUCCESS; 297 | } 298 | 299 | @Override 300 | public String result() { 301 | /*配置模拟网络请求返回的数据*/ 302 | return "{\"status\":0,\"message\":\"请求成功\"}"; 303 | } 304 | }).listener(new RequestListener() { 305 | @Override 306 | public void onSuccess(String result) { 307 | /*请求成功回调,result为接口返回的json数据*/ 308 | } 309 | 310 | @Override 311 | public void onFail(String result) { 312 | /*请求失败回调,result为接口返回的数据*/ 313 | } 314 | }) 315 | .build()); 316 | ``` 317 | 318 | 4、设置网路请求回调数据缓存 319 | 320 | ```java 321 | EasyRequest.getInstance().request(DefaultRequest.create() 322 | .method(Method.POST) 323 | .host("https://api.test.com/")//这里需要说明的是,不设置host时框架会去读取NetworkConfig设置的service的host 324 | .path("login/") 325 | .params(new RequestParam() 326 | .put("mobile", "13000000000") 327 | .put("password", "123456") 328 | .build()) 329 | .cache(CacheType.SOURCE_SUCCESS)//网路请求成功时缓存成功的数据 330 | .listener(new RequestListener() { 331 | @Override 332 | public void onSuccess(String result) { 333 | /*请求成功回调,result为接口返回的json数据*/ 334 | } 335 | 336 | @Override 337 | public void onFail(String result) { 338 | /*请求失败回调,result为接口返回的数据*/ 339 | } 340 | }) 341 | .build()); 342 | ``` 343 | 344 | 5、设置读取缓存的网路请求回调数据 345 | 346 | ```java 347 | EasyRequest.getInstance().request(DefaultRequest.create() 348 | .method(Method.POST) 349 | .host("https://api.test.com/")//这里需要说明的是,不设置host时框架会去读取NetworkConfig设置的service的host 350 | .path("login/") 351 | .params(new RequestParam() 352 | .put("mobile", "13000000000") 353 | .put("password", "123456") 354 | .build()) 355 | .readCache(ReadCacheType.READ_SUCCESS_AFTER_FAIL)//当网络请求失败时读取成功(原始网络请求成功)的缓存数据 356 | .listener(new RequestListener() { 357 | @Override 358 | public void onSuccess(String result) { 359 | /*请求成功回调,result为接口返回的json数据*/ 360 | } 361 | 362 | @Override 363 | public void onFail(String result) { 364 | /*请求失败回调,result为接口返回的数据*/ 365 | } 366 | }) 367 | .build()); 368 | ``` 369 | readCache(ReadCacheType readCacheType)方法解释: 370 | 1. ReadCacheType.NO,表示不读取本地缓存的数据; 371 | 2. ReadCacheType.READ_SUCCESS_AFTER_SUCCESS,表示当前网络请求成功时读取成功(原始网络请求成功)的缓存数据; 372 | 3. ReadCacheType.READ_FAIL_AFTER_SUCCESS,表示当网络请求成功时读取失败(原始网络请求失败)的缓存数据; 373 | 4. ReadCacheType.READ_SUCCESS_AFTER_FAIL,表示当网络请求失败时读取成功(原始网络请求成功)的缓存数据; 374 | 5. ReadCacheType.READ_FAIL_AFTER_FAIL,表示当网络请求失败时读取失败(原始网络请求失败)的缓存数据; 375 | 6. ReadCacheType.DEFAULT,表示默认(跟随网络请求回调成功或失败读取对应类型的缓存数据); 376 | 7. ReadCacheType.READ_SUCCESS_AT_ONCE,表示优先读取成功(原始网络请求成功)的缓存数据,没有缓存则发起网络请求; 377 | 8. ReadCacheType.READ_FAIL_AT_ONCE,表示优先读取失败(原始网络请求失败)的缓存数据,没有缓存则发起网络请求; 378 | 379 | 这里我们默认实现了OkHttp的请求代理,如通过其它网路库的可自行实现RequestDelegate,然后调用下边的方法设置网路请求代理: 380 | 381 | ```java 382 | EasyRequest.getInstance().setRequestDelegate(requestDelegate); 383 | ``` 384 | 385 | 自行实现请求代理的,remove方法的实现可参考我们默认的OkHttp请求代理,我们看下OkHttpDelegate的完整代码: 386 | 387 | ```java 388 | package com.cloudling.request.delegate; 389 | 390 | import android.text.TextUtils; 391 | import android.util.ArrayMap; 392 | import com.cloudling.request.network.BaseRequest; 393 | import com.cloudling.request.network.EasyRequest; 394 | import com.cloudling.request.network.NetworkConfig; 395 | import com.cloudling.request.type.Method; 396 | import com.cloudling.request.type.RequestType; 397 | import org.apache.http.conn.ConnectTimeoutException; 398 | import org.jetbrains.annotations.NotNull; 399 | import org.json.JSONObject; 400 | import java.io.IOException; 401 | import java.net.SocketTimeoutException; 402 | import java.util.Map; 403 | import java.util.concurrent.ConcurrentHashMap; 404 | import java.util.concurrent.TimeUnit; 405 | import okhttp3.Call; 406 | import okhttp3.Callback; 407 | import okhttp3.HttpUrl; 408 | import okhttp3.Interceptor; 409 | import okhttp3.MediaType; 410 | import okhttp3.OkHttpClient; 411 | import okhttp3.Request; 412 | import okhttp3.RequestBody; 413 | import okhttp3.Response; 414 | 415 | /** 416 | * 描述: OkHttp请求代理 417 | * 联系:1966353889@qq.com 418 | * 日期: 2021/12/7 419 | */ 420 | public class OkHttpDelegate implements RequestDelegate { 421 | /** 422 | * okHttp请求实例 423 | */ 424 | private OkHttpClient mOkHttpClient; 425 | /** 426 | * 缓存请求 427 | */ 428 | private ConcurrentHashMap> mRequestMap; 429 | 430 | public OkHttpDelegate() { 431 | mRequestMap = new ConcurrentHashMap<>(); 432 | mOkHttpClient = new OkHttpClient().newBuilder() 433 | .connectTimeout(NetworkConfig.getInstance().getConnectTimeout(), TimeUnit.SECONDS) 434 | .readTimeout(NetworkConfig.getInstance().getReadTimeout(), TimeUnit.SECONDS) 435 | .writeTimeout(NetworkConfig.getInstance().getWriteTimeout(), TimeUnit.SECONDS) 436 | .addInterceptor(new Interceptor() { 437 | @Override 438 | public @NotNull 439 | Response intercept(@NotNull Chain chain) throws IOException { 440 | Request.Builder mBuilder = chain.request().newBuilder().removeHeader("Accept-Encoding"); 441 | ArrayMap headersMap = NetworkConfig.getInstance().getHeaders(); 442 | if (headersMap != null) { 443 | for (Map.Entry entry : headersMap.entrySet()) { 444 | if (!TextUtils.isEmpty(entry.getKey()) && entry.getValue() != null) { 445 | mBuilder.header(entry.getKey(), (String) entry.getValue()); 446 | } 447 | } 448 | } 449 | return chain.proceed(mBuilder.build()); 450 | } 451 | }) 452 | .build(); 453 | } 454 | 455 | public OkHttpDelegate(OkHttpClient okHttpClient) { 456 | mRequestMap = new ConcurrentHashMap<>(); 457 | this.mOkHttpClient = okHttpClient; 458 | } 459 | 460 | @Override 461 | public void request(BaseRequest config) { 462 | if (config == null) { 463 | return; 464 | } 465 | mRequestMap.put(config.getUUid(), config); 466 | if (config.getListener() != null 467 | && mRequestMap.get(config.getUUid()) != null) { 468 | config.getListener().requestBefore(); 469 | } 470 | Request.Builder builder = new Request.Builder(); 471 | if (config.getMethod() == Method.GET || config.getType() == RequestType.GET) { 472 | if (config.getParams() != null) { 473 | HttpUrl.Builder urlBuilder = HttpUrl.parse(config.getUrl()).newBuilder(); 474 | for (Map.Entry entry : config.getParams().entrySet()) { 475 | urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue())); 476 | } 477 | builder.url(urlBuilder.build()); 478 | } else { 479 | builder.url(config.getUrl()); 480 | } 481 | } else if (config.getType() == RequestType.POST 482 | || config.getType() == RequestType.PUT 483 | || config.getType() == RequestType.DELETE 484 | || config.getMethod() == Method.POST 485 | || config.getMethod() == Method.PUT 486 | || config.getMethod() == Method.DELETE) { 487 | builder.url(config.getUrl()); 488 | RequestBody body; 489 | if (config.getParams() != null) { 490 | MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); 491 | String json = new JSONObject(config.getParams()).toString(); 492 | body = RequestBody.create(mediaType, json); 493 | } else { 494 | body = RequestBody.create(null, ""); 495 | } 496 | if (config.getMethod() == Method.POST || config.getType() == RequestType.POST) { 497 | builder.post(body); 498 | } else if (config.getMethod() == Method.PUT || config.getType() == RequestType.PUT) { 499 | builder.put(body); 500 | } else if (config.getMethod() == Method.DELETE || config.getType() == RequestType.DELETE) { 501 | builder.delete(body); 502 | } 503 | } else { 504 | if (mRequestMap.get(config.getUUid()) != null) { 505 | if (config.getListener() != null) { 506 | String methodName = config.getMethod() != null ? config.getMethod().name() : (config.getType() != null ? config.getType().name() : null); 507 | config.getListener().onFail("未知的请求方法-" + methodName); 508 | config.getListener().requestAfter(); 509 | } 510 | removeByUUID(config.getUUid()); 511 | } 512 | return; 513 | } 514 | Request request = builder.build(); 515 | mOkHttpClient.newCall(request).enqueue(new Callback() { 516 | @Override 517 | public void onFailure(@NotNull Call call, @NotNull IOException e) { 518 | String result; 519 | if (e instanceof SocketTimeoutException) { 520 | /*响应超时*/ 521 | result = "SocketTimeoutException"; 522 | } else if (e instanceof ConnectTimeoutException) { 523 | /*请求超时*/ 524 | result = "ConnectTimeoutException"; 525 | } else { 526 | result = e.toString(); 527 | } 528 | if (mRequestMap.get(config.getUUid()) != null) { 529 | if (config.getListener() != null) { 530 | config.getListener().onFail(e.toString()); 531 | config.getListener().requestAfter(); 532 | } 533 | removeByUUID(config.getUUid()); 534 | } else { 535 | EasyRequest.getInstance().logE("[onFailure-no callback]result:" + result); 536 | } 537 | } 538 | 539 | @Override 540 | public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { 541 | String result = response.body() != null ? response.body().string() : null; 542 | if (mRequestMap.get(config.getUUid()) != null) { 543 | if (config.getListener() != null) { 544 | if (response.isSuccessful()) { 545 | config.getListener().onSuccess(result); 546 | } else { 547 | config.getListener().onFail(result); 548 | } 549 | config.getListener().requestAfter(); 550 | } 551 | removeByUUID(config.getUUid()); 552 | } else { 553 | EasyRequest.getInstance().logI("[onResponse-no callback]result:" + result); 554 | } 555 | } 556 | }); 557 | 558 | } 559 | 560 | @Override 561 | public void remove(BaseRequest config) { 562 | if (config != null) { 563 | mRequestMap.remove(config.getUUid()); 564 | } 565 | } 566 | 567 | @Override 568 | public void removeByTag(String TAG) { 569 | if (!TextUtils.isEmpty(TAG)) { 570 | for (String key : mRequestMap.keySet()) { 571 | if (mRequestMap.get(key) != null 572 | && !TextUtils.isEmpty(mRequestMap.get(key).getTAG()) 573 | && mRequestMap.get(key).getTAG().equals(TAG)) { 574 | mRequestMap.remove(key); 575 | } 576 | } 577 | } 578 | } 579 | 580 | @Override 581 | public void removeByUUID(String uuid) { 582 | mRequestMap.remove(uuid); 583 | } 584 | 585 | } 586 | 587 | 588 | ``` 589 | 590 | 设置对应的log处理类 591 | 592 | ```java 593 | EasyRequest.getInstance().setILog(ILog log); 594 | ``` 595 | 596 | 设置是否打开调试模式 597 | 598 | ```java 599 | EasyRequest.getInstance().enableDebug(boolean debug); 600 | ``` 601 | 同样的我们通过NetworkConfig来配置全局的请求头,超时时间,接口请求服务类(可根据需要设置对应的服务类,如各种开发环境下的请求服务类等),我们来看NetworkConfig的完整代码: 602 | 603 | ```java 604 | import android.os.Bundle; 605 | import android.text.TextUtils; 606 | import android.util.ArrayMap; 607 | 608 | import org.json.JSONException; 609 | import org.json.JSONObject; 610 | 611 | import java.util.Iterator; 612 | import java.util.Map; 613 | 614 | /** 615 | * 描述: 网络请求配置类 616 | * 联系: 1966353889@qq.com 617 | * 日期: 2021/12/3 618 | */ 619 | public class NetworkConfig implements SupportCallback { 620 | private static volatile NetworkConfig mInstance; 621 | private BaseService service; 622 | 623 | private NetworkConfig() { 624 | } 625 | 626 | public static NetworkConfig getInstance() { 627 | if (mInstance == null) { 628 | synchronized (NetworkConfig.class) { 629 | if (mInstance == null) { 630 | mInstance = new NetworkConfig(); 631 | } 632 | } 633 | } 634 | return mInstance; 635 | } 636 | 637 | /** 638 | * 获取当前接口请求服务类 639 | */ 640 | private BaseService getService() { 641 | return service; 642 | } 643 | 644 | /** 645 | * 设置当前接口请求服务类 646 | */ 647 | @Override 648 | public void setService(BaseService service) { 649 | this.service = service; 650 | } 651 | 652 | @Override 653 | public void headers(ArrayMap headers) { 654 | if (getService() != null) { 655 | getService().headers(headers); 656 | } 657 | } 658 | 659 | @Override 660 | public void header(String key, Object value) { 661 | if (getService() != null) { 662 | getService().header(key, value); 663 | } 664 | } 665 | 666 | @Override 667 | public long getConnectTimeout() { 668 | return getService() != null ? getService().getConnectTimeout() : 0; 669 | } 670 | 671 | @Override 672 | public long getReadTimeout() { 673 | return getService() != null ? getService().getReadTimeout() : 0; 674 | } 675 | 676 | @Override 677 | public long getWriteTimeout() { 678 | return getService() != null ? getService().getWriteTimeout() : 0; 679 | } 680 | 681 | @Override 682 | public String getHost() { 683 | return getService() != null ? getService().getHost() : null; 684 | } 685 | 686 | @Override 687 | public String getHost(String name) { 688 | return getService() != null ? getService().getHost(name) : null; 689 | } 690 | 691 | @Override 692 | public ArrayMap getHeaders() { 693 | return getService() != null ? getService().getHeaders() : null; 694 | } 695 | 696 | /** 697 | * 用于页面异常关闭保存数据(在Activity对应的生命周期调用) 698 | */ 699 | @Override 700 | public void onSaveInstanceState(Bundle outState) { 701 | if (outState != null) { 702 | BaseService service = getService(); 703 | if (service != null) { 704 | outState.putString("network_config_host", service.getHost()); 705 | outState.putLong("network_config_connectTimeout", service.getConnectTimeout()); 706 | outState.putLong("network_config_readTimeout", service.getReadTimeout()); 707 | outState.putLong("network_config_writeTimeout", service.getWriteTimeout()); 708 | try { 709 | JSONObject microConfig = new JSONObject(); 710 | JSONObject headers = new JSONObject(); 711 | ArrayMap microConfigMap = service.getMicroConfig(); 712 | ArrayMap headersMap = service.getHeaders(); 713 | if (microConfigMap != null) { 714 | for (Map.Entry entry : microConfigMap.entrySet()) { 715 | microConfig.put(entry.getKey(), entry.getValue()); 716 | } 717 | outState.putString("network_config_micro_config", microConfig.toString()); 718 | } 719 | if (headersMap != null) { 720 | for (Map.Entry entry : headersMap.entrySet()) { 721 | headers.put(entry.getKey(), entry.getValue()); 722 | } 723 | outState.putString("network_config_headers", headers.toString()); 724 | } 725 | } catch (JSONException e) { 726 | e.printStackTrace(); 727 | } 728 | 729 | } 730 | } 731 | } 732 | 733 | /** 734 | * 用于页面异常关闭恢复数据(在Activity对应的生命周期调用) 735 | */ 736 | @Override 737 | public void onCreate(Bundle outState) { 738 | if (outState != null) { 739 | BaseService service = getService(); 740 | if (service == null) { 741 | service = new BaseService() { 742 | @Override 743 | public String setHost() { 744 | return outState.getString("network_config_host"); 745 | } 746 | 747 | @Override 748 | public ArrayMap setMicroConfig() { 749 | if (!TextUtils.isEmpty(outState.getString("network_config_micro_config"))) { 750 | try { 751 | ArrayMap map = new ArrayMap<>(); 752 | JSONObject jsonObject = new JSONObject(outState.getString("network_config_micro_config")); 753 | Iterator iterator = jsonObject.keys(); 754 | while (iterator.hasNext()) { 755 | String key = iterator.next(); 756 | map.put(key, jsonObject.getString(key)); 757 | } 758 | return map; 759 | } catch (JSONException e) { 760 | e.printStackTrace(); 761 | } 762 | } 763 | return null; 764 | } 765 | 766 | @Override 767 | public ArrayMap setHeaders() { 768 | if (!TextUtils.isEmpty(outState.getString("network_config_headers"))) { 769 | try { 770 | ArrayMap map = new ArrayMap<>(); 771 | JSONObject jsonObject = new JSONObject(outState.getString("network_config_headers")); 772 | Iterator iterator = jsonObject.keys(); 773 | while (iterator.hasNext()) { 774 | String key = iterator.next(); 775 | map.put(key, jsonObject.getString(key)); 776 | } 777 | return map; 778 | } catch (JSONException e) { 779 | e.printStackTrace(); 780 | } 781 | } 782 | return null; 783 | } 784 | 785 | @Override 786 | public long connectTimeout() { 787 | return outState.getLong("network_config_connectTimeout"); 788 | } 789 | 790 | @Override 791 | public long readTimeout() { 792 | return outState.getLong("network_config_readTimeout"); 793 | } 794 | 795 | @Override 796 | public long writeTimeout() { 797 | return outState.getLong("network_config_writeTimeout"); 798 | } 799 | }; 800 | setService(service); 801 | } 802 | } 803 | } 804 | } 805 | ``` 806 | 807 | 808 | 由于之前在开发过程中,我们在app的启动页通过NetworkConfig配置了接口环境为线上正式环境,在MainActivity也处理了页面异常关闭重新创建时的页面数据的恢复处理,这个时候我们不会再重新走一遍启动页,所以接口环境就有问题了,所以我们在NetworkConfig中提供了两个方法去处理这种情况,分别为onSaveInstanceState(Bundle outState)和onCreate(Bundle outState)方法。 809 | 810 | 使用方法: 811 | 812 | 在需要的Activity中的onCreate方法中调用 813 | 814 | `NetworkConfig.getInstance().onCreate(savedInstanceState`); 815 | 816 | 在需要的Activity中的onSaveInstanceState方法中调用 817 | 818 | ```java 819 | NetworkConfig.getInstance().onSaveInstanceState(outState); 820 | ``` 821 | 822 | 这样就可以自动恢复我们配置好的各种网络配置参数,感兴趣的可以去看NetworkConfig的实现。 823 | 824 | 采用本文的网络请求架构来实现发起网络请求的完整使用步骤如下: 825 | 826 | 1、通过NetworkConfig配置接口请求所需各种参数(一般可在application或启动页配置) 827 | 828 | 微服务接口架构配置示例: 829 | 830 | ```java 831 | NetworkConfig.getInstance().setService(new DefaultMicroService() { 832 | @Override 833 | public ArrayMap setMicroConfig() { 834 | ArrayMap config = new ArrayMap<>(); 835 | config.put("user", "https://user-api.test.com/"); 836 | config.put("game", "https://game-api.test.com/"); 837 | config.put("account", "https://account-api.test.com/"); 838 | return config; 839 | } 840 | 841 | @Override 842 | public ArrayMap setHeaders() { 843 | ArrayMap headers = new ArrayMap<>(); 844 | headers.put("header1", "value1"); 845 | headers.put("header2", "value2"); 846 | ... 847 | return headers; 848 | } 849 | }); 850 | ``` 851 | 852 | 单服务接口架构配置示例: 853 | 854 | ```java 855 | NetworkConfig.getInstance().setService(new DefaultSingleService() { 856 | @Override 857 | public String setHost() { 858 | return “https://api.test.com/”; 859 | } 860 | 861 | @Override 862 | public ArrayMap setHeaders() { 863 | ArrayMap headers = new ArrayMap<>(); 864 | headers.put("header1", "value1"); 865 | headers.put("header2", "value2"); 866 | ... 867 | return headers; 868 | } 869 | }); 870 | ``` 871 | 872 | 不同开发环境可通过setService设置带不同host的Service来实现 873 | 874 | 2、发起请求 875 | 876 | 微服务接口架构请求示例: 877 | 878 | ```java 879 | EasyRequest.getInstance().request(DefaultRequest.create() 880 | .method(Method.POST) 881 | .name("user")//设置微服务名,对应的host在NetworkConfig设置server时设置 882 | .path("login/") 883 | .params(new RequestParam() 884 | .put("mobile", "13000000000") 885 | .put("password", "123456") 886 | .build()) 887 | .listener(new RequestListener() { 888 | @Override 889 | public void onSuccess(String result) { 890 | /*请求成功回调,result为接口返回的json数据*/ 891 | } 892 | 893 | @Override 894 | public void onFail(String result) { 895 | /*请求失败回调,result为接口返回的数据*/ 896 | } 897 | }) 898 | .build()); 899 | ``` 900 | 901 | 单服务接口架构请求示例: 902 | 903 | ```java 904 | EasyRequest.getInstance().request(DefaultRequest.create() 905 | .method(Method.POST) 906 | .host("https://api.test.com/") 907 | .path("login/") 908 | .params(new RequestParam() 909 | .put("mobile", "13000000000") 910 | .put("password", "123456") 911 | .build()) 912 | .listener(new RequestListener() { 913 | @Override 914 | public void onSuccess(String result) { 915 | /*请求成功回调,result为接口返回的json数据*/ 916 | } 917 | 918 | @Override 919 | public void onFail(String result) { 920 | /*请求失败回调,result为接口返回的数据*/ 921 | } 922 | }) 923 | .build()); 924 | ``` 925 | 926 | 这样就可以了,架构涉及到的其它java完整代码如下: 927 | 928 | EasyRequest.java 929 | 930 | ```java 931 | package com.cloudling.request.network; 932 | 933 | import android.os.Handler; 934 | import android.os.Looper; 935 | import android.text.TextUtils; 936 | import android.util.Log; 937 | import com.cloudling.request.BuildConfig; 938 | import com.cloudling.request.delegate.OkHttpDelegate; 939 | import com.cloudling.request.delegate.RequestDelegate; 940 | import com.cloudling.request.listener.ILog; 941 | import com.cloudling.request.type.MockRequestCallbackType; 942 | import org.json.JSONArray; 943 | import org.json.JSONObject; 944 | 945 | /** 946 | * 描述: 网络请求发起类(默认通过okhttp实现) 947 | * 联系:1966353889@qq.com 948 | * 日期: 2021/12/7 949 | */ 950 | public class EasyRequest { 951 | private final String TAG = "EasyRequest"; 952 | private static volatile EasyRequest mInstance; 953 | /** 954 | * 请求代理 955 | */ 956 | private RequestDelegate mRequestDelegate; 957 | /** 958 | * 日志输出类 959 | */ 960 | private ILog mILog; 961 | /** 962 | * 是否调试模式 963 | */ 964 | private boolean debug = BuildConfig.DEBUG; 965 | private Handler mHandler; 966 | 967 | private EasyRequest() { 968 | /*默认设置请求代理为okHttp*/ 969 | mRequestDelegate = new OkHttpDelegate(); 970 | mHandler = new Handler(Looper.getMainLooper()); 971 | mILog = new ILog() { 972 | @Override 973 | public void onLogVerbose(String TAG, String log) { 974 | if (debug) { 975 | Log.v(TAG, log); 976 | } 977 | } 978 | 979 | @Override 980 | public void onLogDebug(String TAG, String log) { 981 | if (debug) { 982 | Log.d(TAG, log); 983 | } 984 | } 985 | 986 | @Override 987 | public void onLogInfo(String TAG, String log) { 988 | if (debug) { 989 | Log.i(TAG, log); 990 | } 991 | } 992 | 993 | @Override 994 | public void onLogWarn(String TAG, String log) { 995 | if (debug) { 996 | Log.w(TAG, log); 997 | } 998 | } 999 | 1000 | @Override 1001 | public void onLogError(String TAG, String log) { 1002 | if (debug) { 1003 | Log.e(TAG, log); 1004 | } 1005 | } 1006 | }; 1007 | } 1008 | 1009 | public Handler getHandler() { 1010 | return mHandler; 1011 | } 1012 | 1013 | /** 1014 | * 延时处理任务 1015 | */ 1016 | private void delayTask(Handler handler, long delayMillis, Runnable runnable) { 1017 | if (delayMillis > 0) { 1018 | handler.postDelayed(runnable, delayMillis); 1019 | } else { 1020 | handler.post(runnable); 1021 | } 1022 | } 1023 | 1024 | public static EasyRequest getInstance() { 1025 | if (mInstance == null) { 1026 | synchronized (EasyRequest.class) { 1027 | if (mInstance == null) { 1028 | mInstance = new EasyRequest(); 1029 | } 1030 | } 1031 | } 1032 | return mInstance; 1033 | } 1034 | 1035 | /** 1036 | * 设置是否打开调试模式 1037 | */ 1038 | public void enableDebug(boolean debug) { 1039 | this.debug = debug; 1040 | if (canPrintLog()) { 1041 | logD("[enableDebug]"); 1042 | } 1043 | } 1044 | 1045 | /** 1046 | * 设置对应的log处理类 1047 | */ 1048 | public void setILog(ILog log) { 1049 | if (log != null) { 1050 | mILog = log; 1051 | if (canPrintLog()) { 1052 | logD("[setILog]"); 1053 | } 1054 | } 1055 | } 1056 | 1057 | /** 1058 | * 设置请求代理 1059 | */ 1060 | public void setRequestDelegate(RequestDelegate delegate) { 1061 | mRequestDelegate = delegate; 1062 | if (canPrintLog() && delegate != null) { 1063 | logD("[setRequestDelegate]" + delegate.getClass().getName()); 1064 | } 1065 | } 1066 | 1067 | /** 1068 | * 打印log 1069 | */ 1070 | public void logV(String log) { 1071 | if (canPrintLog()) { 1072 | mILog.onLogVerbose(TAG, log); 1073 | } 1074 | } 1075 | 1076 | /** 1077 | * 打印log 1078 | */ 1079 | public void logV(String TAG, String log) { 1080 | if (canPrintLog()) { 1081 | mILog.onLogVerbose(TAG, log); 1082 | } 1083 | } 1084 | 1085 | /** 1086 | * 打印log 1087 | */ 1088 | public void logD(String log) { 1089 | if (canPrintLog()) { 1090 | mILog.onLogDebug(TAG, log); 1091 | } 1092 | } 1093 | 1094 | /** 1095 | * 打印log 1096 | */ 1097 | public void logD(String TAG, String log) { 1098 | if (canPrintLog()) { 1099 | mILog.onLogDebug(TAG, log); 1100 | } 1101 | } 1102 | 1103 | /** 1104 | * 打印log 1105 | */ 1106 | public void logI(String log) { 1107 | if (canPrintLog()) { 1108 | mILog.onLogInfo(TAG, log); 1109 | } 1110 | } 1111 | 1112 | /** 1113 | * 打印log 1114 | */ 1115 | public void logI(String TAG, String log) { 1116 | if (canPrintLog()) { 1117 | mILog.onLogInfo(TAG, log); 1118 | } 1119 | } 1120 | 1121 | /** 1122 | * 打印log 1123 | */ 1124 | public void logW(String log) { 1125 | if (canPrintLog()) { 1126 | mILog.onLogWarn(TAG, log); 1127 | } 1128 | } 1129 | 1130 | /** 1131 | * 打印log 1132 | */ 1133 | public void logW(String TAG, String log) { 1134 | if (canPrintLog()) { 1135 | mILog.onLogWarn(TAG, log); 1136 | } 1137 | } 1138 | 1139 | /** 1140 | * 打印log 1141 | */ 1142 | public void logE(String log) { 1143 | if (canPrintLog()) { 1144 | mILog.onLogError(TAG, log); 1145 | } 1146 | } 1147 | 1148 | /** 1149 | * 打印log 1150 | */ 1151 | public void logE(String TAG, String log) { 1152 | if (canPrintLog()) { 1153 | mILog.onLogError(TAG, log); 1154 | } 1155 | } 1156 | 1157 | 1158 | /** 1159 | * 是否可输出调试日志 1160 | */ 1161 | public boolean canPrintLog() { 1162 | return debug && mILog != null; 1163 | } 1164 | 1165 | /** 1166 | * 判断是否为json 1167 | */ 1168 | public boolean isJson(String result) { 1169 | if (TextUtils.isEmpty(result)) { 1170 | return false; 1171 | } 1172 | boolean isJsonObject = true; 1173 | boolean isJsonArray = true; 1174 | try { 1175 | JSONObject jsonObject = new JSONObject(result); 1176 | } catch (Exception e) { 1177 | isJsonObject = false; 1178 | } 1179 | try { 1180 | JSONArray jsonArray = new JSONArray(result); 1181 | } catch (Exception e) { 1182 | isJsonArray = false; 1183 | } 1184 | if (!isJsonObject && !isJsonArray) { 1185 | return false; 1186 | } 1187 | return true; 1188 | } 1189 | 1190 | public void request(BaseRequest config) { 1191 | if (canPrintLog() && config != null) { 1192 | StringBuilder builder = new StringBuilder(); 1193 | builder.append("[request]") 1194 | .append("url:") 1195 | .append(config.getUrl()) 1196 | .append(",method:") 1197 | .append(config.getMethod() != null ? config.getMethod().name() : (config.getType() != null ? config.getType().name() : null)) 1198 | .append(",params:") 1199 | .append(config.params != null ? new JSONObject(config.params).toString() : null); 1200 | logD(builder.toString()); 1201 | } 1202 | if (config != null && config.mockRequest != null && config.getListener() != null) { 1203 | delayTask(EasyRequest.getInstance().getHandler(), 0, new Runnable() { 1204 | @Override 1205 | public void run() { 1206 | config.getListener().requestBefore(); 1207 | } 1208 | }); 1209 | delayTask(EasyRequest.getInstance().getHandler(), config.mockRequest.requestDuration() * 1000L, new Runnable() { 1210 | @Override 1211 | public void run() { 1212 | if (config.mockRequest.callbackType() == MockRequestCallbackType.SUCCESS) { 1213 | config.getListener().onSuccess(config.mockRequest.result()); 1214 | } else if (config.mockRequest.callbackType() == MockRequestCallbackType.FAIL) { 1215 | config.getListener().onFail(config.mockRequest.result()); 1216 | } 1217 | config.getListener().requestAfter(); 1218 | } 1219 | }); 1220 | } else { 1221 | mRequestDelegate.request(config); 1222 | } 1223 | } 1224 | 1225 | public void remove(BaseRequest config) { 1226 | mRequestDelegate.remove(config); 1227 | if (canPrintLog() && config != null) { 1228 | StringBuilder builder = new StringBuilder(); 1229 | builder.append("[remove]") 1230 | .append("url:") 1231 | .append(config.getUrl()) 1232 | .append(",method:") 1233 | .append(config.getMethod() != null ? config.getMethod().name() : (config.getType() != null ? config.getType().name() : null)) 1234 | .append(",TAG:") 1235 | .append(config.getTAG()) 1236 | .append(",uuid:") 1237 | .append(config.getUUid()); 1238 | logD(builder.toString()); 1239 | } 1240 | } 1241 | 1242 | public void removeByTag(String TAG) { 1243 | mRequestDelegate.removeByTag(TAG); 1244 | if (canPrintLog()) { 1245 | StringBuilder builder = new StringBuilder(); 1246 | builder.append("[removeByTag]") 1247 | .append("TAG:") 1248 | .append(TAG); 1249 | logD(builder.toString()); 1250 | } 1251 | } 1252 | 1253 | public void removeByUUID(String uuid) { 1254 | mRequestDelegate.removeByUUID(uuid); 1255 | if (canPrintLog()) { 1256 | StringBuilder builder = new StringBuilder(); 1257 | builder.append("[removeByUUID]") 1258 | .append("uuid:") 1259 | .append(uuid); 1260 | logD(builder.toString()); 1261 | } 1262 | } 1263 | 1264 | } 1265 | 1266 | ``` 1267 | RequestListener.java 1268 | 1269 | ```java 1270 | /** 1271 | * 请求结果监听 1272 | */ 1273 | public interface RequestListener { 1274 | /** 1275 | * 成功 1276 | * 1277 | * @param result 回调参数 1278 | */ 1279 | void onSuccess(String result); 1280 | 1281 | /** 1282 | * 失败 1283 | * 1284 | * @param result 回调参数 1285 | */ 1286 | void onFail(String result); 1287 | } 1288 | ``` 1289 | WholeRequestListener.java 1290 | 1291 | ```java 1292 | /** 1293 | * 请求结果监听(带请求开始和结束回调) 1294 | */ 1295 | public interface WholeRequestListener extends RequestListener { 1296 | /** 1297 | * 请求开始回调 1298 | */ 1299 | void requestBefore(); 1300 | 1301 | /** 1302 | * 请求结束回调 1303 | */ 1304 | void requestAfter(); 1305 | } 1306 | ``` 1307 | TransformListener.java 1308 | 1309 | ```java 1310 | /** 1311 | * 请求结果转换 1312 | */ 1313 | public interface TransformListener { 1314 | /** 1315 | * 转换请求结果(可对请求回调参数做包装) 1316 | * 1317 | * @param result 回调参数 1318 | */ 1319 | String onTransformResult(String result); 1320 | 1321 | /** 1322 | * 是否将结果转成成功 1323 | */ 1324 | TransformCallbackType callbackType(); 1325 | } 1326 | ``` 1327 | TransformCallbackType.java 1328 | 1329 | ```java 1330 | /** 1331 | * 请求结果转换回调类型(可强制将请求结果回调为成功,失败) 1332 | */ 1333 | public enum TransformCallbackType { 1334 | /** 1335 | * 成功 1336 | */ 1337 | SUCCESS, 1338 | /** 1339 | * 失败 1340 | */ 1341 | FAIL, 1342 | /** 1343 | * 默认(跟随网络请求回调) 1344 | */ 1345 | DEFAULT 1346 | } 1347 | ``` 1348 | MockRequest.java 1349 | 1350 | ```java 1351 | /** 1352 | * 模拟请求配置 1353 | */ 1354 | public interface MockRequest { 1355 | /** 1356 | * 请求时长 1357 | */ 1358 | int requestDuration(); 1359 | 1360 | /** 1361 | * 模拟请求结果回调类型 1362 | */ 1363 | MockRequestCallbackType callbackType(); 1364 | 1365 | /** 1366 | * 模拟请求结果返回值 1367 | */ 1368 | String result(); 1369 | } 1370 | ``` 1371 | MockRequestCallbackType.java 1372 | 1373 | ```java 1374 | /** 1375 | * 模拟请求结果回调类型 1376 | */ 1377 | public enum MockRequestCallbackType { 1378 | /** 1379 | * 成功 1380 | */ 1381 | SUCCESS, 1382 | /** 1383 | * 失败 1384 | */ 1385 | FAIL 1386 | } 1387 | ``` 1388 | BaseRequest.java 1389 | 1390 | ```java 1391 | package com.cloudling.request.network; 1392 | 1393 | import android.text.TextUtils; 1394 | import com.cloudling.request.converter.BaseConverterFactory; 1395 | import com.cloudling.request.listener.ConverterListener; 1396 | import com.cloudling.request.listener.MockRequest; 1397 | import com.cloudling.request.listener.RequestListener; 1398 | import com.cloudling.request.listener.TransformListener; 1399 | import com.cloudling.request.listener.WholeConverterListener; 1400 | import com.cloudling.request.listener.WholeRequestListener; 1401 | import com.cloudling.request.type.Method; 1402 | import com.cloudling.request.type.OriginalCallback; 1403 | import com.cloudling.request.type.RequestType; 1404 | import com.cloudling.request.type.TransformCallbackType; 1405 | import java.util.Map; 1406 | import java.util.UUID; 1407 | 1408 | /** 1409 | * 描述: 请求配置 1410 | * 联系:1966353889@qq.com 1411 | * 日期: 2021/12/29 1412 | */ 1413 | public class BaseRequest { 1414 | /** 1415 | * 请求类型 1416 | */ 1417 | RequestType requestType; 1418 | /** 1419 | * 请求类型 1420 | */ 1421 | Method method; 1422 | /** 1423 | * 请求参数 1424 | */ 1425 | Map params; 1426 | /** 1427 | * 请求回调(外部设置) 1428 | */ 1429 | RequestListener requestListener; 1430 | /** 1431 | * 真正的请求回调 1432 | */ 1433 | WholeRequestListener realRequestListener; 1434 | /** 1435 | * 转换请求结果(可对请求回调参数做包装) 1436 | */ 1437 | TransformListener transformListener; 1438 | /** 1439 | * 模拟请求配置 1440 | */ 1441 | MockRequest mockRequest; 1442 | /** 1443 | * 单服务host 1444 | */ 1445 | String host; 1446 | /** 1447 | * 请求path 1448 | */ 1449 | String path; 1450 | /** 1451 | * 微服务名(需在BaseService配置) 1452 | */ 1453 | String name; 1454 | /** 1455 | * 唯一值 1456 | */ 1457 | final String uuid; 1458 | final String TAG; 1459 | final BaseConverterFactory converterFactory; 1460 | final ConverterListener converterListener; 1461 | 1462 | private BaseRequest(Builder builder) { 1463 | uuid = UUID.randomUUID().toString(); 1464 | requestType = builder.requestType; 1465 | method = builder.method; 1466 | params = builder.params; 1467 | requestListener = builder.requestListener; 1468 | transformListener = builder.transformListener; 1469 | mockRequest = builder.mockRequest; 1470 | host = builder.host; 1471 | path = builder.path; 1472 | name = builder.name; 1473 | TAG = builder.TAG; 1474 | converterFactory = builder.converterFactory; 1475 | converterListener = builder.converterListener; 1476 | if (requestListener != null || converterListener != null) { 1477 | realRequestListener = new WholeRequestListener() { 1478 | @Override 1479 | public void requestBefore() { 1480 | if (EasyRequest.getInstance().getHandler() != null) { 1481 | EasyRequest.getInstance().getHandler().post(new Runnable() { 1482 | @Override 1483 | public void run() { 1484 | if (requestListener instanceof WholeRequestListener) { 1485 | ((WholeRequestListener) requestListener).requestBefore(); 1486 | } 1487 | if (converterListener instanceof WholeConverterListener) { 1488 | ((WholeConverterListener) converterListener).requestBefore(); 1489 | } 1490 | } 1491 | }); 1492 | } else { 1493 | if (requestListener instanceof WholeRequestListener) { 1494 | ((WholeRequestListener) requestListener).requestBefore(); 1495 | } 1496 | if (converterListener instanceof WholeConverterListener) { 1497 | ((WholeConverterListener) converterListener).requestBefore(); 1498 | } 1499 | } 1500 | } 1501 | 1502 | @Override 1503 | public void requestAfter() { 1504 | if (EasyRequest.getInstance().getHandler() != null) { 1505 | EasyRequest.getInstance().getHandler().post(new Runnable() { 1506 | @Override 1507 | public void run() { 1508 | if (requestListener instanceof WholeRequestListener) { 1509 | ((WholeRequestListener) requestListener).requestAfter(); 1510 | } 1511 | if (converterListener instanceof WholeConverterListener) { 1512 | ((WholeConverterListener) converterListener).requestAfter(); 1513 | } 1514 | } 1515 | }); 1516 | } else { 1517 | if (requestListener instanceof WholeRequestListener) { 1518 | ((WholeRequestListener) requestListener).requestAfter(); 1519 | } 1520 | if (converterListener instanceof WholeConverterListener) { 1521 | ((WholeConverterListener) converterListener).requestAfter(); 1522 | } 1523 | } 1524 | } 1525 | 1526 | @Override 1527 | public void onSuccess(String result) { 1528 | if (EasyRequest.getInstance().getHandler() != null) { 1529 | EasyRequest.getInstance().getHandler().post(new Runnable() { 1530 | @Override 1531 | public void run() { 1532 | if (transformListener != null) { 1533 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.SUCCESS, result) : transformListener.onTransformResult(result); 1534 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 1535 | || transformListener.callbackType() == TransformCallbackType.SUCCESS) { 1536 | if (requestListener != null) { 1537 | requestListener.onSuccess(realResult); 1538 | } 1539 | if (converterListener != null && converterFactory != null) { 1540 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 1541 | } 1542 | EasyRequest.getInstance().logI("[onSuccess]result:" + realResult); 1543 | } else if (transformListener.callbackType() == TransformCallbackType.FAIL) { 1544 | if (requestListener != null) { 1545 | requestListener.onFail(realResult); 1546 | } 1547 | if (converterListener != null && converterFactory != null) { 1548 | converterListener.onFail(converterFactory.converterFail(realResult)); 1549 | } 1550 | EasyRequest.getInstance().logE("[onFail]result:" + realResult); 1551 | } 1552 | } else { 1553 | if (requestListener != null) { 1554 | requestListener.onSuccess(result); 1555 | } 1556 | if (converterListener != null && converterFactory != null) { 1557 | converterListener.onSuccess(converterFactory.converterSuccess(result)); 1558 | } 1559 | EasyRequest.getInstance().logI("[onSuccess]result:" + result); 1560 | } 1561 | } 1562 | }); 1563 | } else { 1564 | if (transformListener != null) { 1565 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.SUCCESS, result) : transformListener.onTransformResult(result); 1566 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 1567 | || transformListener.callbackType() == TransformCallbackType.SUCCESS) { 1568 | if (requestListener != null) { 1569 | requestListener.onSuccess(realResult); 1570 | } 1571 | if (converterListener != null && converterFactory != null) { 1572 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 1573 | } 1574 | EasyRequest.getInstance().logI("[onSuccess]result:" + realResult); 1575 | } else if (transformListener.callbackType() == TransformCallbackType.FAIL) { 1576 | if (requestListener != null) { 1577 | requestListener.onFail(realResult); 1578 | } 1579 | if (converterListener != null && converterFactory != null) { 1580 | converterListener.onFail(converterFactory.converterFail(realResult)); 1581 | } 1582 | EasyRequest.getInstance().logE("[onFail]result:" + realResult); 1583 | } 1584 | } else { 1585 | if (requestListener != null) { 1586 | requestListener.onSuccess(result); 1587 | } 1588 | if (converterListener != null && converterFactory != null) { 1589 | converterListener.onSuccess(converterFactory.converterSuccess(result)); 1590 | } 1591 | EasyRequest.getInstance().logI("[onSuccess]result:" + result); 1592 | } 1593 | } 1594 | } 1595 | 1596 | @Override 1597 | public void onFail(String result) { 1598 | if (EasyRequest.getInstance().getHandler() != null) { 1599 | EasyRequest.getInstance().getHandler().post(new Runnable() { 1600 | @Override 1601 | public void run() { 1602 | if (transformListener != null) { 1603 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.FAILURE, result) : transformListener.onTransformResult(result); 1604 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 1605 | || transformListener.callbackType() == TransformCallbackType.FAIL) { 1606 | if (requestListener != null) { 1607 | requestListener.onFail(realResult); 1608 | } 1609 | if (converterListener != null && converterFactory != null) { 1610 | converterListener.onFail(converterFactory.converterFail(realResult)); 1611 | } 1612 | EasyRequest.getInstance().logE("[onFail]result:" + realResult); 1613 | } else if (transformListener.callbackType() == TransformCallbackType.SUCCESS) { 1614 | if (requestListener != null) { 1615 | requestListener.onSuccess(realResult); 1616 | } 1617 | if (converterListener != null && converterFactory != null) { 1618 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 1619 | } 1620 | EasyRequest.getInstance().logI("[onSuccess]result:" + realResult); 1621 | } 1622 | } else { 1623 | if (requestListener != null) { 1624 | requestListener.onFail(result); 1625 | } 1626 | if (converterListener != null && converterFactory != null) { 1627 | converterListener.onFail(converterFactory.converterFail(result)); 1628 | } 1629 | EasyRequest.getInstance().logE("[onFail]result:" + result); 1630 | } 1631 | } 1632 | }); 1633 | } else { 1634 | if (transformListener != null) { 1635 | String realResult = transformListener instanceof OriginalTransformListener ? ((OriginalTransformListener) transformListener).onTransformResult(OriginalCallback.FAILURE, result) : transformListener.onTransformResult(result); 1636 | if (transformListener.callbackType() == TransformCallbackType.DEFAULT 1637 | || transformListener.callbackType() == TransformCallbackType.FAIL) { 1638 | if (requestListener != null) { 1639 | requestListener.onFail(realResult); 1640 | } 1641 | if (converterListener != null && converterFactory != null) { 1642 | converterListener.onFail(converterFactory.converterFail(realResult)); 1643 | } 1644 | EasyRequest.getInstance().logE("[onFail]result:" + realResult); 1645 | } else if (transformListener.callbackType() == TransformCallbackType.SUCCESS) { 1646 | if (requestListener != null) { 1647 | requestListener.onSuccess(realResult); 1648 | } 1649 | if (converterListener != null && converterFactory != null) { 1650 | converterListener.onSuccess(converterFactory.converterSuccess(realResult)); 1651 | } 1652 | EasyRequest.getInstance().logI("[onSuccess]result:" + realResult); 1653 | } 1654 | } else { 1655 | if (requestListener != null) { 1656 | requestListener.onFail(result); 1657 | } 1658 | if (converterListener != null && converterFactory != null) { 1659 | converterListener.onFail(converterFactory.converterFail(result)); 1660 | } 1661 | EasyRequest.getInstance().logE("[onFail]result:" + result); 1662 | } 1663 | } 1664 | } 1665 | }; 1666 | } 1667 | } 1668 | 1669 | public String getUUid() { 1670 | return uuid; 1671 | } 1672 | 1673 | public String getTAG() { 1674 | return TAG; 1675 | } 1676 | 1677 | /** 1678 | * @deprecated 推荐使用 {@link #getMethod()} 1679 | */ 1680 | public RequestType getType() { 1681 | return requestType; 1682 | } 1683 | 1684 | public Method getMethod() { 1685 | return method; 1686 | } 1687 | 1688 | public Map getParams() { 1689 | return params; 1690 | } 1691 | 1692 | public WholeRequestListener getListener() { 1693 | return realRequestListener; 1694 | } 1695 | 1696 | public String getUrl() { 1697 | StringBuilder builder = new StringBuilder(); 1698 | if (!TextUtils.isEmpty(name)) { 1699 | builder.append(NetworkConfig.getInstance().getHost(name)); 1700 | } else { 1701 | builder.append(!TextUtils.isEmpty(host) ? host : NetworkConfig.getInstance().getHost()); 1702 | } 1703 | if (!TextUtils.isEmpty(path)) { 1704 | builder.append(path); 1705 | } 1706 | return builder.toString(); 1707 | } 1708 | 1709 | public static class Builder { 1710 | RequestType requestType; 1711 | Method method; 1712 | Map params; 1713 | RequestListener requestListener; 1714 | TransformListener transformListener; 1715 | MockRequest mockRequest; 1716 | String host; 1717 | String path; 1718 | String name; 1719 | String TAG; 1720 | BaseConverterFactory converterFactory; 1721 | ConverterListener converterListener; 1722 | 1723 | /** 1724 | * @deprecated 推荐使用 {@link Builder#method(Method)} 1725 | */ 1726 | public Builder type(RequestType requestType) { 1727 | this.requestType = requestType; 1728 | return this; 1729 | } 1730 | 1731 | public Builder method(Method method) { 1732 | this.method = method; 1733 | return this; 1734 | } 1735 | 1736 | public Builder params(Map params) { 1737 | this.params = params; 1738 | return this; 1739 | } 1740 | 1741 | public Builder listener(RequestListener listener) { 1742 | this.requestListener = listener; 1743 | return this; 1744 | } 1745 | 1746 | public Builder listener(ConverterListener converterListener) { 1747 | this.converterListener = converterListener; 1748 | return this; 1749 | } 1750 | 1751 | public Builder transformResult(TransformListener listener) { 1752 | this.transformListener = listener; 1753 | return this; 1754 | } 1755 | 1756 | public Builder mockRequest(MockRequest mockRequest) { 1757 | this.mockRequest = mockRequest; 1758 | return this; 1759 | } 1760 | 1761 | public Builder host(String host) { 1762 | this.host = host; 1763 | return this; 1764 | } 1765 | 1766 | public Builder path(String path) { 1767 | this.path = path; 1768 | return this; 1769 | } 1770 | 1771 | public Builder name(String name) { 1772 | this.name = name; 1773 | return this; 1774 | } 1775 | 1776 | public Builder tag(String TAG) { 1777 | this.TAG = TAG; 1778 | return this; 1779 | } 1780 | 1781 | public Builder addConverterFactory(BaseConverterFactory converterFactory) { 1782 | this.converterFactory = converterFactory; 1783 | return this; 1784 | } 1785 | 1786 | public BaseRequest build() { 1787 | return new BaseRequest<>(this); 1788 | } 1789 | } 1790 | 1791 | 1792 | } 1793 | 1794 | ``` 1795 | RequestParam.java 1796 | 1797 | ```java 1798 | public static class RequestParam { 1799 | private Map param; 1800 | 1801 | public RequestParam() { 1802 | param = new HashMap<>(); 1803 | } 1804 | 1805 | public RequestParam put(String key, Object value) { 1806 | param.put(key, value); 1807 | return this; 1808 | } 1809 | 1810 | public Map build() { 1811 | return param; 1812 | } 1813 | } 1814 | ``` 1815 | RequestType.java 1816 | 1817 | ```java 1818 | /** 1819 | * 请求方法 1820 | * 1821 | * @deprecated 推荐使用 {@link Method} 1822 | */ 1823 | public enum RequestType { 1824 | GET, 1825 | POST, 1826 | PUT, 1827 | DELETE 1828 | } 1829 | ``` 1830 | Method.java 1831 | 1832 | ```java 1833 | /** 1834 | * 请求方法 1835 | */ 1836 | public enum Method { 1837 | GET, 1838 | POST, 1839 | PUT, 1840 | DELETE 1841 | } 1842 | ``` 1843 | RequestDelegate.java 1844 | 1845 | ```java 1846 | /** 1847 | * 请求代理 1848 | */ 1849 | public interface RequestDelegate { 1850 | /** 1851 | * 发起请求 1852 | */ 1853 | void request(Request config); 1854 | 1855 | /** 1856 | * 移除请求 1857 | */ 1858 | void remove(Request config); 1859 | 1860 | /** 1861 | * 通过tag移除请求 1862 | */ 1863 | void removeByTag(String TAG); 1864 | 1865 | /** 1866 | * 通过uuid移除请求 1867 | */ 1868 | void removeByUUID(String uuid); 1869 | } 1870 | ``` 1871 | ILog.java 1872 | 1873 | ```java 1874 | /** 1875 | * 日志输出接口 1876 | */ 1877 | public interface ILog { 1878 | void onLogVerbose(String TAG, String log); 1879 | 1880 | void onLogDebug(String TAG, String log); 1881 | 1882 | void onLogInfo(String TAG, String log); 1883 | 1884 | void onLogWarn(String TAG, String log); 1885 | 1886 | void onLogError(String TAG, String log); 1887 | } 1888 | ``` 1889 | 1890 | BaseService.java 1891 | 1892 | ```java 1893 | import android.text.TextUtils; 1894 | import android.util.ArrayMap; 1895 | 1896 | /** 1897 | * 描述: 接口请求服务基类 1898 | * 联系: 1966353889@qq.com 1899 | * 日期: 2021/12/3 1900 | */ 1901 | abstract class BaseService implements TimeoutListener { 1902 | /** 1903 | * 连接超时时间 1904 | */ 1905 | private final long mConnectTimeout; 1906 | /** 1907 | * 读取超时时间 1908 | */ 1909 | private final long mReadTimeout; 1910 | /** 1911 | * 写入超时时间 1912 | */ 1913 | private final long mWriteTimeout; 1914 | /** 1915 | * 单服务接口host 1916 | */ 1917 | private final String mHost; 1918 | /** 1919 | * 微服务键值对 1920 | */ 1921 | private final ArrayMap mMicroConfig; 1922 | /** 1923 | * 请求头 1924 | */ 1925 | private ArrayMap mHeaders; 1926 | 1927 | public BaseService() { 1928 | /*设置连接超时时间*/ 1929 | mConnectTimeout = connectTimeout(); 1930 | /*设置读取超时时间*/ 1931 | mReadTimeout = readTimeout(); 1932 | /*设置写入超时时间*/ 1933 | mWriteTimeout = writeTimeout(); 1934 | /*设置单服务接口host*/ 1935 | mHost = setHost(); 1936 | /*设置微服务键值对*/ 1937 | mMicroConfig = setMicroConfig(); 1938 | /*设置请求头*/ 1939 | mHeaders = setHeaders(); 1940 | } 1941 | 1942 | /** 1943 | * 设置单服务接口host 1944 | */ 1945 | public abstract String setHost(); 1946 | 1947 | /** 1948 | * 设置微服务键值对(服务名与对应的Host) 1949 | */ 1950 | public abstract ArrayMap setMicroConfig(); 1951 | 1952 | /** 1953 | * 设置请求头 1954 | */ 1955 | public abstract ArrayMap setHeaders(); 1956 | 1957 | /** 1958 | * 获取连接超时时间 1959 | */ 1960 | long getConnectTimeout() { 1961 | return mConnectTimeout; 1962 | } 1963 | 1964 | /** 1965 | * 获取读取超时时间 1966 | */ 1967 | long getReadTimeout() { 1968 | return mReadTimeout; 1969 | } 1970 | 1971 | /** 1972 | * 获取写入超时时间 1973 | */ 1974 | long getWriteTimeout() { 1975 | return mWriteTimeout; 1976 | } 1977 | 1978 | /** 1979 | * 获取host(单服务) 1980 | */ 1981 | String getHost() { 1982 | return mHost; 1983 | } 1984 | 1985 | /** 1986 | * 获取host(微服务) 1987 | * 1988 | * @param name 微服务服务名 1989 | */ 1990 | String getHost(String name) { 1991 | return mMicroConfig != null && !TextUtils.isEmpty(name) ? mMicroConfig.get(name) : null; 1992 | } 1993 | 1994 | /** 1995 | * 获取微服务配置 1996 | */ 1997 | ArrayMap getMicroConfig() { 1998 | return mMicroConfig; 1999 | } 2000 | 2001 | /** 2002 | * 获取请求头 2003 | */ 2004 | ArrayMap getHeaders() { 2005 | return mHeaders; 2006 | } 2007 | 2008 | /** 2009 | * 设置请求头 2010 | */ 2011 | void headers(ArrayMap headers) { 2012 | mHeaders = headers; 2013 | } 2014 | 2015 | /** 2016 | * 设置请求头 2017 | */ 2018 | void header(String key, Object value) { 2019 | if (mHeaders == null) { 2020 | mHeaders = new ArrayMap<>(); 2021 | } 2022 | mHeaders.put(key, value); 2023 | } 2024 | } 2025 | ``` 2026 | 2027 | BaseSingleService.java 2028 | 2029 | ```java 2030 | import android.util.ArrayMap; 2031 | 2032 | /** 2033 | * 描述: 单服务接口请求服务基类(不同环境继承该类设置不同的host) 2034 | * 作者:lpx 2035 | * 日期: 2021/12/3 2036 | */ 2037 | public abstract class BaseSingleService extends BaseService { 2038 | public BaseSingleService() { 2039 | super(); 2040 | } 2041 | 2042 | @Override 2043 | public final ArrayMap setMicroConfig() { 2044 | return null; 2045 | } 2046 | 2047 | } 2048 | ``` 2049 | 2050 | BaseMicroService.java 2051 | 2052 | ```java 2053 | /** 2054 | * 描述: 微服务接口请求服务基类(不同环境继承该类设置不同的host) 2055 | * 作者:lpx 2056 | * 日期: 2021/12/3 2057 | */ 2058 | public abstract class BaseMicroService extends BaseService { 2059 | public BaseMicroService() { 2060 | super(); 2061 | } 2062 | 2063 | @Override 2064 | public final String setHost() { 2065 | return null; 2066 | } 2067 | } 2068 | ``` 2069 | 2070 | DefaultSingleService.java 2071 | 2072 | ```java 2073 | import android.util.ArrayMap; 2074 | 2075 | /** 2076 | * 描述: 单服务接口默认请求服务基类(已实现默认超时时间,不同环境继承该类设置不同的host) 2077 | * 作者:lpx 2078 | * 日期: 2021/12/3 2079 | */ 2080 | public abstract class DefaultSingleService extends BaseService { 2081 | public DefaultSingleService() { 2082 | super(); 2083 | } 2084 | 2085 | @Override 2086 | public final ArrayMap setMicroConfig() { 2087 | return null; 2088 | } 2089 | 2090 | @Override 2091 | public final long connectTimeout() { 2092 | return 20; 2093 | } 2094 | 2095 | @Override 2096 | public final long readTimeout() { 2097 | return 20; 2098 | } 2099 | 2100 | @Override 2101 | public final long writeTimeout() { 2102 | return 20; 2103 | } 2104 | } 2105 | ``` 2106 | 2107 | DefaultMicroService.java 2108 | 2109 | ```java 2110 | /** 2111 | * 描述: 微服务接口默认请求服务基类(已实现默认超时时间,不同环境继承该类设置不同的host) 2112 | * 作者:lpx 2113 | * 日期: 2021/12/3 2114 | */ 2115 | public abstract class DefaultMicroService extends BaseService { 2116 | public DefaultMicroService() { 2117 | super(); 2118 | } 2119 | 2120 | @Override 2121 | public final String setHost() { 2122 | return null; 2123 | } 2124 | 2125 | @Override 2126 | public final long connectTimeout() { 2127 | return 20; 2128 | } 2129 | 2130 | @Override 2131 | public final long readTimeout() { 2132 | return 20; 2133 | } 2134 | 2135 | @Override 2136 | public final long writeTimeout() { 2137 | return 20; 2138 | } 2139 | } 2140 | ``` 2141 | 2142 | SupportCallback.java 2143 | 2144 | ```java 2145 | import android.os.Bundle; 2146 | import android.util.ArrayMap; 2147 | 2148 | /** 2149 | * 描述: 接口请求支持回调 2150 | * 作者:lpx 2151 | * 日期: 2021/12/3 2152 | */ 2153 | interface SupportCallback { 2154 | /** 2155 | * 设置当前接口请求服务类 2156 | */ 2157 | void setService(BaseService service); 2158 | 2159 | /** 2160 | * 设置请求头 2161 | */ 2162 | void headers(ArrayMap headers); 2163 | 2164 | /** 2165 | * 设置请求头 2166 | */ 2167 | void header(String key, Object value); 2168 | 2169 | /** 2170 | * 获取连接超时时间 2171 | */ 2172 | long getConnectTimeout(); 2173 | 2174 | /** 2175 | * 获取读取超时时间 2176 | */ 2177 | long getReadTimeout(); 2178 | 2179 | /** 2180 | * 获取写入超时时间 2181 | */ 2182 | long getWriteTimeout(); 2183 | 2184 | /** 2185 | * 获取host(单服务) 2186 | */ 2187 | String getHost(); 2188 | 2189 | /** 2190 | * 获取host(微服务) 2191 | * 2192 | * @param name 微服务服务名 2193 | */ 2194 | String getHost(String name); 2195 | 2196 | /** 2197 | * 获取配置的请求头 2198 | */ 2199 | ArrayMap getHeaders(); 2200 | 2201 | /** 2202 | * 用于页面异常关闭保存数据(在Activity对应的生命周期调用) 2203 | */ 2204 | void onSaveInstanceState(Bundle outState); 2205 | 2206 | /** 2207 | * 用于页面异常关闭恢复数据(在Activity对应的生命周期调用) 2208 | */ 2209 | void onCreate(Bundle outState); 2210 | } 2211 | ``` 2212 | 2213 | TimeoutListener.java 2214 | 2215 | ```java 2216 | /** 2217 | * 描述: 接口超时配置 2218 | * 作者:lpx 2219 | * 日期: 2021/12/3 2220 | */ 2221 | interface TimeoutListener { 2222 | /** 2223 | * 连接超时时间 2224 | */ 2225 | long connectTimeout(); 2226 | 2227 | /** 2228 | * 读取超时时间 2229 | */ 2230 | long readTimeout(); 2231 | 2232 | /** 2233 | * 写入超时时间 2234 | */ 2235 | long writeTimeout(); 2236 | 2237 | } 2238 | ``` 2239 | 2240 | 是不是很方便快捷,希望本文可以帮助到您,也希望各位不吝赐教,提出您在使用中的宝贵意见,谢谢。 2241 | 2242 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/cbc7403dc04040c5823f0092d062c9e5.jpg?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54mnLueJpw==,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center) 2243 | 2244 | --------------------------------------------------------------------------------