9 | * 10 | * @author: FreddyChen 11 | * @date : 2022/01/14 12:14 12 | * @email : freddychencsc@gmail.com 13 | */ 14 | public class RequestManagerFactory { 15 | 16 | public static IRequest getRequestManager() { 17 | return RetrofitRequestManager.getInstance(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /shine-java/src/main/java/com/freddy/shine/java/ShineKit.java: -------------------------------------------------------------------------------- 1 | package com.freddy.shine.java; 2 | 3 | import com.freddy.shine.java.config.ShineOptions; 4 | import com.freddy.shine.java.interf.IRequest; 5 | 6 | /** 7 | * Shine核心类 8 | *
9 | * 10 | * @author: FreddyChen 11 | * @date : 2022/01/14 10:56 12 | * @email : freddychencsc@gmail.com 13 | */ 14 | public class ShineKit { 15 | 16 | private ShineKit() { 17 | options = new ShineOptions.Builder().build(); 18 | } 19 | 20 | public static ShineKit getInstance() { 21 | return SingletonHolder.INSTANCE; 22 | } 23 | 24 | private static class SingletonHolder { 25 | private static final ShineKit INSTANCE = new ShineKit(); 26 | } 27 | 28 | private ShineOptions options; 29 | 30 | public void init(ShineOptions options) { 31 | this.options = options; 32 | } 33 | 34 | public ShineOptions getShineOptions() { 35 | return this.options; 36 | } 37 | 38 | public IRequest getRequestManager() { 39 | return RequestManagerFactory.getRequestManager(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /shine-java/src/main/java/com/freddy/shine/java/cipher/AbstractCipher.java: -------------------------------------------------------------------------------- 1 | package com.freddy.shine.java.cipher; 2 | 3 | /** 4 | * 抽象的加解密器 5 | *
6 | * 如果需要自定义加解密器,继承此{@link AbstractCipher},实现{@link ICipher#encrypt(String)}及{@link ICipher#decrypt(String)}方法即可
7 | *
8 | * @author: FreddyChen
9 | * @date : 2022/01/14 10:12
10 | * @email : freddychencsc@gmail.com
11 | */
12 | public abstract class AbstractCipher implements ICipher {
13 | }
14 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/cipher/DefaultCipher.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.cipher;
2 |
3 | /**
4 | * 默认的加解密器
5 | *
6 | * 示例实现
7 | * 在{@link #encrypt(String)}中实现加密逻辑
8 | * 在{@link #decrypt(String)}中实现解密逻辑
9 | * {@link #getParamName()}配置与服务端协商好的加密字段key
10 | *
11 | * @author: FreddyChen
12 | * @date : 2022/01/14 10:16
13 | * @email : freddychencsc@gmail.com
14 | */
15 | public class DefaultCipher extends AbstractCipher {
16 |
17 | @Override
18 | public String encrypt(String original) {
19 | return original;
20 | }
21 |
22 | @Override
23 | public String decrypt(String original) {
24 | return original;
25 | }
26 |
27 | @Override
28 | public String getParamName() {
29 | return "params";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/cipher/ICipher.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.cipher;
2 |
3 | /**
4 | * 加解密器抽象接口
5 | *
6 | * 7 | * @author: FreddyChen 8 | * @date : 2022/01/13 18:02 9 | * @email : freddychencsc@gmail.com 10 | * @see DefaultCipher 11 | */ 12 | public interface ICipher { 13 | 14 | /** 15 | * 加密数据 16 | * 17 | * @param original 18 | * @return 19 | */ 20 | String encrypt(String original); 21 | 22 | /** 23 | * 解密数据 24 | * 25 | * @param original 26 | * @return 27 | */ 28 | String decrypt(String original); 29 | 30 | /** 31 | * 获取加解密字段名称 32 | * 33 | * @return 34 | */ 35 | String getParamName(); 36 | } 37 | -------------------------------------------------------------------------------- /shine-java/src/main/java/com/freddy/shine/java/config/NetworkConfig.java: -------------------------------------------------------------------------------- 1 | package com.freddy.shine.java.config; 2 | 3 | /** 4 | * 网络配置 5 | *
6 | * @author: FreddyChen 7 | * @date : 2022/01/14 10:19 8 | * @email : freddychencsc@gmail.com 9 | */ 10 | public class NetworkConfig { 11 | 12 | public static final String DEFAULT_CONTENT_TYPE = "application/json; charset=utf-8"; 13 | } 14 | -------------------------------------------------------------------------------- /shine-java/src/main/java/com/freddy/shine/java/config/RequestMethod.java: -------------------------------------------------------------------------------- 1 | package com.freddy.shine.java.config; 2 | 3 | /** 4 | * 请求方式 5 | *
6 | * 支持以下请求逻辑:
7 | * {@link #GET}
8 | * {@link #POST}
9 | * {@link #PUT}
10 | * {@link #DELETE}
11 | *
12 | * @author: FreddyChen
13 | * @date : 2022/01/14 10:20
14 | * @email : freddychencsc@gmail.com
15 | */
16 | public enum RequestMethod {
17 | GET,
18 | POST,
19 | PUT,
20 | DELETE
21 | }
22 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/config/RequestOptions.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.config;
2 |
3 | import android.util.ArrayMap;
4 |
5 | /**
6 | * 请求配置
7 | *
8 | * {@link #requestMethod} 请求方式
6 | * @author: FreddyChen
7 | * @date : 2022/01/14 10:30
8 | * @email : freddychencsc@gmail.com
9 | */
10 | public class ShineConfig {
11 |
12 | public static final String DEFAULT_LOG_TAG = "Shine";
13 | public static final boolean DEFAULT_LOG_ENABLE = true;
14 | }
15 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/config/ShineOptions.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.config;
2 |
3 | import com.freddy.shine.java.parser.DefaultParser;
4 | import com.freddy.shine.java.parser.IParser;
5 |
6 | /**
7 | * Shine配置类
8 | *
9 | * {@link #logEnable} 日志开关
6 | * * {@link #type} 异常类型
22 | * {@link #NATIVE} 本地异常
23 | * {@link #NETWORK} 网络异常
24 | */
25 | public enum Type {
26 | NATIVE,
27 | NETWORK
28 | }
29 |
30 | private Type type;
31 | private String url;
32 | private Integer statusCode;
33 | private Integer errCode;
34 | private String errMsg;
35 | private String errBody;
36 |
37 | public Type getType() {
38 | return type;
39 | }
40 |
41 | public void setType(Type type) {
42 | this.type = type;
43 | }
44 |
45 | public String getUrl() {
46 | return url;
47 | }
48 |
49 | public void setUrl(String url) {
50 | this.url = url;
51 | }
52 |
53 | public Integer getStatusCode() {
54 | return statusCode;
55 | }
56 |
57 | public void setStatusCode(Integer statusCode) {
58 | this.statusCode = statusCode;
59 | }
60 |
61 | public Integer getErrCode() {
62 | return errCode;
63 | }
64 |
65 | public void setErrCode(Integer errCode) {
66 | this.errCode = errCode;
67 | }
68 |
69 | public String getErrMsg() {
70 | return errMsg;
71 | }
72 |
73 | public void setErrMsg(String errMsg) {
74 | this.errMsg = errMsg;
75 | }
76 |
77 | public String getErrBody() {
78 | return errBody;
79 | }
80 |
81 | public void setErrBody(String errBody) {
82 | this.errBody = errBody;
83 | }
84 |
85 | @Override
86 | public String toString() {
87 | return "RequestException{" +
88 | "type=" + type +
89 | ", url='" + url + '\'' +
90 | ", statusCode=" + statusCode +
91 | ", errCode=" + errCode +
92 | ", errMsg='" + errMsg + '\'' +
93 | '}';
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/interf/IRequest.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.interf;
2 |
3 | import com.freddy.shine.java.cipher.ICipher;
4 | import com.freddy.shine.java.config.RequestOptions;
5 | import com.freddy.shine.java.exception.RequestException;
6 | import com.freddy.shine.java.listener.OnResponseListener;
7 | import com.freddy.shine.java.parser.IParser;
8 |
9 | import java.lang.reflect.Type;
10 |
11 | /**
12 | * 抽象的接口请求封装,自定义RequestManager实现此接口即可
13 | *
14 | *
15 | * @author: FreddyChen
16 | * @date : 2022/01/14 11:09
17 | * @email : freddychencsc@gmail.com
18 | */
19 | public interface IRequest {
20 |
21 |
8 | * {@link #onStart()} 请求开始
6 | * @author: FreddyChen
7 | * @date : 2022/01/14 11:31
8 | * @email : freddychencsc@gmail.com
9 | */
10 | public interface OnResponseListener
8 | * 可以按需实现接口回调方法
6 | * {@link #code} 返回码
6 | * @author: FreddyChen
7 | * @date : 2022/01/15 00:53
8 | * @email : freddychencsc@gmail.com
9 | */
10 | public interface IResponseModel {
11 |
12 | boolean isSuccessful();
13 | }
14 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/parser/AbstractParser.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.parser;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import java.lang.reflect.Type;
6 |
7 | /**
8 | * 抽象的数据解析器
9 | *
10 | * 如果需要自定义解析器,继承此{@link AbstractParser},实现{@link AbstractParser#parse(String, String, Type)}方法即可
13 | * ResponseModel包含
10 | *
11 | * @author: FreddyChen
12 | * @date : 2022/01/14 10:42
13 | * @email : freddychencsc@gmail.com
14 | * @see DefaultParser
23 | *
24 | * @author: FreddyChen
25 | * @date : 2022/01/14 15:56
26 | * @email : freddychencsc@gmail.com
27 | */
28 | public class StringConverterFactory extends Converter.Factory {
29 |
30 | private static final MediaType MEDIA_TYPE = MediaType.parse(NetworkConfig.DEFAULT_CONTENT_TYPE);
31 | private static final String UTF_8 = "UTF-8";
32 | private static final int BUFFER_SIZE = 4096;
33 |
34 | public static StringConverterFactory create() {
35 | return new StringConverterFactory();
36 | }
37 |
38 | @Nullable
39 | @Override
40 | public Converter
18 | *
19 | * @author: FreddyChen
20 | * @date : 2022/01/14 15:47
21 | * @email : freddychencsc@gmail.com
22 | */
23 | public class OkHttpLoggingInterceptor extends OkHttpBaseInterceptor {
24 |
25 | @NonNull
26 | @Override
27 | public Response intercept(@NonNull Chain chain) throws IOException {
28 | long startTime = System.currentTimeMillis();
29 | Request request = chain.request();
30 | Response response = chain.proceed(request);
31 | String method = request.method();
32 | StringBuilder logBuilder = new StringBuilder();
33 | Headers headers = request.headers();
34 | String headerString = null;
35 | if (headers.size() == 0) {
36 | headerString = null;
37 | } else {
38 | StringBuilder headerBuilder = new StringBuilder();
39 | for (Iterator
27 | *
28 | * @author: FreddyChen
29 | * @date : 2022/01/14 15:47
30 | * @email : freddychencsc@gmail.com
31 | */
32 | public class OkHttpRequestEncryptInterceptor extends OkHttpBaseInterceptor {
33 |
34 | private static final String TAG = OkHttpRequestEncryptInterceptor.class.getSimpleName();
35 |
36 | @NonNull
37 | @Override
38 | public Response intercept(@NonNull Chain chain) throws IOException {
39 | Request request = chain.request();
40 | RequestMethod requestMethod = getRequestMethod(request.method());
41 | if (requestMethod == null) {
42 | return chain.proceed(request);
43 | }
44 | HttpUrl url = request.url();
45 | String urlString = url.toString();
46 | switch (requestMethod) {
47 | case GET:
48 | case DELETE: {
49 | if (!TextUtils.isEmpty(url.encodedQuery())) {
50 | try {
51 | StringBuilder apiBuilder = new StringBuilder();
52 | apiBuilder.append(url.scheme());
53 | apiBuilder.append("://");
54 | apiBuilder.append(url.host());
55 | apiBuilder.append(url.encodedPath());
56 | String api = apiBuilder.toString().trim();
57 | ICipher cipher = RetrofitManager.getInstance().getCipher(urlString.substring(0, urlString.indexOf("?")));
58 | if (cipher != null) {
59 | StringBuilder newApiBuilder = new StringBuilder();
60 | newApiBuilder.append(api);
61 | newApiBuilder.append(cipher.getParamName());
62 | newApiBuilder.append("=");
63 | newApiBuilder.append(cipher.encrypt(url.encodedQuery()));
64 | String newApi = newApiBuilder.toString().trim();
65 | request = request.newBuilder().url(newApi).build();
66 | ShineLog.i(TAG + "#intercept()\napi = " + api + "\nnewApi = " + newApi);
67 | }
68 | } catch (Exception e) {
69 | e.printStackTrace();
70 | ShineLog.e(TAG + "#intercept() encrypt failure, reason: " + e.getMessage());
71 | chain.proceed(request);
72 | }
73 | }
74 | break;
75 | }
76 |
77 | case POST:
78 | case PUT: {
79 | RequestBody requestBody = request.body();
80 | if (requestBody != null) {
81 | Charset charset = null;
82 | MediaType contentType = requestBody.contentType();
83 | if (contentType != null) {
84 | charset = contentType.charset(Charsets.UTF_8);
85 | // 如果contentType为multipart,则不进行加密
86 | if ("multipart".equalsIgnoreCase(contentType.type())) {
87 | return chain.proceed(request);
88 | }
89 | }
90 | if (charset == null) {
91 | return chain.proceed(request);
92 | }
93 | try {
94 | ICipher cipher = RetrofitManager.getInstance().getCipher(urlString);
95 | if (cipher != null) {
96 | Buffer buffer = new Buffer();
97 | requestBody.writeTo(buffer);
98 | String requestData = URLDecoder.decode(buffer.readString(charset).trim(), Charsets.UTF_8.name());
99 | String encryptData = cipher.encrypt(requestData);
100 | if (!TextUtils.isEmpty(encryptData)) {
101 | RequestBody newRequestBody = RequestBody.create(encryptData, contentType);
102 | Request.Builder newRequestBuilder = request.newBuilder();
103 | switch (requestMethod) {
104 | case POST: {
105 | newRequestBuilder.post(newRequestBody);
106 | break;
107 | }
108 | case PUT: {
109 | newRequestBuilder.put(newRequestBody);
110 | break;
111 | }
112 | }
113 | request = newRequestBuilder.build();
114 | ShineLog.i(TAG + "#intercept() \nrequestBody = " + requestBody + "\nnewRequestBody = " + newRequestBody + "\nrequestData = " + requestData + "\nencryptData = " + encryptData);
115 | }
116 | }
117 | } catch (Exception e) {
118 | e.printStackTrace();
119 | ShineLog.e(TAG + "#intercept() encrypt failure, reason: " + e.getMessage());
120 | chain.proceed(request);
121 | }
122 | }
123 | break;
124 | }
125 | }
126 | return chain.proceed(request);
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/retrofit/interceptor/OkHttpRequestHeaderInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.retrofit.interceptor;
2 |
3 | import android.util.ArrayMap;
4 |
5 | import androidx.annotation.NonNull;
6 |
7 | import com.freddy.shine.java.retrofit.manager.RetrofitManager;
8 |
9 | import java.io.IOException;
10 | import java.util.Map;
11 |
12 | import okhttp3.Headers;
13 | import okhttp3.Request;
14 | import okhttp3.Response;
15 |
16 | /**
17 | * OkHttp请求头拦截器
18 | *
19 | *
20 | * @author: FreddyChen
21 | * @date : 2022/01/14 15:46
22 | * @email : freddychencsc@gmail.com
23 | */
24 | public class OkHttpRequestHeaderInterceptor extends OkHttpBaseInterceptor {
25 |
26 | @NonNull
27 | @Override
28 | public Response intercept(@NonNull Chain chain) throws IOException {
29 | Request request = chain.request();
30 | String url = request.url().toString();
31 | Headers headers = getHeaders(url);
32 | if (headers == null) {
33 | return chain.proceed(request);
34 | }
35 | return chain.proceed(request.newBuilder().headers(headers).build());
36 | }
37 |
38 | private Headers getHeaders(String url) {
39 | Headers.Builder headersBuilder = new Headers.Builder();
40 | ArrayMap
27 | *
28 | * @author: FreddyChen
29 | * @date : 2022/01/14 15:48
30 | * @email : freddychencsc@gmail.com
31 | */
32 | public class OkHttpResponseDecryptInterceptor extends OkHttpBaseInterceptor {
33 |
34 | private static final String TAG = OkHttpResponseDecryptInterceptor.class.getSimpleName();
35 |
36 | @NonNull
37 | @Override
38 | public Response intercept(@NonNull Chain chain) throws IOException {
39 | Request request = chain.request();
40 | Response response = chain.proceed(request);
41 | HttpUrl requestUrl = request.url();
42 | String urlString = requestUrl.toString();
43 | String url;
44 |
45 | RequestMethod requestMethod = getRequestMethod(request.method());
46 | if (requestMethod == null) return response;
47 | switch (requestMethod) {
48 | case GET:
49 | case DELETE: {
50 | if (TextUtils.isEmpty(requestUrl.encodedQuery())) {
51 | url = urlString;
52 | } else {
53 | url = urlString.substring(0, urlString.indexOf("?"));
54 | }
55 | break;
56 | }
57 |
58 | case POST:
59 | case PUT:
60 | default: {
61 | url = urlString;
62 | break;
63 | }
64 | }
65 |
66 | if (response.isSuccessful()) {
67 | ResponseBody responseBody = response.body();
68 | if (responseBody != null) {
69 | try {
70 | ICipher cipher = RetrofitManager.getInstance().getCipher(url);
71 | if (cipher == null) {
72 | return response;
73 | }
74 | BufferedSource source = responseBody.source();
75 | source.request(Long.MAX_VALUE);
76 | Buffer buffer = source.getBuffer();
77 | Charset charset = Charsets.UTF_8;
78 | MediaType contentType = responseBody.contentType();
79 | if (contentType == null) {
80 | return response;
81 | }
82 | charset = contentType.charset(charset);
83 | if (charset == null) {
84 | return response;
85 | }
86 | String responseData = buffer.clone().readString(charset).trim();
87 | String decryptData = cipher.decrypt(responseData);
88 | if (TextUtils.isEmpty(decryptData)) {
89 | return response;
90 | }
91 | ResponseBody newResponseBody = ResponseBody.create(decryptData, contentType);
92 | response = response.newBuilder().body(newResponseBody).build();
93 | ShineLog.i(TAG + "#intercept() \nresponseBody = " + responseBody + "\nnewResponseBody = " + newResponseBody + "\nresponseData = " + responseData + "\ndecryptData = " + decryptData);
94 | } catch (Exception e) {
95 | e.printStackTrace();
96 | ShineLog.e(TAG + "#intercept() decrypt failure, reason:${e.message}");
97 | }
98 | }
99 | }
100 | RetrofitManager.getInstance().removeCipherCls(url);
101 | return response;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/retrofit/manager/RetrofitManager.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.retrofit.manager;
2 |
3 | import android.util.ArrayMap;
4 |
5 | import com.freddy.shine.java.cipher.ICipher;
6 | import com.freddy.shine.java.retrofit.converter.StringConverterFactory;
7 | import com.freddy.shine.java.retrofit.interceptor.OkHttpLoggingInterceptor;
8 | import com.freddy.shine.java.retrofit.interceptor.OkHttpResponseDecryptInterceptor;
9 | import com.freddy.shine.java.retrofit.interceptor.OkHttpRequestEncryptInterceptor;
10 | import com.freddy.shine.java.retrofit.interceptor.OkHttpRequestHeaderInterceptor;
11 | import com.freddy.shine.java.utils.ShineLog;
12 |
13 | import java.util.HashMap;
14 | import java.util.Map;
15 | import java.util.concurrent.ConcurrentHashMap;
16 | import java.util.concurrent.TimeUnit;
17 |
18 | import okhttp3.OkHttpClient;
19 | import retrofit2.Retrofit;
20 | import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
21 |
22 | /**
23 | * Retrofit管理类,提供获取OkHttpClient、Retrofit等方法
24 | *
25 | *
26 | * @author: FreddyChen
27 | * @date : 2022/01/14 15:40
28 | * @email : freddychencsc@gmail.com
29 | */
30 | public class RetrofitManager {
31 |
32 | private static final String TAG = "RetrofitManager";
33 |
34 | private RetrofitManager() {
35 | this.mRetrofitMap = new ConcurrentHashMap<>();
36 | this.mCipherClsMap = new HashMap<>();
37 | this.mCipherMap = new ConcurrentHashMap<>();
38 | this.mHeadersMap = new HashMap<>();
39 | }
40 |
41 | public static RetrofitManager getInstance() {
42 | return SingletonHolder.INSTANCE;
43 | }
44 |
45 | private static class SingletonHolder {
46 | private static final RetrofitManager INSTANCE = new RetrofitManager();
47 | }
48 |
49 | /**
50 | * Retrofit集合
51 | * key: baseUrl
52 | * value: Retrofit
53 | */
54 | private final ConcurrentHashMap
35 | *
36 | * @author: FreddyChen
37 | * @date : 2022/01/14 11:53
38 | * @email : freddychencsc@gmail.com
39 | */
40 | public class RetrofitRequestManager extends AbstractRequestManager {
41 |
42 | private RetrofitRequestManager() {
43 | }
44 |
45 | public static RetrofitRequestManager getInstance() {
46 | return SingletonHolder.INSTANCE;
47 | }
48 |
49 | private static class SingletonHolder {
50 | private static final RetrofitRequestManager INSTANCE = new RetrofitRequestManager();
51 | }
52 |
53 | /**
54 | * 同步请求
55 | *
56 | * @param options 请求参数
57 | * @param type 数据类型映射
58 | * @param parserCls 数据解析器
59 | * @param cipherCls 数据加解密器
60 | * @param listener 回调监听器
61 | * @param
12 | *
13 | * @author: FreddyChen
14 | * @date : 2022/01/15 02:58
15 | * @email : freddychencsc@gmail.com
16 | */
17 | public class ParameterizedTypeImpl implements ParameterizedType {
18 |
19 | private final Class> raw;
20 | private final Type[] args;
21 |
22 | public ParameterizedTypeImpl(Class> raw, Type[] args) {
23 | this.raw = raw;
24 | this.args = args != null ? args : new Type[0];
25 | }
26 |
27 | @NonNull
28 | @Override
29 | public Type[] getActualTypeArguments() {
30 | return args;
31 | }
32 |
33 | @NonNull
34 | @Override
35 | public Type getRawType() {
36 | return raw;
37 | }
38 |
39 | @Nullable
40 | @Override
41 | public Type getOwnerType() {
42 | return null;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/utils/RxExecutor.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.utils;
2 |
3 | import java.util.concurrent.LinkedBlockingQueue;
4 | import java.util.concurrent.ThreadPoolExecutor;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | /**
8 | * 自定义RxJava线程池
9 | *
10 | *
11 | * @author: FreddyChen
12 | * @date : 2022/01/14 16:48
13 | * @email : freddychencsc@gmail.com
14 | */
15 | public class RxExecutor extends ThreadPoolExecutor {
16 |
17 | private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();// CPU个数
18 | private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));// 线程池中核心线程的数量
19 | private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;// 线程池中最大线程数量
20 | private static final long KEEP_ALIVE_TIME = 30L;// 非核心线程的超时时长,当系统中非核心线程闲置时间超过keepAliveTime之后,则会被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,则该参数也表示核心线程的超时时长
21 | private static final int WAIT_COUNT = 128; // 最多排队个数,这里控制线程创建的频率
22 |
23 | public RxExecutor() {
24 | super(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(WAIT_COUNT));
25 | }
26 |
27 | private static final class SingletonHolder {
28 | private static final RxExecutor INSTANCE = new RxExecutor();
29 | }
30 |
31 | public static RxExecutor getInstance() {
32 | return SingletonHolder.INSTANCE;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/utils/ShineLog.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.utils;
2 |
3 | import android.util.Log;
4 |
5 | import com.freddy.shine.java.ShineKit;
6 |
7 | /**
8 | * Shine日志工具类
9 | *
10 | *
11 | * @author: FreddyChen
12 | * @date : 2022/01/14 10:54
13 | * @email : freddychencsc@gmail.com
14 | */
15 | public class ShineLog {
16 |
17 | public static void v(String log) {
18 | ShineLog.v(ShineKit.getInstance().getShineOptions().getLogTag(), log);
19 | }
20 |
21 | public static void v(String tag, String log) {
22 | if (!ShineKit.getInstance().getShineOptions().isLogEnable()) return;
23 | Log.v(tag, log);
24 | }
25 |
26 | public static void d(String log) {
27 | ShineLog.d(ShineKit.getInstance().getShineOptions().getLogTag(), log);
28 | }
29 |
30 | public static void d(String tag, String log) {
31 | if (!ShineKit.getInstance().getShineOptions().isLogEnable()) return;
32 | Log.d(tag, log);
33 | }
34 |
35 | public static void i(String log) {
36 | ShineLog.i(ShineKit.getInstance().getShineOptions().getLogTag(), log);
37 | }
38 |
39 | public static void i(String tag, String log) {
40 | if (!ShineKit.getInstance().getShineOptions().isLogEnable()) return;
41 | Log.i(tag, log);
42 | }
43 |
44 | public static void w(String log) {
45 | ShineLog.w(ShineKit.getInstance().getShineOptions().getLogTag(), log);
46 | }
47 |
48 | public static void w(String tag, String log) {
49 | if (!ShineKit.getInstance().getShineOptions().isLogEnable()) return;
50 | Log.w(tag, log);
51 | }
52 |
53 | public static void e(String log) {
54 | ShineLog.e(ShineKit.getInstance().getShineOptions().getLogTag(), log);
55 | }
56 |
57 | public static void e(String tag, String log) {
58 | if (!ShineKit.getInstance().getShineOptions().isLogEnable()) return;
59 | Log.e(tag, log);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/utils/TypeUtil.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.utils;
2 |
3 | import java.lang.reflect.Type;
4 |
5 | /**
6 | * Type工具类
7 | *
8 | *
9 | * @author: FreddyChen
10 | * @date : 2022/01/15 03:24
11 | * @email : freddychencsc@gmail.com
12 | */
13 | public class TypeUtil {
14 |
15 | public static
9 | * {@link #baseUrl} baseUrl
10 | * {@link #function} 接口地址
11 | * {@link #headers} 请求头
12 | * {@link #params} 请求参数
13 | * {@link #contentType} contentType
14 | *
15 | * @author: FreddyChen
16 | * @date : 2022/01/14 10:22
17 | * @email : freddychencsc@gmail.com
18 | */
19 | public class RequestOptions {
20 |
21 | private final RequestMethod requestMethod;
22 | private final String baseUrl;
23 | private final String function;
24 | private final ArrayMap
10 | * {@link #logTag} 日志Tag
11 | * {@link #baseUrl} 默认baseUrl
12 | * {@link #parserCls} 默认数据解析器cls
13 | *
14 | * @author: FreddyChen
15 | * @date : 2022/01/14 10:38
16 | * @email : freddychencsc@gmail.com
17 | */
18 | public class ShineOptions {
19 |
20 | private final boolean logEnable;
21 | private final String logTag;
22 | private final String baseUrl;
23 | private final Class extends IParser> parserCls;
24 |
25 | private ShineOptions(Builder builder) {
26 | this.logEnable = builder.logEnable;
27 | this.logTag = builder.logTag;
28 | this.baseUrl = builder.baseUrl;
29 | this.parserCls = builder.parserCls;
30 | }
31 |
32 | public boolean isLogEnable() {
33 | return logEnable;
34 | }
35 |
36 | public String getLogTag() {
37 | return logTag;
38 | }
39 |
40 | public String getBaseUrl() {
41 | return baseUrl;
42 | }
43 |
44 | public Class extends IParser> getParserCls() {
45 | return parserCls;
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | return "ShineOptions{" +
51 | "logEnable=" + logEnable +
52 | ", logTag='" + logTag + '\'' +
53 | ", baseUrl='" + baseUrl + '\'' +
54 | ", parserCls=" + parserCls +
55 | '}';
56 | }
57 |
58 | public static class Builder {
59 | private boolean logEnable;
60 | private String logTag;
61 | private String baseUrl;
62 | private Class extends IParser> parserCls;
63 |
64 | public Builder() {
65 | this.logEnable = ShineConfig.DEFAULT_LOG_ENABLE;
66 | this.logTag = ShineConfig.DEFAULT_LOG_TAG;
67 | this.parserCls = DefaultParser.class;
68 | }
69 |
70 | public Builder setLogEnable(boolean logEnable) {
71 | this.logEnable = logEnable;
72 | return this;
73 | }
74 |
75 | public Builder setLogTag(String logTag) {
76 | this.logTag = logTag;
77 | return this;
78 | }
79 |
80 | public Builder setBaseUrl(String baseUrl) {
81 | this.baseUrl = baseUrl;
82 | return this;
83 | }
84 |
85 | public Builder setParserCls(Class extends IParser> parserCls) {
86 | this.parserCls = parserCls;
87 | return this;
88 | }
89 |
90 | public ShineOptions build() {
91 | return new ShineOptions(this);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/exception/RequestException.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.exception;
2 |
3 | /**
4 | * 封装的请求异常
5 | *
7 | * * {@link #url} 接口地址(baseUrl+function)
8 | * * {@link #statusCode} http状态码
9 | * * {@link #errCode} 业务错误码
10 | * * {@link #errMsg} 业务错误信息
11 | * * {@link #errBody} 错误详细信息
12 | *
13 | * @author: FreddyChen
14 | * @date : 2022/01/14 11:23
15 | * @email : freddychencsc@gmail.com
16 | */
17 | public class RequestException extends Throwable {
18 |
19 | /**
20 | * 异常类型
21 | *
9 | * {@link #onSuccessful(T)}} 请求成功
10 | * {@link #onFailure(RequestException)} 请求失败
11 | * {@link #onFinish()} 请求完成
12 | *
13 | * @author: FreddyChen
14 | * @date : 2022/01/14 11:22
15 | * @email : freddychencsc@gmail.com
16 | */
17 | public interface IResponseListener
9 | *
10 | * @author: FreddyChen
11 | * @date : 2022/01/14 11:35
12 | * @email : freddychencsc@gmail.com
13 | */
14 | public abstract class ResponseListAdapter
7 | * {@link #msg} 返回信息
8 | * {@link #data} 返回数据
9 | *
10 | * @author: FreddyChen
11 | * @date : 2022/01/14 10:51
12 | * @email : freddychencsc@gmail.com
13 | */
14 | public class DefaultResponseModel
11 | *
12 | * @author: FreddyChen
13 | * @date : 2022/01/14 10:43
14 | * @email : freddychencsc@gmail.com
15 | */
16 | public abstract class AbstractParser implements IParser {
17 |
18 | protected Gson gson = new Gson();
19 | }
20 |
--------------------------------------------------------------------------------
/shine-java/src/main/java/com/freddy/shine/java/parser/DefaultParser.java:
--------------------------------------------------------------------------------
1 | package com.freddy.shine.java.parser;
2 |
3 | import com.freddy.shine.java.exception.RequestException;
4 | import com.freddy.shine.java.model.DefaultResponseModel;
5 | import com.freddy.shine.java.utils.ShineLog;
6 | import com.google.gson.reflect.TypeToken;
7 |
8 | import java.lang.reflect.Type;
9 |
10 | /**
11 | * 默认数据解析器
12 | *
14 | * code
15 | * msg
16 | * data
17 | *
18 | * @author: FreddyChen
19 | * @date : 2022/01/14 10:43
20 | * @email : freddychencsc@gmail.com
21 | */
22 | public class DefaultParser extends AbstractParser {
23 |
24 | private static final String TAG = "DefaultParser";
25 |
26 | @Override
27 | public
15 | */
16 | public interface IParser {
17 |
18 |