├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── layout
│ │ │ │ ├── activity_auto_cancel_task.xml
│ │ │ │ └── activity_main.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── qpg
│ │ │ │ └── superhttpdemo
│ │ │ │ ├── Test.java
│ │ │ │ ├── UserBean.java
│ │ │ │ ├── CustomApiFunc.java
│ │ │ │ ├── MyObserver.java
│ │ │ │ └── AutoCancelTaskActivity.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── qpg
│ │ │ └── superhttpdemo
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── qpg
│ │ └── superhttpdemo
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── superhttp
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ └── values
│ │ │ └── strings.xml
│ │ ├── java
│ │ └── com
│ │ │ └── qpg
│ │ │ └── superhttp
│ │ │ ├── subscriber
│ │ │ ├── IProgressDialog.java
│ │ │ ├── ProgressCancelListener.java
│ │ │ ├── DownCallbackSubscriber.java
│ │ │ ├── ApiSubscriber.java
│ │ │ └── ApiCallbackSubscriber.java
│ │ │ ├── interf
│ │ │ └── ILoader.java
│ │ │ ├── callback
│ │ │ ├── DownloadCallback.java
│ │ │ ├── UCallback.java
│ │ │ ├── BaseCallback.java
│ │ │ ├── SimpleCallBack.java
│ │ │ ├── StringCallBack.java
│ │ │ ├── LoadingViewCallBack.java
│ │ │ └── ProgressDialogCallBack.java
│ │ │ ├── cache
│ │ │ ├── ICache.java
│ │ │ └── DiskCache.java
│ │ │ ├── request
│ │ │ ├── RetrofitRequest.java
│ │ │ ├── GetRequest.java
│ │ │ ├── HeadRequest.java
│ │ │ ├── PutRequest.java
│ │ │ ├── SynRequest.java
│ │ │ ├── OptionsRequest.java
│ │ │ ├── DeleteRequest.java
│ │ │ ├── PatchRequest.java
│ │ │ ├── DownloadRequest.java
│ │ │ └── PostRequest.java
│ │ │ ├── strategy
│ │ │ ├── ICacheStrategy.java
│ │ │ ├── OnlyCacheStrategy.java
│ │ │ ├── OnlyRemoteStrategy.java
│ │ │ ├── CacheAndRemoteStrategy.java
│ │ │ ├── FirstCacheStrategy.java
│ │ │ ├── FirstRemoteStrategy.java
│ │ │ └── CacheStrategy.java
│ │ │ ├── utils
│ │ │ ├── GsonUtil.java
│ │ │ ├── MD5Util.java
│ │ │ └── CommonUtil.java
│ │ │ ├── netexpand
│ │ │ ├── convert
│ │ │ │ ├── JsonResponseBodyConverter.java
│ │ │ │ ├── GsonRequestBodyConverter.java
│ │ │ │ ├── GsonResponseBodyConverter.java
│ │ │ │ └── GsonConverterFactory.java
│ │ │ ├── func
│ │ │ │ ├── ApiDataFunc.java
│ │ │ │ └── ApiResultFunc.java
│ │ │ ├── temp
│ │ │ │ ├── IResponseState.java
│ │ │ │ ├── Utils.java
│ │ │ │ └── DefaultResponseState.java
│ │ │ ├── mode
│ │ │ │ ├── ResponseCode.java
│ │ │ │ └── ApiResult.java
│ │ │ ├── common
│ │ │ │ └── ResponseHelper.java
│ │ │ ├── request
│ │ │ │ ├── ApiBaseRequest.java
│ │ │ │ ├── ApiGetRequest.java
│ │ │ │ └── ApiPostRequest.java
│ │ │ └── interceptor
│ │ │ │ └── HttpResponseInterceptor.java
│ │ │ ├── interceptor
│ │ │ ├── NoCacheInterceptor.java
│ │ │ ├── HeadersInterceptorNormal.java
│ │ │ ├── HeadersInterceptorDynamic.java
│ │ │ ├── UploadProgressInterceptor.java
│ │ │ ├── OnlineCacheInterceptor.java
│ │ │ ├── OfflineCacheInterceptor.java
│ │ │ └── GzipRequestInterceptor.java
│ │ │ ├── mode
│ │ │ ├── CacheMode.java
│ │ │ ├── CacheResult.java
│ │ │ ├── MediaTypes.java
│ │ │ ├── ApiHost.java
│ │ │ ├── ApiCode.java
│ │ │ ├── DownProgress.java
│ │ │ └── HttpHeaders.java
│ │ │ ├── cookie
│ │ │ ├── store
│ │ │ │ ├── CookieStore.java
│ │ │ │ ├── MemoryCookieStore.java
│ │ │ │ └── SPCookieStore.java
│ │ │ └── CookieJarImpl.java
│ │ │ ├── transformer
│ │ │ ├── ApiFunc.java
│ │ │ ├── ApiRetryFunc.java
│ │ │ └── DownloadFunction.java
│ │ │ ├── config
│ │ │ └── SuperConfig.java
│ │ │ ├── lifecycle
│ │ │ └── BaseLifeCycleObserver.java
│ │ │ ├── core
│ │ │ ├── ApiTransformer.java
│ │ │ ├── ApiManager.java
│ │ │ └── ApiCache.java
│ │ │ ├── api
│ │ │ └── ApiService.java
│ │ │ ├── upload
│ │ │ └── UploadProgressRequestBody.java
│ │ │ └── exception
│ │ │ └── ApiException.java
│ │ └── AndroidManifest.xml
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .idea
├── caches
│ └── build_file_checksums.ser
├── encodings.xml
├── vcs.xml
├── modules.xml
├── runConfigurations.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
└── misc.xml
├── .gitignore
├── gradle.properties
├── bintray.gradle
├── gradlew.bat
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/superhttp/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':superhttp'
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SuperHttpDemo
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/superhttp/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SuperHttp
3 |
4 |
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qiaodashaoye/SuperHttp/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/subscriber/IProgressDialog.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.subscriber;
2 |
3 | import android.app.Dialog;
4 |
5 | /**
6 | *
描述:自定义对话框的dialog
7 | */
8 | public interface IProgressDialog {
9 | Dialog getDialog();
10 | }
11 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interf/ILoader.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interf;
2 |
3 | /**
4 | * @author qpg
5 | * @date 2017/11/22 0022
6 | * @description:
7 | */
8 | public interface ILoader {
9 | void showLoader();
10 | void hideLoader();
11 | }
12 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Feb 24 21:52:37 CST 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
7 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/callback/DownloadCallback.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.callback;
2 |
3 | /**
4 | * @Description: 下载进度回调
5 | */
6 | public abstract class DownloadCallback extends BaseCallback{
7 | public abstract void onProgress(long currentLength, long totalLength, float percent);
8 | }
9 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/callback/UCallback.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.callback;
2 |
3 | /**
4 | * @Description: 上传进度回调
5 | */
6 | public interface UCallback {
7 | void onProgress(long currentLength, long totalLength, float percent);
8 | void onFail(int errCode, String errMsg);
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/subscriber/ProgressCancelListener.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.subscriber;
2 |
3 | /**
4 | * 描述:进度框取消监听
5 | * 作者: zhouyou
6 | * 日期: 2017/5/15 17:09
7 | * 版本: v1.0
8 | */
9 | public interface ProgressCancelListener {
10 | void onCancelProgress();
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/cache/ICache.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.cache;
2 |
3 | /**
4 | * @Description: 缓存接口
5 | */
6 | public interface ICache {
7 | void put(String key, Object value);
8 |
9 | Object get(String key);
10 |
11 | boolean contains(String key);
12 |
13 | void remove(String key);
14 |
15 | void clear();
16 | }
17 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/callback/BaseCallback.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.callback;
2 |
3 | /**
4 | * @Description: 请求接口回调
5 | */
6 | public abstract class BaseCallback {
7 | public abstract void onStart();
8 |
9 | public abstract void onSuccess(T data);
10 |
11 | public abstract void onFail(int errCode, String errMsg);
12 |
13 | public abstract void onCompleted();
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qpg/superhttpdemo/Test.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttpdemo;
2 |
3 | import androidx.activity.ComponentActivity;
4 | import androidx.lifecycle.Lifecycle;
5 |
6 | public class Test {
7 | public Test(ComponentActivity activity){
8 | Lifecycle lifecycle= activity.getLifecycle();
9 | activity.getLifecycle().addObserver(new MyObserver(activity.getLifecycle(),activity));
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/superhttp/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/request/RetrofitRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.request;
2 |
3 | /**
4 | * @Description: 传入自定义Retrofit接口的请求类型
5 | */
6 | public class RetrofitRequest extends BaseRequest {
7 |
8 | public RetrofitRequest() {
9 |
10 | }
11 |
12 | public T create(Class cls) {
13 | generateGlobalConfig();
14 | generateLocalConfig();
15 | return retrofit.create(cls);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/strategy/ICacheStrategy.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.strategy;
2 |
3 | import com.qpg.superhttp.core.ApiCache;
4 | import com.qpg.superhttp.mode.CacheResult;
5 |
6 | import java.lang.reflect.Type;
7 |
8 | import io.reactivex.Observable;
9 |
10 | /**
11 | * @Description: 缓存策略接口
12 | */
13 | public interface ICacheStrategy {
14 | Observable> execute(ApiCache apiCache, String cacheKey, Observable source, Type type);
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_auto_cancel_task.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/com/qpg/superhttpdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttpdemo;
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() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/subscriber/DownCallbackSubscriber.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.subscriber;
2 |
3 | import com.qpg.superhttp.callback.BaseCallback;
4 |
5 | /**
6 | * @Description: 包含下载进度回调的订阅者
7 | */
8 | public class DownCallbackSubscriber extends ApiCallbackSubscriber {
9 | public DownCallbackSubscriber(BaseCallback callBack) {
10 | super(callBack);
11 | }
12 |
13 | @Override
14 | public void onComplete() {
15 | super.onComplete();
16 | callBack.onSuccess(super.data);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/strategy/OnlyCacheStrategy.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.strategy;
2 |
3 | import com.qpg.superhttp.core.ApiCache;
4 | import com.qpg.superhttp.mode.CacheResult;
5 |
6 | import java.lang.reflect.Type;
7 |
8 | import io.reactivex.Observable;
9 |
10 | /**
11 | * @Description: 缓存策略--只取缓存
12 | */
13 | public class OnlyCacheStrategy extends CacheStrategy {
14 | @Override
15 | public Observable> execute(ApiCache apiCache, String cacheKey, Observable source, Type type) {
16 | return loadCache(apiCache, cacheKey, type);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/strategy/OnlyRemoteStrategy.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.strategy;
2 | import com.qpg.superhttp.core.ApiCache;
3 | import com.qpg.superhttp.mode.CacheResult;
4 |
5 | import java.lang.reflect.Type;
6 |
7 | import io.reactivex.Observable;
8 |
9 | /**
10 | * @Description: 缓存策略--只取网络
11 | */
12 | public class OnlyRemoteStrategy extends CacheStrategy {
13 | @Override
14 | public Observable> execute(ApiCache apiCache, String cacheKey, Observable source, Type type) {
15 | return loadRemote(apiCache, cacheKey, source);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/utils/GsonUtil.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.utils;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | /**
6 | * @Description: Gson单例操作
7 | */
8 | public class GsonUtil{
9 | private static Gson gson;
10 |
11 | public static Gson gson() {
12 | if (gson == null) {
13 | synchronized (Gson.class) {
14 | if (gson == null) {
15 | gson = (new GsonBuilder()).disableHtmlEscaping().create();
16 | }
17 | }
18 | }
19 | return gson;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/convert/JsonResponseBodyConverter.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.convert;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import java.io.IOException;
6 |
7 | import okhttp3.ResponseBody;
8 | import retrofit2.Converter;
9 |
10 | /**
11 | * @Description: ResponseBody to T
12 | */
13 | final class JsonResponseBodyConverter implements Converter {
14 |
15 | JsonResponseBodyConverter() {
16 | }
17 |
18 | @Override
19 | public T convert(@NonNull ResponseBody value) throws IOException {
20 | return (T) value.string();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/callback/SimpleCallBack.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.callback;
2 |
3 | /**
4 | * 描述:简单的回调,默认可以使用该回调,不用关注其他回调方法
5 | * 使用该回调默认只需要处理onError,onSuccess两个方法既成功失败
6 | */
7 | public abstract class SimpleCallBack extends BaseCallback {
8 |
9 | @Override
10 | public void onStart() {
11 | // if(!CommonUtil.isConnected(SuperHttp.getContext())){
12 | // Toast.makeText(SuperHttp.getContext(),"网络连接错误",Toast.LENGTH_LONG).show();
13 | // onCompleted();
14 | // }
15 | }
16 |
17 | @Override
18 | public void onCompleted() {
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/callback/StringCallBack.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.callback;
2 |
3 | /**
4 | * 描述:简单的回调,默认可以使用该回调,不用关注其他回调方法
5 | * 使用该回调默认只需要处理onError,onSuccess两个方法既成功失败
6 | */
7 | public abstract class StringCallBack extends BaseCallback {
8 |
9 | @Override
10 | public void onStart() {
11 | // if(!CommonUtil.isConnected(SuperHttp.getContext())){
12 | // Toast.makeText(SuperHttp.getContext(),"网络连接错误",Toast.LENGTH_LONG).show();
13 | // onCompleted();
14 | // }
15 | }
16 |
17 | @Override
18 | public void onCompleted() {
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/func/ApiDataFunc.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.func;
2 |
3 | import com.qpg.superhttp.netexpand.common.ResponseHelper;
4 | import com.qpg.superhttp.netexpand.mode.ApiResult;
5 |
6 | import io.reactivex.functions.Function;
7 |
8 | /**
9 | * @Description: ApiResult转T
10 | */
11 | public class ApiDataFunc implements Function, T> {
12 | public ApiDataFunc() {
13 | }
14 |
15 | @Override
16 | public T apply(ApiResult response) throws Exception {
17 | if (ResponseHelper.isSuccess(response)) {
18 | return response.getData();
19 | }
20 | return null;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/temp/IResponseState.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.temp;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @Description:
7 | * @date: 2018/1/20 16:27
8 | */
9 | public interface IResponseState {
10 | //HTTP请求成功状态码
11 | int httpSuccess();
12 | //AccessToken错误或已过期
13 | int accessTokenExpired();
14 | //RefreshToken错误或已过期
15 | int refreshTokenExpired();
16 | //帐号在其它手机已登录
17 | int otherPhoneLogin();
18 | //时间戳过期
19 | int timestampError();
20 | //缺少授权信息,没有AccessToken
21 | int noAccessToken();
22 | //签名错误
23 | int signError();
24 | //其他错误
25 | List otherError();
26 | }
27 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/subscriber/ApiSubscriber.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.subscriber;
2 |
3 | import com.qpg.superhttp.exception.ApiException;
4 | import com.qpg.superhttp.mode.ApiCode;
5 |
6 | import io.reactivex.observers.DisposableObserver;
7 |
8 | /**
9 | * @Description: API统一订阅者
10 | */
11 | abstract class ApiSubscriber extends DisposableObserver {
12 |
13 | ApiSubscriber() {
14 |
15 | }
16 |
17 | @Override
18 | public void onError(Throwable e) {
19 | if (e instanceof ApiException) {
20 | onError((ApiException) e);
21 | } else {
22 | onError(new ApiException(e, ApiCode.Request.UNKNOWN));
23 | }
24 | }
25 |
26 | protected abstract void onError(ApiException e);
27 | }
28 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/mode/ResponseCode.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.mode;
2 |
3 | /**
4 | * @Description: Response响应码(根据服务器提供文档进行定义)
5 | */
6 | public class ResponseCode {
7 | //HTTP请求成功状态码
8 | public static final int HTTP_SUCCESS = 0;
9 | //AccessToken错误或已过期
10 | public static final int ACCESS_TOKEN_EXPIRED = 10001;
11 | //RefreshToken错误或已过期
12 | public static final int REFRESH_TOKEN_EXPIRED = 10002;
13 | //帐号在其它手机已登录
14 | public static final int OTHER_PHONE_LOGIN = 10003;
15 | //时间戳过期
16 | public static final int TIMESTAMP_ERROR = 10004;
17 | //缺少授权信息,没有AccessToken
18 | public static final int NO_ACCESS_TOKEN = 10005;
19 | //签名错误
20 | public static final int SIGN_ERROR = 10006;
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qpg/superhttpdemo/UserBean.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttpdemo;
2 |
3 | /**
4 | * Created by Administrator on 2017/11/9 0009.
5 | */
6 |
7 | public class UserBean {
8 | private long id;
9 | private String userName;
10 |
11 | public long getId() {
12 | return id;
13 | }
14 |
15 | public void setId(long id) {
16 | this.id = id;
17 | }
18 |
19 | public String getUserName() {
20 | return userName;
21 | }
22 |
23 | public void setUserName(String userName) {
24 | this.userName = userName;
25 | }
26 |
27 | public String getAvatarUrl() {
28 | return avatarUrl;
29 | }
30 |
31 | public void setAvatarUrl(String avatarUrl) {
32 | this.avatarUrl = avatarUrl;
33 | }
34 |
35 | private String avatarUrl;
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/temp/Utils.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.temp;
2 |
3 | /**
4 | * @Description:
5 | * @date: 2018/1/20 16:37
6 | */
7 | public class Utils {
8 | public static T checkNotNull(T t, String message) {
9 | if (t == null) {
10 | throw new NullPointerException(message);
11 | }
12 | return t;
13 | }
14 |
15 | public static T checkIllegalArgument(T t, String message) {
16 | if (t == null) {
17 | throw new IllegalArgumentException(message);
18 | }
19 | return t;
20 | }
21 |
22 | public static void checkIllegalArgument(boolean condition, String message) {
23 | if (condition) {
24 | throw new IllegalArgumentException(message);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/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
22 |
--------------------------------------------------------------------------------
/superhttp/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
22 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interceptor/NoCacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interceptor;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import java.io.IOException;
6 |
7 | import okhttp3.Interceptor;
8 | import okhttp3.Request;
9 | import okhttp3.Response;
10 |
11 | /**
12 | * @Description: 无缓存拦截
13 | */
14 | public class NoCacheInterceptor implements Interceptor {
15 |
16 | @Override
17 | public Response intercept(@NonNull Chain chain) throws IOException {
18 | Request request = chain.request();
19 | request = request.newBuilder().header("Cache-Control", "no-cache").build();
20 | Response originalResponse = chain.proceed(request);
21 | originalResponse = originalResponse.newBuilder().header("Cache-Control", "no-cache").build();
22 | return originalResponse;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/qpg/superhttpdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttpdemo;
2 |
3 | import android.content.Context;
4 | import androidx.test.InstrumentationRegistry;
5 | import androidx.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.qpg.superhttpdemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/mode/CacheMode.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.mode;
2 |
3 | /**
4 | * @Description: 缓存模式
5 | */
6 | public enum CacheMode {
7 | /**
8 | * 先请求网络,请求网络失败后再加载缓存
9 | */
10 | FIRST_REMOTE("FirstRemoteStrategy"),
11 |
12 | /**
13 | * 先加载缓存,缓存没有再去请求网络
14 | */
15 | FIRST_CACHE("FirstCacheStrategy"),
16 |
17 | /**
18 | * 仅加载网络,但数据依然会被缓存
19 | */
20 | ONLY_REMOTE("OnlyRemoteStrategy"),
21 |
22 | /**
23 | * 只读取缓存
24 | */
25 | ONLY_CACHE("OnlyCacheStrategy"),
26 |
27 | /**
28 | * 先使用缓存,不管是否存在,仍然请求网络,会回调两次
29 | */
30 | CACHE_AND_REMOTE("CacheAndRemoteStrategy");
31 |
32 | private final String className;
33 |
34 | CacheMode(String className) {
35 | this.className = className;
36 | }
37 |
38 | public String getClassName() {
39 | return className;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/cookie/store/CookieStore.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.cookie.store;
2 |
3 | import java.util.List;
4 |
5 | import okhttp3.Cookie;
6 | import okhttp3.HttpUrl;
7 |
8 | public interface CookieStore {
9 |
10 | /** 保存url对应所有cookie */
11 | void saveCookie(HttpUrl url, List cookie);
12 |
13 | /** 保存url对应所有cookie */
14 | void saveCookie(HttpUrl url, Cookie cookie);
15 |
16 | /** 加载url所有的cookie */
17 | List loadCookie(HttpUrl url);
18 |
19 | /** 获取当前所有保存的cookie */
20 | List getAllCookie();
21 |
22 | /** 获取当前url对应的所有的cookie */
23 | List getCookie(HttpUrl url);
24 |
25 | /** 根据url和cookie移除对应的cookie */
26 | boolean removeCookie(HttpUrl url, Cookie cookie);
27 |
28 | /** 根据url移除所有的cookie */
29 | boolean removeCookie(HttpUrl url);
30 |
31 | /** 移除所有的cookie */
32 | boolean removeAllCookie();
33 | }
34 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/cookie/CookieJarImpl.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.cookie;
2 |
3 | import com.qpg.superhttp.cookie.store.CookieStore;
4 |
5 | import java.util.List;
6 |
7 | import okhttp3.Cookie;
8 | import okhttp3.CookieJar;
9 | import okhttp3.HttpUrl;
10 |
11 | public class CookieJarImpl implements CookieJar {
12 |
13 | private CookieStore cookieStore;
14 |
15 | public CookieJarImpl(CookieStore cookieStore) {
16 | if (cookieStore == null) {
17 | throw new IllegalArgumentException("cookieStore can not be null!");
18 | }
19 | this.cookieStore = cookieStore;
20 | }
21 |
22 | @Override
23 | public synchronized void saveFromResponse(HttpUrl url, List cookies) {
24 | cookieStore.saveCookie(url, cookies);
25 | }
26 |
27 | @Override
28 | public synchronized List loadForRequest(HttpUrl url) {
29 | return cookieStore.loadCookie(url);
30 | }
31 |
32 | public CookieStore getCookieStore() {
33 | return cookieStore;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/transformer/ApiFunc.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.transformer;
2 |
3 | import com.google.gson.Gson;
4 | import java.io.IOException;
5 | import java.lang.reflect.Type;
6 | import io.reactivex.functions.Function;
7 | import okhttp3.ResponseBody;
8 |
9 | /**
10 | * @Description: ResponseBody转T
11 | */
12 | public class ApiFunc implements Function {
13 | private Type type;
14 |
15 | public ApiFunc(Type type) {
16 | this.type = type;
17 | }
18 |
19 | @Override
20 | public T apply(ResponseBody responseBody) throws Exception {
21 | Gson gson = new Gson();
22 | String json;
23 | try {
24 | json = responseBody.string();
25 | if (type.equals(String.class)) {
26 | return (T) json;
27 | } else {
28 | return gson.fromJson(json, type);
29 | }
30 | } catch (IOException e) {
31 | e.printStackTrace();
32 | } finally {
33 | responseBody.close();
34 | }
35 | return null;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/mode/CacheResult.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.mode;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @Description: 设置缓存后的数据返回结果,主要增加是否是缓存数据的区分
7 | */
8 | public class CacheResult implements Serializable {
9 | private boolean isCache;
10 | private T cacheData;
11 |
12 | public CacheResult(boolean isCache, T cacheData) {
13 | this.isCache = isCache;
14 | this.cacheData = cacheData;
15 | }
16 |
17 | public boolean isCache() {
18 | return isCache;
19 | }
20 |
21 | public CacheResult setCache(boolean cache) {
22 | isCache = cache;
23 | return this;
24 | }
25 |
26 | public T getCacheData() {
27 | return cacheData;
28 | }
29 |
30 | public CacheResult setCacheData(T cacheData) {
31 | this.cacheData = cacheData;
32 | return this;
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "CacheResult{" +
38 | "isCache=" + isCache +
39 | ", cacheData=" + cacheData +
40 | '}';
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/strategy/CacheAndRemoteStrategy.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.strategy;
2 |
3 | import com.qpg.superhttp.core.ApiCache;
4 | import com.qpg.superhttp.mode.CacheResult;
5 |
6 | import java.lang.reflect.Type;
7 |
8 | import io.reactivex.Observable;
9 | import io.reactivex.functions.Predicate;
10 |
11 | /**
12 | * @Description: 缓存策略--缓存和网络
13 | */
14 | public class CacheAndRemoteStrategy extends CacheStrategy {
15 | @Override
16 | public Observable> execute(ApiCache apiCache, String cacheKey, Observable source, final Type type) {
17 | Observable> cache = loadCache(apiCache, cacheKey, type);
18 | final Observable> remote = loadRemote(apiCache, cacheKey, source);
19 | return Observable.concat(cache, remote).filter(new Predicate>() {
20 | @Override
21 | public boolean test(CacheResult tCacheResult) throws Exception {
22 | return tCacheResult != null && tCacheResult.getCacheData() != null;
23 | }
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/mode/ApiResult.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.mode;
2 |
3 | /**
4 | * @Description: 封装的通用服务器返回对象,可自行定义
5 | * @date: 2016-12-30 16:43
6 | */
7 | public class ApiResult {
8 | private int code;
9 | private String msg;
10 | private T data;
11 |
12 | public int getCode() {
13 | return code;
14 | }
15 |
16 | public ApiResult setCode(int code) {
17 | this.code = code;
18 | return this;
19 | }
20 |
21 | public String getMsg() {
22 | return msg;
23 | }
24 |
25 | public ApiResult setMsg(String msg) {
26 | this.msg = msg;
27 | return this;
28 | }
29 |
30 | public T getData() {
31 | return data;
32 | }
33 |
34 | public ApiResult setData(T data) {
35 | this.data = data;
36 | return this;
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return "ApiResult{" +
42 | "code=" + code +
43 | ", msg='" + msg + '\'' +
44 | ", data=" + data +
45 | '}';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interceptor/HeadersInterceptorNormal.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interceptor;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import java.io.IOException;
6 | import java.util.Map;
7 | import java.util.Set;
8 |
9 | import okhttp3.Interceptor;
10 | import okhttp3.Request;
11 | import okhttp3.Response;
12 |
13 | /**
14 | * @Description: 请求头拦截
15 | */
16 | public class HeadersInterceptorNormal implements Interceptor {
17 |
18 | private Map headers;
19 |
20 | public HeadersInterceptorNormal(Map headers) {
21 | this.headers = headers;
22 | }
23 |
24 | @Override
25 | public Response intercept(@NonNull Chain chain) throws IOException {
26 | Request.Builder builder = chain.request().newBuilder();
27 | if (headers != null && headers.size() > 0) {
28 | Set keys = headers.keySet();
29 | for (String headerKey : keys) {
30 | builder.addHeader(headerKey, headers.get(headerKey)).build();
31 | }
32 | }
33 | return chain.proceed(builder.build());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qpg/superhttpdemo/CustomApiFunc.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttpdemo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import java.io.IOException;
6 | import java.lang.reflect.Type;
7 |
8 | import io.reactivex.functions.Function;
9 | import okhttp3.ResponseBody;
10 |
11 | /**
12 | * @Description: 自定义ResponseBody转T,
13 | * 可根据每个项目返回的数据格式自定义,提高了扩展性
14 | */
15 | public class CustomApiFunc implements Function {
16 | private Type type;
17 |
18 | public CustomApiFunc(Type type) {
19 | this.type = type;
20 | }
21 |
22 | @Override
23 | public T apply(ResponseBody responseBody) throws Exception {
24 | Gson gson = new Gson();
25 | String json;
26 | try {
27 | json = responseBody.string();
28 | if (type.equals(String.class)) {
29 | return (T) json;
30 | } else {
31 | return gson.fromJson(json, type);
32 | }
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | } finally {
36 | responseBody.close();
37 | }
38 | return null;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | defaultConfig {
6 | applicationId "com.qpg.superhttpdemo"
7 | minSdkVersion 21
8 | targetSdkVersion 29
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | compileOptions {
20 | sourceCompatibility = '1.8'
21 | targetCompatibility = '1.8'
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(include: ['*.jar'], dir: 'libs')
27 | implementation 'androidx.appcompat:appcompat:1.2.0'
28 | implementation 'androidx.constraintlayout:constraintlayout:2.0.0-rc1'
29 | testImplementation 'junit:junit:4.13'
30 | androidTestImplementation 'androidx.test:runner:1.3.0-rc03'
31 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-rc03'
32 | api project(':superhttp')
33 | }
34 |
--------------------------------------------------------------------------------
/superhttp/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 29
5 |
6 | defaultConfig {
7 | minSdkVersion 21
8 | targetSdkVersion 29
9 | versionCode 1
10 | versionName "1.1.3"
11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
12 | }
13 |
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 |
21 | lintOptions {
22 | abortOnError false
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | implementation 'androidx.appcompat:appcompat:1.2.0'
30 | api 'com.squareup.okhttp3:logging-interceptor:4.9.0'
31 | api 'com.squareup.okhttp3:okhttp:4.9.0'
32 | api 'io.reactivex.rxjava2:rxjava:2.2.19'
33 | api 'io.reactivex.rxjava2:rxandroid:2.1.1'
34 | api 'com.squareup.retrofit2:retrofit:2.9.0'
35 | api 'com.squareup.retrofit2:converter-gson:2.9.0'
36 | api 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
37 | }
38 | apply from: '../bintray.gradle'
39 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/common/ResponseHelper.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.common;
2 |
3 | import com.qpg.superhttp.netexpand.mode.ApiResult;
4 | import com.qpg.superhttp.netexpand.mode.ResponseCode;
5 |
6 | /**
7 | * @Description: 响应处理帮助类
8 | */
9 | public class ResponseHelper {
10 |
11 | public static boolean isSuccess(ApiResult apiResult) {
12 | if (apiResult == null) {
13 | return false;
14 | }
15 | return apiResult.getCode() == ResponseCode.HTTP_SUCCESS || ignoreSomeIssue(apiResult.getCode());
16 | }
17 |
18 | private static boolean ignoreSomeIssue(int code) {
19 | switch (code) {
20 | case ResponseCode.TIMESTAMP_ERROR://时间戳过期
21 | case ResponseCode.ACCESS_TOKEN_EXPIRED://AccessToken错误或已过期
22 | case ResponseCode.REFRESH_TOKEN_EXPIRED://RefreshToken错误或已过期
23 | case ResponseCode.OTHER_PHONE_LOGIN://帐号在其它手机已登录
24 | case ResponseCode.NO_ACCESS_TOKEN://缺少授权信息,没有AccessToken
25 | case ResponseCode.SIGN_ERROR://签名错误
26 | return true;
27 | default:
28 | return false;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/temp/DefaultResponseState.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.temp;
2 |
3 | import com.qpg.superhttp.netexpand.mode.ResponseCode;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @Description:
9 | * @date: 2018/1/20 16:31
10 | */
11 | public class DefaultResponseState implements IResponseState {
12 | @Override
13 | public int httpSuccess() {
14 | return ResponseCode.HTTP_SUCCESS;
15 | }
16 |
17 | @Override
18 | public int accessTokenExpired() {
19 | return ResponseCode.ACCESS_TOKEN_EXPIRED;
20 | }
21 |
22 | @Override
23 | public int refreshTokenExpired() {
24 | return ResponseCode.REFRESH_TOKEN_EXPIRED;
25 | }
26 |
27 | @Override
28 | public int otherPhoneLogin() {
29 | return ResponseCode.OTHER_PHONE_LOGIN;
30 | }
31 |
32 | @Override
33 | public int timestampError() {
34 | return ResponseCode.TIMESTAMP_ERROR;
35 | }
36 |
37 | @Override
38 | public int noAccessToken() {
39 | return ResponseCode.NO_ACCESS_TOKEN;
40 | }
41 |
42 | @Override
43 | public int signError() {
44 | return ResponseCode.SIGN_ERROR;
45 | }
46 |
47 | @Override
48 | public List otherError() {
49 | return null;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interceptor/HeadersInterceptorDynamic.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interceptor;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import java.io.IOException;
6 | import java.nio.charset.Charset;
7 | import java.util.Map;
8 | import java.util.Set;
9 |
10 | import okhttp3.Interceptor;
11 | import okhttp3.Request;
12 | import okhttp3.Response;
13 |
14 | public class HeadersInterceptorDynamic implements Interceptor {
15 | private final Headers mHeaders;
16 | private static final Charset UTF8 = Charset.forName("UTF-8");
17 |
18 | public HeadersInterceptorDynamic(Headers headers) {
19 | this.mHeaders = headers;
20 | }
21 | @Override
22 | public Response intercept(@NonNull Chain chain) throws IOException {
23 | Map headers=mHeaders.headers();
24 | Request.Builder builder = chain.request().newBuilder();
25 | if (headers != null && headers.size() > 0) {
26 | Set keys = headers.keySet();
27 | for (String headerKey : keys) {
28 | builder.addHeader(headerKey, headers.get(headerKey)).build();
29 | }
30 | }
31 | return chain.proceed(builder.build());
32 | }
33 | public interface Headers{
34 | Map headers();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
19 | GROUP=com.qpg.net
20 | SITE_URL=https://github.com/qiaodashaoye/SuperHttp
21 | GIT_URL=https://github.com/qiaodashaoye/SuperHttp.git
22 |
23 | PACKAGING=aar
24 | DESCRIBE=This is a lightweight HttpRequest framework
25 |
26 | LICENSE_NAME=The Apache Software License, Version 2.0
27 | LICENSE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
28 |
29 | DEVELOPER_ID=SuperHttp
30 | DEVELOPER_NAME=qpg
31 | DEVELOPER_EMAIL=1451449315@qq.com
32 |
33 | USERORG=q-p-g
34 | PROJECT_REPO=maven
35 | PROJECT_NAME=SuperHttp
36 | PROJECT_PUBLISH=true
37 | android.useAndroidX=true
38 | android.enableJetifier=true
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interceptor/UploadProgressInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interceptor;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import com.qpg.superhttp.upload.UploadProgressRequestBody;
6 | import com.qpg.superhttp.callback.UCallback;
7 |
8 | import java.io.IOException;
9 |
10 | import okhttp3.Interceptor;
11 | import okhttp3.Request;
12 | import okhttp3.Response;
13 |
14 | /**
15 | * @Description: 上传进度拦截
16 | */
17 | public class UploadProgressInterceptor implements Interceptor {
18 |
19 | private UCallback callback;
20 |
21 | public UploadProgressInterceptor(UCallback callback) {
22 | this.callback = callback;
23 | if (callback == null) {
24 | throw new NullPointerException("this callback must not null.");
25 | }
26 | }
27 |
28 | @Override
29 | public Response intercept(@NonNull Chain chain) throws IOException {
30 | Request originalRequest = chain.request();
31 | if (originalRequest.body() == null) {
32 | return chain.proceed(originalRequest);
33 | }
34 | Request progressRequest = originalRequest.newBuilder()
35 | .method(originalRequest.method(),
36 | new UploadProgressRequestBody(originalRequest.body(), callback))
37 | .build();
38 | return chain.proceed(progressRequest);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/strategy/FirstCacheStrategy.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.strategy;
2 |
3 | import com.qpg.superhttp.core.ApiCache;
4 | import com.qpg.superhttp.mode.CacheResult;
5 |
6 | import java.lang.reflect.Type;
7 |
8 | import io.reactivex.Observable;
9 | import io.reactivex.functions.Function;
10 | import io.reactivex.functions.Predicate;
11 |
12 | /**
13 | * @Description: 缓存策略--优先缓存
14 | */
15 | public class FirstCacheStrategy extends CacheStrategy {
16 | @Override
17 | public Observable> execute(ApiCache apiCache, String cacheKey, Observable source, Type type) {
18 | Observable> cache = loadCache(apiCache, cacheKey, type);
19 | cache.onErrorReturn(new Function>() {
20 | @Override
21 | public CacheResult apply(Throwable throwable) throws Exception {
22 | return null;
23 | }
24 | });
25 | Observable> remote = loadRemote(apiCache, cacheKey, source);
26 | return Observable.concat(cache, remote).filter(new Predicate>() {
27 | @Override
28 | public boolean test(CacheResult tCacheResult) throws Exception {
29 | return tCacheResult != null && tCacheResult.getCacheData() != null;
30 | }
31 | }).firstElement().toObservable();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/strategy/FirstRemoteStrategy.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.strategy;
2 |
3 | import com.qpg.superhttp.core.ApiCache;
4 | import com.qpg.superhttp.mode.CacheResult;
5 |
6 | import java.lang.reflect.Type;
7 |
8 | import io.reactivex.Observable;
9 | import io.reactivex.functions.Function;
10 | import io.reactivex.functions.Predicate;
11 |
12 | /**
13 | * @Description: 缓存策略--优先网络
14 | */
15 | public class FirstRemoteStrategy extends CacheStrategy {
16 | @Override
17 | public Observable> execute(ApiCache apiCache, String cacheKey, Observable source, Type type) {
18 | Observable> cache = loadCache(apiCache, cacheKey, type);
19 | cache.onErrorReturn(new Function>() {
20 | @Override
21 | public CacheResult apply(Throwable throwable) throws Exception {
22 | return null;
23 | }
24 | });
25 | Observable> remote = loadRemote(apiCache, cacheKey, source);
26 | return Observable.concat(remote, cache).filter(new Predicate>() {
27 | @Override
28 | public boolean test(CacheResult tCacheResult) throws Exception {
29 | return tCacheResult != null && tCacheResult.getCacheData() != null;
30 | }
31 | }).firstElement().toObservable();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/config/SuperConfig.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.config;
2 |
3 | /**
4 | * @Description: 全局常量配置
5 | */
6 | public class SuperConfig {
7 |
8 | public static final String CACHE_SP_NAME = "sp_cache";//默认SharedPreferences缓存文件名
9 | public static final String CACHE_DISK_DIR = "disk_cache";//默认磁盘缓存目录
10 | public static final String CACHE_HTTP_DIR = "http_cache";//默认HTTP缓存目录
11 | public static final long CACHE_NEVER_EXPIRE = -1;//永久不过期
12 |
13 | public static final int MAX_AGE_ONLINE = 60;//默认最大在线缓存时间(秒)
14 | public static final int MAX_AGE_OFFLINE = 24 * 60 * 60;//默认最大离线缓存时间(秒)
15 |
16 | public static final String API_HOST = "https://api.github.com/";//默认API主机地址
17 |
18 | public static final String COOKIE_PREFS = "Cookies_Prefs";//默认Cookie缓存目录
19 |
20 | public static final int DEFAULT_TIMEOUT = 60;//默认超时时间(秒)
21 | public static final int DEFAULT_MAX_IDLE_CONNECTIONS = 5;//默认空闲连接数
22 | public static final long DEFAULT_KEEP_ALIVE_DURATION = 8;//默认心跳间隔时长(秒)
23 | public static final long CACHE_MAX_SIZE = 10 * 1024 * 1024;//默认最大缓存大小(字节)
24 |
25 | public static final int DEFAULT_RETRY_COUNT = 3;//默认重试次数
26 | public static final int DEFAULT_RETRY_DELAY_MILLIS = 3000;//默认重试间隔时间(毫秒)
27 |
28 | public static final String DEFAULT_DOWNLOAD_DIR = "download";//默认下载目录
29 | public static final String DEFAULT_DOWNLOAD_FILE_NAME = "download_file.tmp";//默认下载文件名称
30 | }
31 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/subscriber/ApiCallbackSubscriber.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.subscriber;
2 |
3 | import com.qpg.superhttp.callback.BaseCallback;
4 | import com.qpg.superhttp.exception.ApiException;
5 |
6 | /**
7 | * @Description: 包含回调的订阅者,如果订阅这个,上层在不使用订阅者的情况下可获得回调
8 | */
9 | public class ApiCallbackSubscriber extends ApiSubscriber {
10 |
11 | BaseCallback callBack;
12 | T data;
13 |
14 | public ApiCallbackSubscriber(BaseCallback callBack) {
15 | if (callBack == null) {
16 | throw new NullPointerException("this callback is null!");
17 | }
18 | this.callBack = callBack;
19 | }
20 |
21 | @Override
22 | protected void onStart() {
23 | super.onStart();
24 | if (callBack != null) {
25 | callBack.onStart();
26 | }
27 | }
28 |
29 | @Override
30 | public void onError(ApiException e) {
31 | if (e == null) {
32 | callBack.onFail(-1, "This ApiException is Null.");
33 | return;
34 | }
35 | callBack.onFail(e.getCode(), e.getMessage());
36 | }
37 |
38 | @Override
39 | public void onNext(T t) {
40 | this.data = t;
41 | callBack.onSuccess(t);
42 | }
43 |
44 | @Override
45 | public void onComplete() {
46 | if (callBack != null) {
47 | callBack.onCompleted();
48 | }
49 | }
50 | public T getData() {
51 | return data;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/request/ApiBaseRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.request;
2 |
3 | import com.qpg.superhttp.transformer.ApiRetryFunc;
4 | import com.qpg.superhttp.netexpand.func.ApiDataFunc;
5 | import com.qpg.superhttp.netexpand.mode.ApiResult;
6 | import com.qpg.superhttp.request.BaseHttpRequest;
7 |
8 | import io.reactivex.Observable;
9 | import io.reactivex.ObservableSource;
10 | import io.reactivex.ObservableTransformer;
11 | import io.reactivex.android.schedulers.AndroidSchedulers;
12 | import io.reactivex.schedulers.Schedulers;
13 |
14 | /**
15 | * @Description: 返回APIResult的基础请求类
16 | * @date: 17/5/28 15:46.
17 | */
18 | public abstract class ApiBaseRequest extends BaseHttpRequest {
19 | public ApiBaseRequest(String suffixUrl) {
20 | super(suffixUrl);
21 | }
22 |
23 | protected ObservableTransformer, T> apiTransformer() {
24 | return new ObservableTransformer, T>() {
25 | @Override
26 | public ObservableSource apply(Observable> apiResultObservable) {
27 | return apiResultObservable
28 | .subscribeOn(Schedulers.io())
29 | .unsubscribeOn(Schedulers.io())
30 | .observeOn(AndroidSchedulers.mainThread())
31 | .map(new ApiDataFunc())
32 | .retryWhen(new ApiRetryFunc(retryCount, retryDelayMillis));
33 | }
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/convert/GsonRequestBodyConverter.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.convert;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import com.google.gson.Gson;
6 | import com.google.gson.TypeAdapter;
7 | import com.google.gson.stream.JsonWriter;
8 |
9 | import java.io.IOException;
10 | import java.io.OutputStreamWriter;
11 | import java.io.Writer;
12 | import java.nio.charset.Charset;
13 |
14 | import okhttp3.MediaType;
15 | import okhttp3.RequestBody;
16 | import okio.Buffer;
17 | import retrofit2.Converter;
18 |
19 | /**
20 | * @Description: T to RequestBody
21 | */
22 | final class GsonRequestBodyConverter implements Converter {
23 | private static final MediaType MEDIA_TYPE = MediaType.parse("init/json; charset=UTF-8");
24 | private static final Charset UTF_8 = Charset.forName("UTF-8");
25 |
26 | private final Gson gson;
27 | private final TypeAdapter adapter;
28 |
29 | GsonRequestBodyConverter(Gson gson, TypeAdapter adapter) {
30 | this.gson = gson;
31 | this.adapter = adapter;
32 | }
33 |
34 | @Override
35 | public RequestBody convert(@NonNull T value) throws IOException {
36 | Buffer buffer = new Buffer();
37 | Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
38 | JsonWriter jsonWriter = gson.newJsonWriter(writer);
39 | adapter.write(jsonWriter, value);
40 | jsonWriter.close();
41 | return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/utils/MD5Util.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.utils;
2 |
3 | import java.security.MessageDigest;
4 |
5 | public class MD5Util {
6 | public static String byteArrayToHexString(byte b[]) {
7 | StringBuffer resultSb = new StringBuffer();
8 | for (int i = 0; i < b.length; i++)
9 | resultSb.append(byteToHexString(b[i]));
10 |
11 | return resultSb.toString();
12 | }
13 |
14 | private static String byteToHexString(byte b) {
15 | int n = b;
16 | if (n < 0) {
17 | n += 256;
18 | }
19 | int d1 = n / 16;
20 | int d2 = n % 16;
21 | return hexDigits[d1] + hexDigits[d2];
22 | }
23 |
24 | public static String MD5Encode(String origin, String charsetname) {
25 | String resultString = null;
26 | try {
27 | resultString = new String(origin);
28 | MessageDigest md = MessageDigest.getInstance("MD5");
29 | if (charsetname == null || "".equals(charsetname)) {
30 | resultString = byteArrayToHexString(md.digest(resultString
31 | .getBytes()));
32 | } else {
33 | resultString = byteArrayToHexString(md.digest(resultString
34 | .getBytes(charsetname)));
35 | }
36 | } catch (Exception exception) {
37 | }
38 | return resultString;
39 | }
40 |
41 | private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
42 | "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
43 | }
44 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interceptor/OnlineCacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interceptor;
2 |
3 | import androidx.annotation.NonNull;
4 | import android.text.TextUtils;
5 |
6 | import com.qpg.superhttp.config.SuperConfig;
7 |
8 | import java.io.IOException;
9 |
10 | import okhttp3.Interceptor;
11 | import okhttp3.Response;
12 |
13 | /**
14 | * @Description: 在线缓存拦截
15 | */
16 | public class OnlineCacheInterceptor implements Interceptor {
17 | private String cacheControlValue;
18 |
19 | public OnlineCacheInterceptor() {
20 | this(SuperConfig.MAX_AGE_ONLINE);
21 | }
22 |
23 | public OnlineCacheInterceptor(int cacheControlValue) {
24 | this.cacheControlValue = String.format("max-age=%d", cacheControlValue);
25 | }
26 |
27 | @Override
28 | public Response intercept(@NonNull Chain chain) throws IOException {
29 | Response originalResponse = chain.proceed(chain.request());
30 | String cacheControl = originalResponse.header("Cache-Control");
31 | if (TextUtils.isEmpty(cacheControl) || cacheControl.contains("no-store") || cacheControl.contains("no-cache") || cacheControl
32 | .contains("must-revalidate") || cacheControl.contains("max-age") || cacheControl.contains("max-stale")) {
33 |
34 | return originalResponse.newBuilder()
35 | .header("Cache-Control", "public, " + cacheControlValue)
36 | .removeHeader("Pragma")
37 | .build();
38 |
39 | } else {
40 | return originalResponse;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/mode/MediaTypes.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.mode;
2 |
3 | import okhttp3.MediaType;
4 |
5 | /**
6 | * @Description: MediaType汇总
7 | */
8 | public class MediaTypes {
9 | public static final MediaType APPLICATION_ATOM_XML_TYPE = MediaType.parse("application/atom+xml;charset=utf-8");
10 | public static final MediaType APPLICATION_FORM_URLENCODED_TYPE = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
11 | public static final MediaType APPLICATION_JSON_TYPE = MediaType.parse("application/json;charset=utf-8");
12 | public static final MediaType APPLICATION_OCTET_STREAM_TYPE = MediaType.parse("application/octet-stream");
13 | public static final MediaType APPLICATION_SVG_XML_TYPE = MediaType.parse("application/svg+xml;charset=utf-8");
14 | public static final MediaType APPLICATION_XHTML_XML_TYPE = MediaType.parse("application/xhtml+xml;charset=utf-8");
15 | public static final MediaType APPLICATION_XML_TYPE = MediaType.parse("application/xml;charset=utf-8");
16 | public static final MediaType MULTIPART_FORM_DATA_TYPE = MediaType.parse("multipart/form-data;charset=utf-8");
17 | public static final MediaType TEXT_HTML_TYPE = MediaType.parse("text/html;charset=utf-8");
18 | public static final MediaType TEXT_XML_TYPE = MediaType.parse("text/xml;charset=utf-8");
19 | public static final MediaType TEXT_PLAIN_TYPE = MediaType.parse("text/plain;charset=utf-8");
20 | public static final MediaType IMAGE_TYPE = MediaType.parse("image/*");
21 | public static final MediaType WILDCARD_TYPE = MediaType.parse("*/*");
22 | }
23 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/mode/ApiHost.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.mode;
2 |
3 | import com.qpg.superhttp.config.SuperConfig;
4 |
5 | /**
6 | * @Description: 主机信息
7 | */
8 | public class ApiHost {
9 |
10 | private static String host = SuperConfig.API_HOST;
11 |
12 | public static String getHost() {
13 | return host;
14 | }
15 |
16 | public static void setHost(String url) {
17 | setHostHttps(url);
18 | }
19 |
20 | public static void setHostHttp(String url) {
21 | if (url.startsWith("https://") || url.startsWith("http://")) {
22 | host = url;
23 | host = host.replaceAll("https://", "http://");
24 | } else {
25 | host = "http://" + url;
26 | }
27 | }
28 |
29 | public static void setHostHttps(String url) {
30 | if (url.startsWith("https://") || url.startsWith("http://")) {
31 | host = url;
32 | host = host.replaceAll("http://", "https://");
33 | } else {
34 | host = "https://" + url;
35 | }
36 | }
37 |
38 | public static String getHttp() {
39 | if (host.startsWith("https://") || host.startsWith("http://")) {
40 | host = host.replaceAll("https://", "http://");
41 | } else {
42 | host = "http://" + host;
43 | }
44 | return host;
45 | }
46 |
47 | public static String getHttps() {
48 | if (host.startsWith("https://") || host.startsWith("http://")) {
49 | host = host.replaceAll("http://", "https://");
50 | } else {
51 | host = "https://" + host;
52 | }
53 | return host;
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/transformer/ApiRetryFunc.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.transformer;
2 |
3 | import com.qpg.superhttp.exception.ApiException;
4 |
5 | import java.net.ConnectException;
6 | import java.net.SocketTimeoutException;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | import io.reactivex.Observable;
10 | import io.reactivex.ObservableSource;
11 | import io.reactivex.functions.Function;
12 |
13 | /**
14 | * @Description: 重试机制
15 | */
16 | public class ApiRetryFunc implements Function, Observable>> {
17 |
18 | private final int maxRetries;
19 | private final int retryDelayMillis;
20 | private int retryCount;
21 |
22 | public ApiRetryFunc(int maxRetries, int retryDelayMillis) {
23 | this.maxRetries = maxRetries;
24 | this.retryDelayMillis = retryDelayMillis;
25 | }
26 |
27 | @Override
28 | public Observable> apply(Observable extends Throwable> observable) throws Exception {
29 | return observable
30 | .flatMap(new Function>() {
31 | @Override
32 | public ObservableSource> apply(Throwable throwable) throws Exception {
33 | if (++retryCount <= maxRetries && (throwable instanceof SocketTimeoutException
34 | || throwable instanceof ConnectException)) {
35 | return Observable.timer(retryDelayMillis, TimeUnit.MILLISECONDS);
36 | }
37 | return Observable.error(ApiException.handleException(throwable));
38 | }
39 | });
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interceptor/OfflineCacheInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interceptor;
2 |
3 | import android.content.Context;
4 | import androidx.annotation.NonNull;
5 |
6 | import com.qpg.superhttp.utils.CommonUtil;
7 | import com.qpg.superhttp.config.SuperConfig;
8 |
9 | import java.io.IOException;
10 |
11 | import okhttp3.CacheControl;
12 | import okhttp3.Interceptor;
13 | import okhttp3.Request;
14 | import okhttp3.Response;
15 |
16 | /**
17 | * @Description: 离线缓存拦截
18 | */
19 | public class OfflineCacheInterceptor implements Interceptor {
20 | private Context context;
21 | private String cacheControlValue;
22 |
23 | public OfflineCacheInterceptor(Context context) {
24 | this(context, SuperConfig.MAX_AGE_OFFLINE);
25 | }
26 |
27 | public OfflineCacheInterceptor(Context context, int cacheControlValue) {
28 | this.context = context;
29 | this.cacheControlValue = String.format("max-stale=%d", cacheControlValue);
30 | }
31 |
32 | @Override
33 | public Response intercept(@NonNull Chain chain) throws IOException {
34 | Request request = chain.request();
35 | if (!CommonUtil.isConnected(context)) {
36 | request = request.newBuilder()
37 | .cacheControl(CacheControl.FORCE_CACHE)
38 | .build();
39 | Response response = chain.proceed(request);
40 | return response.newBuilder()
41 | .header("Cache-Control", "public, only-if-cached, " + cacheControlValue)
42 | .removeHeader("Pragma")
43 | .build();
44 | }
45 | return chain.proceed(request);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/mode/ApiCode.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.mode;
2 |
3 | /**
4 | * @Description: 网络通用状态码定义
5 | */
6 | public class ApiCode {
7 |
8 | /**
9 | * 对应HTTP的状态码
10 | */
11 | public static class Http {
12 | public static final int OK = 200;//请求成功。一般用于GET与POST请求
13 | public static final int Bad_Request = 400;//1、客户端请求的语法错误,服务器无法理解。2、请求参数有误。
14 | public static final int UNAUTHORIZED = 401;//请求要求用户的身份认证
15 | public static final int FORBIDDEN = 403;//服务器理解请求客户端的请求,但是拒绝执行此请求
16 | public static final int NOT_FOUND = 404;
17 | public static final int REQUEST_TIMEOUT = 408;//服务器等待客户端发送的请求时间过长,超时
18 | public static final int INTERNAL_SERVER_ERROR = 500;//服务器内部错误,无法完成请求
19 | public static final int BAD_GATEWAY = 502;//作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
20 | public static final int SERVICE_UNAVAILABLE = 503;//由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
21 | public static final int GATEWAY_TIMEOUT = 504;//充当网关或代理的服务器,未及时从远端服务器获取请求
22 | }
23 |
24 | /**
25 | * Request请求码
26 | */
27 | public static class Request {
28 | //未知错误
29 | public static final int UNKNOWN = 1000;
30 | //解析错误
31 | public static final int PARSE_ERROR = 1001;
32 | //网络错误
33 | public static final int NETWORK_ERROR = 1002;
34 | //协议出错
35 | public static final int HTTP_ERROR = 1003;
36 | //证书出错
37 | public static final int SSL_ERROR = 1005;
38 | //连接超时
39 | public static final int TIMEOUT_ERROR = 1006;
40 | //调用错误
41 | public static final int INVOKE_ERROR = 1007;
42 | //类转换错误
43 | public static final int CONVERT_ERROR = 1008;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/interceptor/GzipRequestInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.interceptor;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import java.io.IOException;
6 |
7 | import okhttp3.Interceptor;
8 | import okhttp3.MediaType;
9 | import okhttp3.Request;
10 | import okhttp3.RequestBody;
11 | import okhttp3.Response;
12 | import okio.BufferedSink;
13 | import okio.GzipSink;
14 | import okio.Okio;
15 |
16 | /**
17 | * @Description: 包含Gzip压缩的请求拦截
18 | */
19 | public class GzipRequestInterceptor implements Interceptor {
20 | @Override
21 | public Response intercept(@NonNull Chain chain) throws IOException {
22 | Request originalRequest = chain.request();
23 | if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
24 | return chain.proceed(originalRequest);
25 | }
26 | Request compressedRequest = originalRequest.newBuilder().header("Accept-Encoding", "gzip").method(originalRequest.method(), gzip
27 | (originalRequest.body())).build();
28 | return chain.proceed(compressedRequest);
29 | }
30 |
31 | private RequestBody gzip(final RequestBody body) {
32 | return new RequestBody() {
33 | @Override
34 | public MediaType contentType() {
35 | return body.contentType();
36 | }
37 |
38 | @Override
39 | public long contentLength() {
40 | return -1;
41 | }
42 |
43 | @Override
44 | public void writeTo(@NonNull BufferedSink sink) throws IOException {
45 | BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
46 | body.writeTo(gzipSink);
47 | gzipSink.close();
48 | }
49 | };
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/lifecycle/BaseLifeCycleObserver.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.lifecycle;
2 |
3 | import android.app.Activity;
4 | import android.util.Log;
5 |
6 | import androidx.fragment.app.Fragment;
7 | import androidx.lifecycle.Lifecycle;
8 | import androidx.lifecycle.LifecycleObserver;
9 | import androidx.lifecycle.OnLifecycleEvent;
10 |
11 | import com.qpg.superhttp.SuperHttp;
12 |
13 | public class BaseLifeCycleObserver implements LifecycleObserver {
14 |
15 | private Activity mActivity;
16 | private Fragment mFragment;
17 | private Lifecycle mLifecycle;
18 | private static final String TAG = "1-------->";
19 | public BaseLifeCycleObserver(Lifecycle lifecycle, Activity activity){
20 | mActivity=activity;
21 | mLifecycle=lifecycle;
22 | }
23 | public BaseLifeCycleObserver(Lifecycle lifecycle, Fragment fragment){
24 | mFragment=fragment;
25 | mLifecycle=lifecycle;
26 | }
27 |
28 | // 使用注解 @OnLifecycleEvent 来表明该方法需要监听指定的生命周期事件
29 | @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
30 | public void connectListener() {
31 | Log.d(TAG, "connectListener: -------- onResume" );
32 | }
33 |
34 | @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
35 | public void disconnectListener() {
36 | Log.d(TAG, "disconnectListener: ------- onPause");
37 | }
38 |
39 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
40 | public void destroyListener() {
41 | mLifecycle.removeObserver(this);
42 | if(mActivity!=null){
43 | SuperHttp.cancelSome(mActivity.getClass().getName());
44 | }
45 | if(mFragment!=null){
46 | SuperHttp.cancelSome(mFragment.getClass().getName());
47 | }
48 | Log.d(TAG, "destroyListener: ------- onDestroy");
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qpg/superhttpdemo/MyObserver.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttpdemo;
2 |
3 | import android.app.Activity;
4 | import android.util.Log;
5 | import androidx.fragment.app.Fragment;
6 | import androidx.lifecycle.Lifecycle;
7 | import androidx.lifecycle.LifecycleObserver;
8 | import androidx.lifecycle.OnLifecycleEvent;
9 | import com.qpg.superhttp.SuperHttp;
10 |
11 | public class MyObserver implements LifecycleObserver {
12 |
13 | private Activity mActivity;
14 | private Fragment mFragment;
15 | private Lifecycle mLifecycle;
16 | private static final String TAG = "MyObserver";
17 | public MyObserver(Lifecycle lifecycle,Activity activity){
18 | mActivity=activity;
19 | mLifecycle=lifecycle;
20 | mActivity.getClass().getName();
21 | }
22 | public MyObserver(Lifecycle lifecycle,Fragment fragment){
23 | mFragment=fragment;
24 | mLifecycle=lifecycle;
25 | mActivity.getClass().getName();
26 | }
27 |
28 | // 使用注解 @OnLifecycleEvent 来表明该方法需要监听指定的生命周期事件
29 | @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
30 | public void connectListener() {
31 | // ...
32 | Log.d(TAG, "connectListener: -------- onResume" );
33 | }
34 |
35 | @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
36 | public void disconnectListener() {
37 | // ...
38 | Log.d(TAG, "disconnectListener: ------- onPause");
39 | }
40 |
41 | @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
42 | public void destroyListener() {
43 | mLifecycle.removeObserver(this);
44 | if(mActivity!=null){
45 | SuperHttp.cancelSome(mActivity.getClass().getName());
46 | }
47 | if(mFragment!=null){
48 | SuperHttp.cancelSome(mFragment.getClass().getName());
49 | }
50 | // ...
51 | Log.d(TAG, "destroyListener: ------- onPause");
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/convert/GsonResponseBodyConverter.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.convert;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import com.google.gson.Gson;
6 | import com.google.gson.TypeAdapter;
7 | import com.google.gson.stream.JsonReader;
8 | import com.qpg.superhttp.netexpand.common.ResponseHelper;
9 | import com.qpg.superhttp.netexpand.mode.ApiResult;
10 |
11 | import java.io.IOException;
12 | import java.net.UnknownServiceException;
13 |
14 | import okhttp3.ResponseBody;
15 | import retrofit2.Converter;
16 |
17 | /**
18 | * @Description: ResponseBody to T
19 | */
20 | final class GsonResponseBodyConverter implements Converter {
21 | private final Gson gson;
22 | private final TypeAdapter adapter;
23 |
24 | GsonResponseBodyConverter(Gson gson, TypeAdapter adapter) {
25 | this.gson = gson;
26 | this.adapter = adapter;
27 | }
28 |
29 | @Override
30 | public T convert(@NonNull ResponseBody value) throws IOException {
31 | if (adapter != null && gson != null) {
32 | JsonReader jsonReader = gson.newJsonReader(value.charStream());
33 | try {
34 | T data = adapter.read(jsonReader);
35 | if (data == null) throw new UnknownServiceException("server back data is null");
36 | if (data instanceof ApiResult) {
37 | ApiResult apiResult = (ApiResult) data;
38 | if (!ResponseHelper.isSuccess(apiResult)) {
39 | throw new UnknownServiceException(apiResult.getMsg() == null ? "unknow error" : apiResult.getMsg());
40 | }
41 | }
42 | return data;
43 | } finally {
44 | value.close();
45 | }
46 | } else {
47 | return null;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/core/ApiTransformer.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.core;
2 |
3 | import com.qpg.superhttp.config.HttpGlobalConfig;
4 | import com.qpg.superhttp.transformer.ApiRetryFunc;
5 |
6 | import io.reactivex.Observable;
7 | import io.reactivex.ObservableSource;
8 | import io.reactivex.ObservableTransformer;
9 | import io.reactivex.android.schedulers.AndroidSchedulers;
10 | import io.reactivex.schedulers.Schedulers;
11 |
12 | /**
13 | * @Description: 转换器
14 | */
15 | public class ApiTransformer {
16 |
17 | public static ObservableTransformer norTransformer() {
18 | return new ObservableTransformer() {
19 | @Override
20 | public ObservableSource apply(Observable apiResultObservable) {
21 | return apiResultObservable
22 | .subscribeOn(Schedulers.io())
23 | .unsubscribeOn(Schedulers.io())
24 | .observeOn(AndroidSchedulers.mainThread())
25 | .retryWhen(new ApiRetryFunc(HttpGlobalConfig.getInstance().getRetryCount(),
26 | HttpGlobalConfig.getInstance().getRetryDelayMillis()));
27 | }
28 | };
29 | }
30 |
31 | public static ObservableTransformer norTransformer(final int retryCount, final int retryDelayMillis) {
32 | return new ObservableTransformer() {
33 | @Override
34 | public ObservableSource apply(Observable apiResultObservable) {
35 | return apiResultObservable
36 | .subscribeOn(Schedulers.io())
37 | .unsubscribeOn(Schedulers.io())
38 | .observeOn(AndroidSchedulers.mainThread())
39 | .retryWhen(new ApiRetryFunc(retryCount, retryDelayMillis));
40 | }
41 | };
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/convert/GsonConverterFactory.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.convert;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.TypeAdapter;
5 | import com.google.gson.reflect.TypeToken;
6 |
7 | import java.lang.annotation.Annotation;
8 | import java.lang.reflect.Type;
9 |
10 | import okhttp3.RequestBody;
11 | import okhttp3.ResponseBody;
12 | import retrofit2.Converter;
13 | import retrofit2.Retrofit;
14 |
15 | /**
16 | * @Description: GSON转换工厂
17 | */
18 | public class GsonConverterFactory extends Converter.Factory {
19 | private final Gson gson;
20 |
21 | private GsonConverterFactory(Gson gson) {
22 | if (gson == null) throw new NullPointerException("gson == null");
23 | this.gson = gson;
24 | }
25 |
26 | public static GsonConverterFactory create() {
27 | return create(new Gson());
28 | }
29 |
30 | public static GsonConverterFactory create(Gson gson) {
31 | return new GsonConverterFactory(gson);
32 | }
33 |
34 | @Override
35 | public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
36 | if (type != null && type.equals(String.class)) {
37 | return new JsonResponseBodyConverter<>();
38 | }
39 | TypeAdapter> adapter = null;
40 | if (type != null) {
41 | adapter = gson.getAdapter(TypeToken.get(type));
42 | }
43 | return new GsonResponseBodyConverter<>(gson, adapter);
44 | }
45 |
46 | @Override
47 | public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations,
48 | Retrofit retrofit) {
49 | TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
50 | return new GsonRequestBodyConverter<>(gson, adapter);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/strategy/CacheStrategy.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.strategy;
2 |
3 |
4 | import com.qpg.superhttp.utils.GsonUtil;
5 | import com.qpg.superhttp.core.ApiCache;
6 | import com.qpg.superhttp.mode.CacheResult;
7 |
8 | import java.lang.reflect.Type;
9 |
10 | import io.reactivex.Observable;
11 | import io.reactivex.functions.Consumer;
12 | import io.reactivex.functions.Function;
13 | import io.reactivex.functions.Predicate;
14 | import io.reactivex.schedulers.Schedulers;
15 |
16 | /**
17 | * @Description: 缓存策略
18 | */
19 | abstract class CacheStrategy implements ICacheStrategy {
20 | Observable> loadCache(final ApiCache apiCache, final String key, final Type type) {
21 | return apiCache.get(key).filter(new Predicate() {
22 | @Override
23 | public boolean test(String s) throws Exception {
24 | return s != null;
25 | }
26 | }).map(new Function>() {
27 | @Override
28 | public CacheResult apply(String s) throws Exception {
29 | T t = GsonUtil.gson().fromJson(s, type);
30 |
31 | return new CacheResult<>(true, t);
32 | }
33 | });
34 | }
35 |
36 | Observable> loadRemote(final ApiCache apiCache, final String key, Observable source) {
37 | return source.map(new Function>() {
38 | @Override
39 | public CacheResult apply(T t) throws Exception {
40 |
41 | apiCache.put(key, t).subscribeOn(Schedulers.io()).subscribe(new Consumer() {
42 | @Override
43 | public void accept(Boolean status) throws Exception {
44 |
45 | }
46 | });
47 | return new CacheResult<>(false, t);
48 | }
49 | });
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/utils/CommonUtil.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.utils;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 | import android.net.ConnectivityManager;
7 | import android.net.NetworkInfo;
8 |
9 | public class CommonUtil {
10 |
11 | /**
12 | * @return 当前程序的版本名称
13 | */
14 | public static String getVersionName(Context context) {
15 | String version;
16 | try {
17 | PackageManager pm = context.getPackageManager();
18 | PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
19 | version = packageInfo.versionName;
20 | } catch (Exception e) {
21 | e.printStackTrace();
22 |
23 | version = "";
24 | }
25 | return version;
26 | }
27 | /**
28 | * 方法: getVersionCode
29 | * 描述: 获取客户端版本号
30 | *
31 | * @return int 版本号
32 | */
33 | public static int getVersionCode(Context context) {
34 | int versionCode;
35 | try {
36 | PackageManager pm = context.getPackageManager();
37 | PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
38 | versionCode = packageInfo.versionCode;
39 | } catch (Exception e) {
40 | e.printStackTrace();
41 |
42 | versionCode = 999;
43 | }
44 | return versionCode;
45 | }
46 |
47 | /**
48 | * 判断网络连接是否有效(此时可传输数据)。
49 | *
50 | * @return boolean 不管wifi,还是mobile net,只有当前在连接状态(可有效传输数据)才返回true,反之false。
51 | */
52 | public static boolean isConnected(Context context) {
53 | NetworkInfo net = getConnectivityManager(context).getActiveNetworkInfo();
54 | return net != null && net.isConnected();
55 | }
56 |
57 | /**
58 | * 获取ConnectivityManager
59 | */
60 | public static ConnectivityManager getConnectivityManager(Context context) {
61 | return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/callback/LoadingViewCallBack.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.callback;
2 |
3 | import android.widget.Toast;
4 | import com.qpg.superhttp.SuperHttp;
5 | import com.qpg.superhttp.interf.ILoader;
6 | import com.qpg.superhttp.subscriber.IProgressDialog;
7 | import com.qpg.superhttp.subscriber.ProgressCancelListener;
8 | import com.qpg.superhttp.utils.CommonUtil;
9 | import io.reactivex.disposables.Disposable;
10 |
11 | /**
12 | * 描述:可以自定义带有加载进度框的回调
13 | * 1.可以自定义带有加载进度框的回调,是否需要显示,是否可以取消
14 | * 2.取消对话框会自动取消掉网络请求
15 | */
16 | public abstract class LoadingViewCallBack extends BaseCallback implements ProgressCancelListener {
17 | private ILoader iLoader;
18 | private String onFailMsg;
19 |
20 | public LoadingViewCallBack(ILoader iLoader) {
21 | this.iLoader = iLoader;
22 |
23 | }
24 | public LoadingViewCallBack(ILoader iLoader, String onFailMsg) {
25 | this.iLoader = iLoader;
26 | this.onFailMsg = onFailMsg;
27 | }
28 |
29 | @Override
30 | public void onStart() {
31 | if(!CommonUtil.isConnected(SuperHttp.getContext())){
32 | Toast.makeText(SuperHttp.getContext(),"网络连接错误",Toast.LENGTH_SHORT).show();
33 | onFail(0,"");
34 | }else {
35 | iLoader.showLoader();
36 | }
37 |
38 | }
39 |
40 | @Override
41 | public void onFail(int errCode, String errMsg) {
42 | if(!CommonUtil.isConnected(SuperHttp.getContext())){
43 | return;
44 | }
45 | if(onFailMsg!=null){
46 | Toast.makeText(SuperHttp.getContext(),onFailMsg,Toast.LENGTH_SHORT).show();
47 | }
48 |
49 | iLoader.hideLoader();
50 | }
51 |
52 | @Override
53 | public void onCompleted() {
54 | iLoader.hideLoader();
55 | }
56 |
57 |
58 | @Override
59 | public void onCancelProgress() {
60 | if (disposed != null && !disposed.isDisposed()) {
61 | disposed.dispose();
62 | }
63 | }
64 |
65 | private Disposable disposed;
66 |
67 | public void subscription(Disposable disposed) {
68 | this.disposed = disposed;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/request/GetRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.request;
2 |
3 | import com.qpg.superhttp.SuperHttp;
4 | import com.qpg.superhttp.callback.BaseCallback;
5 | import com.qpg.superhttp.core.ApiManager;
6 | import com.qpg.superhttp.lifecycle.BaseLifeCycleObserver;
7 | import com.qpg.superhttp.mode.CacheResult;
8 | import com.qpg.superhttp.subscriber.ApiCallbackSubscriber;
9 |
10 | import java.lang.reflect.Type;
11 |
12 | import io.reactivex.Observable;
13 | import io.reactivex.observers.DisposableObserver;
14 |
15 | /**
16 | * @Description: Get请求
17 | */
18 | public class GetRequest extends BaseHttpRequest {
19 | public GetRequest(String suffixUrl) {
20 | super(suffixUrl);
21 | }
22 |
23 | @Override
24 | protected Observable execute(Type type) {
25 | return apiService.get(suffixUrl, params).compose(this.norTransformer(type));
26 | }
27 |
28 | @Override
29 | protected Observable> cacheExecute(Type type) {
30 | return this.execute(type).compose(SuperHttp.getApiCache().transformer(cacheMode, type));
31 | }
32 |
33 | @Override
34 | protected void execute(BaseCallback callback) {
35 | DisposableObserver disposableObserver = new ApiCallbackSubscriber(callback);
36 | if (super.tag != null) {
37 | ApiManager.get().add(super.tag, disposableObserver);
38 |
39 | }
40 |
41 | if (super.mActivity != null) {
42 | if (!ApiManager.get().isContainTag(mActivity.getClass().getName())) {
43 | mActivity.getLifecycle().addObserver(new BaseLifeCycleObserver(mActivity.getLifecycle(), mActivity));
44 | }
45 | ApiManager.get().add(mActivity.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
46 | }
47 |
48 | if (super.mFragment != null) {
49 | if (!ApiManager.get().isContainTag(mFragment.getClass().getName())) {
50 | mFragment.getLifecycle().addObserver(new BaseLifeCycleObserver(mFragment.getLifecycle(), mFragment));
51 | }
52 | ApiManager.get().add(mFragment.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
53 | }
54 |
55 | if (isLocalCache) {
56 | this.cacheExecute(getSubType(callback)).subscribe(disposableObserver);
57 | } else {
58 | this.execute(getType(callback)).subscribe(disposableObserver);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/request/HeadRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.request;
2 |
3 |
4 | import com.qpg.superhttp.SuperHttp;
5 | import com.qpg.superhttp.callback.BaseCallback;
6 | import com.qpg.superhttp.core.ApiManager;
7 | import com.qpg.superhttp.lifecycle.BaseLifeCycleObserver;
8 | import com.qpg.superhttp.mode.CacheResult;
9 | import com.qpg.superhttp.subscriber.ApiCallbackSubscriber;
10 |
11 | import java.lang.reflect.Type;
12 |
13 | import io.reactivex.Observable;
14 | import io.reactivex.observers.DisposableObserver;
15 |
16 | /**
17 | * @Description: Head请求
18 | */
19 | public class HeadRequest extends BaseHttpRequest {
20 | public HeadRequest(String suffixUrl) {
21 | super(suffixUrl);
22 | }
23 |
24 | @Override
25 | protected Observable execute(Type type) {
26 | return apiService.head(suffixUrl, params).compose(this.norTransformer(type));
27 | }
28 |
29 | @Override
30 | protected Observable> cacheExecute(Type type) {
31 | return this.execute(type).compose(SuperHttp.getApiCache().transformer(cacheMode, type));
32 | }
33 |
34 | @Override
35 | protected void execute(BaseCallback callback) {
36 | DisposableObserver disposableObserver = new ApiCallbackSubscriber(callback);
37 | if (super.tag != null) {
38 | ApiManager.get().add(super.tag, disposableObserver);
39 | }
40 |
41 | if (super.mActivity != null) {
42 | if(!ApiManager.get().isContainTag(super.mActivity.getClass().getName())){
43 | super.mActivity.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mActivity.getLifecycle(),super.mActivity));
44 | }
45 | ApiManager.get().add(super.mActivity.getClass().getName()+"_"+disposableObserver.hashCode(), disposableObserver);
46 | }
47 |
48 | if (super.mFragment != null) {
49 | if(!ApiManager.get().isContainTag(super.mFragment.getClass().getName())){
50 | super.mFragment.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mFragment.getLifecycle(),mFragment));
51 | }
52 | ApiManager.get().add(super.mFragment.getClass().getName()+"_"+disposableObserver.hashCode(), disposableObserver);
53 | }
54 |
55 | if (isLocalCache) {
56 | this.cacheExecute(getSubType(callback)).subscribe(disposableObserver);
57 | } else {
58 | this.execute(getType(callback)).subscribe(disposableObserver);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/request/PutRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.request;
2 |
3 | import com.qpg.superhttp.SuperHttp;
4 | import com.qpg.superhttp.callback.BaseCallback;
5 | import com.qpg.superhttp.core.ApiManager;
6 | import com.qpg.superhttp.lifecycle.BaseLifeCycleObserver;
7 | import com.qpg.superhttp.mode.CacheResult;
8 | import com.qpg.superhttp.subscriber.ApiCallbackSubscriber;
9 |
10 | import java.lang.reflect.Type;
11 |
12 | import io.reactivex.Observable;
13 | import io.reactivex.observers.DisposableObserver;
14 |
15 | /**
16 | * @Description: Put请求
17 | */
18 | public class PutRequest extends BaseHttpRequest {
19 | public PutRequest(String suffixUrl) {
20 | super(suffixUrl);
21 | }
22 |
23 | @Override
24 | protected Observable execute(Type type) {
25 | return apiService.put(suffixUrl, params).compose(this.norTransformer(type));
26 | }
27 |
28 | @Override
29 | protected Observable> cacheExecute(Type type) {
30 | return this.execute(type).compose(SuperHttp.getApiCache().transformer(cacheMode, type));
31 | }
32 |
33 | @Override
34 | protected void execute(BaseCallback callback) {
35 | DisposableObserver disposableObserver = new ApiCallbackSubscriber(callback);
36 | if (super.tag != null) {
37 | ApiManager.get().add(super.tag, disposableObserver);
38 | }
39 |
40 | if (super.mActivity != null) {
41 | if (!ApiManager.get().isContainTag(super.mActivity.getClass().getName())) {
42 | super.mActivity.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mActivity.getLifecycle(), super.mActivity));
43 | }
44 | ApiManager.get().add(super.mActivity.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
45 | }
46 |
47 | if (super.mFragment != null) {
48 | if (!ApiManager.get().isContainTag(super.mFragment.getClass().getName())) {
49 | super.mFragment.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mFragment.getLifecycle(), mFragment));
50 | }
51 | ApiManager.get().add(super.mFragment.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
52 | }
53 |
54 | if (isLocalCache) {
55 | this.cacheExecute(getSubType(callback)).subscribe(disposableObserver);
56 | } else {
57 | this.execute(getType(callback)).subscribe(disposableObserver);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/request/SynRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.request;
2 |
3 | import com.qpg.superhttp.SuperHttp;
4 | import com.qpg.superhttp.callback.BaseCallback;
5 | import com.qpg.superhttp.core.ApiManager;
6 | import com.qpg.superhttp.lifecycle.BaseLifeCycleObserver;
7 | import com.qpg.superhttp.mode.CacheResult;
8 | import com.qpg.superhttp.subscriber.ApiCallbackSubscriber;
9 |
10 | import java.lang.reflect.Type;
11 |
12 | import io.reactivex.Observable;
13 | import io.reactivex.observers.DisposableObserver;
14 |
15 | /**
16 | * @Description: 同步请求
17 | */
18 | public class SynRequest extends BaseHttpRequest {
19 | public SynRequest(String suffixUrl) {
20 | super(suffixUrl);
21 | }
22 |
23 | @Override
24 | protected Observable execute(Type type) {
25 | return apiService.get(suffixUrl, params).compose(this.norTransformer(type));
26 | }
27 |
28 | @Override
29 | protected Observable> cacheExecute(Type type) {
30 | return this.execute(type).compose(SuperHttp.getApiCache().transformer(cacheMode, type));
31 | }
32 |
33 | @Override
34 | protected void execute(BaseCallback callback) {
35 | DisposableObserver disposableObserver = new ApiCallbackSubscriber(callback);
36 | if (super.tag != null) {
37 | ApiManager.get().add(super.tag, disposableObserver);
38 | }
39 |
40 | if (super.mActivity != null) {
41 | if (!ApiManager.get().isContainTag(super.mActivity.getClass().getName())) {
42 | super.mActivity.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mActivity.getLifecycle(), super.mActivity));
43 | }
44 | ApiManager.get().add(super.mActivity.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
45 | }
46 |
47 | if (super.mFragment != null) {
48 | if (!ApiManager.get().isContainTag(super.mFragment.getClass().getName())) {
49 | super.mFragment.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mFragment.getLifecycle(), mFragment));
50 | }
51 | ApiManager.get().add(super.mFragment.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
52 | }
53 |
54 | if (isLocalCache) {
55 | this.cacheExecute(getSubType(callback)).subscribe(disposableObserver);
56 | } else {
57 | this.execute(getType(callback)).subscribe(disposableObserver);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/func/ApiResultFunc.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.func;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.qpg.superhttp.utils.GsonUtil;
6 | import com.qpg.superhttp.netexpand.mode.ApiResult;
7 | import com.qpg.superhttp.netexpand.mode.ResponseCode;
8 | import org.json.JSONException;
9 | import org.json.JSONObject;
10 |
11 | import java.io.IOException;
12 | import java.lang.reflect.Type;
13 |
14 | import io.reactivex.functions.Function;
15 | import okhttp3.ResponseBody;
16 |
17 | /**
18 | * @Description: ResponseBody转ApiResult
19 | */
20 | public class ApiResultFunc implements Function> {
21 | protected Type type;
22 |
23 | public ApiResultFunc(Type type) {
24 | this.type = type;
25 | }
26 |
27 | @Override
28 | public ApiResult apply(ResponseBody responseBody) throws Exception {
29 | ApiResult apiResult = new ApiResult<>();
30 | apiResult.setCode(-1);
31 | try {
32 | String json = responseBody.string();
33 | ApiResult result = parseApiResult(json, apiResult);
34 | if (result != null) {
35 | apiResult = result;
36 | if (apiResult.getData() != null) {
37 | T data = GsonUtil.gson().fromJson(apiResult.getData().toString(), type);
38 | apiResult.setData(data);
39 | apiResult.setCode(ResponseCode.HTTP_SUCCESS);
40 | } else {
41 | apiResult.setMsg("ApiResult's data is null");
42 | }
43 | } else {
44 | apiResult.setMsg("json is null");
45 | }
46 | } catch (JSONException | IOException e) {
47 | e.printStackTrace();
48 | apiResult.setMsg(e.getMessage());
49 | } finally {
50 | responseBody.close();
51 | }
52 | return apiResult;
53 | }
54 |
55 | private ApiResult parseApiResult(String json, ApiResult apiResult) throws JSONException {
56 | if (TextUtils.isEmpty(json)) return null;
57 | JSONObject jsonObject = new JSONObject(json);
58 | if (jsonObject.has("code")) {
59 | apiResult.setCode(jsonObject.getInt("code"));
60 | }
61 | if (jsonObject.has("data")) {
62 | apiResult.setData(jsonObject.getString("data"));
63 | }
64 | if (jsonObject.has("msg")) {
65 | apiResult.setMsg(jsonObject.getString("msg"));
66 | }
67 | return apiResult;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/request/OptionsRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.request;
2 |
3 | import com.qpg.superhttp.SuperHttp;
4 | import com.qpg.superhttp.callback.BaseCallback;
5 | import com.qpg.superhttp.core.ApiManager;
6 | import com.qpg.superhttp.lifecycle.BaseLifeCycleObserver;
7 | import com.qpg.superhttp.mode.CacheResult;
8 | import com.qpg.superhttp.subscriber.ApiCallbackSubscriber;
9 |
10 | import java.lang.reflect.Type;
11 |
12 | import io.reactivex.Observable;
13 | import io.reactivex.observers.DisposableObserver;
14 |
15 | /**
16 | * @Description: Options请求
17 | */
18 | public class OptionsRequest extends BaseHttpRequest {
19 | public OptionsRequest(String suffixUrl) {
20 | super(suffixUrl);
21 | }
22 |
23 | @Override
24 | protected Observable execute(Type type) {
25 | return apiService.options(suffixUrl, params).compose(this.norTransformer(type));
26 | }
27 |
28 | @Override
29 | protected Observable> cacheExecute(Type type) {
30 | return this.execute(type).compose(SuperHttp.getApiCache().transformer(cacheMode, type));
31 | }
32 |
33 | @Override
34 | protected void execute(BaseCallback callback) {
35 | DisposableObserver disposableObserver = new ApiCallbackSubscriber(callback);
36 | if (super.tag != null) {
37 | ApiManager.get().add(super.tag, disposableObserver);
38 | }
39 |
40 | if (super.mActivity != null) {
41 | if (!ApiManager.get().isContainTag(super.mActivity.getClass().getName())) {
42 | super.mActivity.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mActivity.getLifecycle(), super.mActivity));
43 | }
44 | ApiManager.get().add(super.mActivity.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
45 | }
46 |
47 | if (super.mFragment != null) {
48 | if (!ApiManager.get().isContainTag(super.mFragment.getClass().getName())) {
49 | super.mFragment.getLifecycle().addObserver(new BaseLifeCycleObserver(super.mFragment.getLifecycle(), mFragment));
50 | }
51 | ApiManager.get().add(super.mFragment.getClass().getName() + "_" + disposableObserver.hashCode(), disposableObserver);
52 | }
53 |
54 | if (isLocalCache) {
55 | this.cacheExecute(getSubType(callback)).subscribe(disposableObserver);
56 | } else {
57 | this.execute(getType(callback)).subscribe(disposableObserver);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/netexpand/request/ApiGetRequest.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.netexpand.request;
2 |
3 | import com.qpg.superhttp.SuperHttp;
4 | import com.qpg.superhttp.callback.BaseCallback;
5 | import com.qpg.superhttp.core.ApiManager;
6 | import com.qpg.superhttp.lifecycle.BaseLifeCycleObserver;
7 | import com.qpg.superhttp.mode.CacheResult;
8 | import com.qpg.superhttp.netexpand.func.ApiResultFunc;
9 | import com.qpg.superhttp.subscriber.ApiCallbackSubscriber;
10 |
11 | import java.lang.reflect.Type;
12 |
13 | import io.reactivex.Observable;
14 | import io.reactivex.observers.DisposableObserver;
15 |
16 | /**
17 | * @Description: 返回APIResult的GET请求类
18 | * @date: 17/5/13 14:31.
19 | */
20 | public class ApiGetRequest extends ApiBaseRequest {
21 | public ApiGetRequest(String suffixUrl) {
22 | super(suffixUrl);
23 | }
24 |
25 | @Override
26 | protected Observable execute(Type type) {
27 | return apiService.get(suffixUrl, params).map(new ApiResultFunc(type)).compose(this.apiTransformer());
28 | }
29 |
30 | @Override
31 | protected Observable> cacheExecute(Type type) {
32 | return this.execute(type).compose(SuperHttp.getApiCache().transformer(cacheMode, type));
33 | }
34 |
35 | @Override
36 | protected void execute(BaseCallback callback) {
37 | DisposableObserver disposableObserver = new ApiCallbackSubscriber(callback);
38 | if (super.tag != null) {
39 | ApiManager.get().add(super.tag, disposableObserver);
40 | }
41 | if (super.mActivity != null) {
42 | String tag=String.valueOf(mActivity.getClass().getName()+"_"+System.nanoTime());
43 | if(!ApiManager.get().isContainTag(tag)){
44 | mActivity.getLifecycle().addObserver(new BaseLifeCycleObserver(mActivity.getLifecycle(),mActivity));
45 | }
46 | ApiManager.get().add(tag, disposableObserver);
47 | }
48 | if (super.mFragment != null) {
49 | String tag=String.valueOf(mFragment.getClass().getName()+"_"+System.nanoTime());
50 | if(!ApiManager.get().isContainTag(tag)){
51 | mFragment.getLifecycle().addObserver(new BaseLifeCycleObserver(mFragment.getLifecycle(),mFragment));
52 | }
53 | ApiManager.get().add(tag, disposableObserver);
54 | }
55 | if (isLocalCache) {
56 | this.cacheExecute(getSubType(callback)).subscribe(disposableObserver);
57 | } else {
58 | this.execute(getType(callback)).subscribe(disposableObserver);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/bintray.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.github.dcendents.android-maven'
2 | apply plugin: 'com.jfrog.bintray'
3 | // ./gradlew build bintrayUpload -PbintrayUser=q-p-g -PbintrayKey=f66f6ed4c5aec926f236eae5b0325731024997c2 -PdryRun=false
4 | //gradlew bintrayUpload -PbintrayUser=q-p-p -PbintrayKey=f66f6ed4c5aec926f236eae5b0325731024997c2 -PdryRun=false
5 | version = android.defaultConfig.versionName
6 | group = GROUP
7 |
8 | install {
9 | repositories.mavenInstaller {
10 | pom {
11 | project {
12 | packaging PACKAGING
13 | name DESCRIBE
14 | url SITE_URL
15 | licenses {
16 | license {
17 | name LICENSE_NAME
18 | url LICENSE_URL
19 | }
20 | }
21 | developers {
22 | developer {
23 | id DEVELOPER_ID
24 | name DEVELOPER_NAME
25 | email DEVELOPER_EMAIL
26 | }
27 | }
28 | scm {
29 | connection GIT_URL
30 | developerConnection GIT_URL
31 | url SITE_URL
32 | }
33 | }
34 | }
35 | }
36 | }
37 |
38 | task sourcesJar(type: Jar) {
39 | from android.sourceSets.main.java.srcDirs
40 | classifier = 'sources'
41 | }
42 |
43 | task javadoc(type: Javadoc) {
44 | options.encoding = "UTF-8"
45 | source = android.sourceSets.main.java.srcDirs
46 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
47 | }
48 |
49 | task javadocJar(type: Jar, dependsOn: javadoc) {
50 | classifier = 'javadoc'
51 | from javadoc.destinationDir
52 | }
53 |
54 | tasks.withType(JavaCompile) {
55 | options.encoding = "UTF-8"
56 | }
57 |
58 | tasks.withType(Javadoc) {
59 | options.addStringOption('Xdoclint:none', '-quiet')
60 | options.addStringOption('encoding', 'UTF-8')
61 | options.addStringOption('charSet', 'UTF-8')
62 | }
63 |
64 | artifacts {
65 | archives javadocJar
66 | archives sourcesJar
67 | }
68 |
69 | Properties properties = new Properties()
70 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
71 | bintray {
72 | user = properties.getProperty("bintray.user")
73 | key = properties.getProperty("bintray.apikey")
74 | configurations = ['archives']
75 | pkg {
76 | repo = PROJECT_REPO
77 | name = PROJECT_NAME
78 | websiteUrl = SITE_URL
79 | vcsUrl = GIT_URL
80 | licenses = ["Apache-2.0"]
81 | publish = PROJECT_PUBLISH
82 | }
83 | }
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/superhttp/src/main/java/com/qpg/superhttp/core/ApiManager.java:
--------------------------------------------------------------------------------
1 | package com.qpg.superhttp.core;
2 |
3 | import java.util.Set;
4 | import java.util.concurrent.ConcurrentHashMap;
5 | import io.reactivex.disposables.Disposable;
6 |
7 | /**
8 | * @Description: 请求管理,方便中途取消请求
9 | */
10 | public class ApiManager {
11 | private static ApiManager sInstance;
12 |
13 | private ConcurrentHashMap