boolean doSave(String key, T value) {
29 | return false;
30 | }
31 |
32 | @Override
33 | protected boolean doRemove(String key) {
34 | return false;
35 | }
36 |
37 | @Override
38 | protected boolean doClear() {
39 | return false;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/converter/IDiskConverter.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.cache.converter;
3 |
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.lang.reflect.Type;
7 |
8 | /**
9 | * 描述:通用转换器接口
10 | * 1.实现该接口可以实现一大波的磁盘存储操作。
11 | * 2.可以实现Serializable、Gson,Parcelable、fastjson、xml、kryo等等
12 | * 目前只实现了:GsonDiskConverter和SerializableDiskConverter转换器,有其它自定义需求自己去实现吧!
13 | *
14 | * 《看到能很方便的实现一大波功能,是不是很刺激啊(*>﹏<*)》
15 | *
16 | */
17 | public interface IDiskConverter {
18 |
19 | /**
20 | * 读取
21 | *
22 | * @param source 输入流
23 | * @param type 读取数据后要转换的数据类型
24 | * 这里没有用泛型T或者Tyepe来做,是因为本框架决定的一些问题,泛型会丢失
25 | * @return
26 | */
27 | T load(InputStream source, Type type);
28 |
29 | /**
30 | * 写入
31 | *
32 | * @param sink
33 | * @param data 保存的数据
34 | * @return
35 | */
36 | boolean writer(OutputStream sink, Object data);
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/model/CacheResult.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.cache.model;
3 |
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * 描述:缓存对象
9 | */
10 | public class CacheResult implements Serializable {
11 | public boolean isFromCache;
12 | public T data;
13 |
14 | public CacheResult() {
15 | }
16 |
17 | public CacheResult(boolean isFromCache) {
18 | this.isFromCache = isFromCache;
19 | }
20 |
21 | public CacheResult(boolean isFromCache, T data) {
22 | this.isFromCache = isFromCache;
23 | this.data = data;
24 | }
25 |
26 | public boolean isCache() {
27 | return isFromCache;
28 | }
29 |
30 | public void setCache(boolean cache) {
31 | isFromCache = cache;
32 | }
33 |
34 | @Override
35 | public String toString() {
36 | return "CacheResult{" +
37 | "isCache=" + isFromCache +
38 | ", data=" + data +
39 | '}';
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/model/ApiResult.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.model;
3 |
4 | /**
5 | * 描述:提供的默认的标注返回api
6 | */
7 | public class ApiResult {
8 | private int code;
9 | private String msg;
10 | private T data;
11 | public int getCode() {
12 | return code;
13 | }
14 |
15 | public void setCode(int code) {
16 | this.code = code;
17 | }
18 |
19 | public String getMsg() {
20 | return msg;
21 | }
22 |
23 | public void setMsg(String msg) {
24 | this.msg = msg;
25 | }
26 |
27 | public T getData() {
28 | return data;
29 | }
30 |
31 | public void setData(T data) {
32 | this.data = data;
33 | }
34 |
35 | public boolean isOk() {
36 | return code == 0;
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return "ApiResult{" +
42 | "code='" + code + '\'' +
43 | ", msg='" + msg + '\'' +
44 | ", data=" + data +
45 | '}';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/pic/PaletteTarget.java:
--------------------------------------------------------------------------------
1 | package com.wls.wnlibrary.utils.pic;
2 |
3 | import android.support.v4.util.Pair;
4 | import android.view.View;
5 | import android.widget.TextView;
6 |
7 | import java.util.ArrayList;
8 |
9 | public class PaletteTarget {
10 |
11 | @BitmapPalette.Profile
12 | protected int paletteProfile = GlidePalette.Profile.VIBRANT;
13 |
14 | protected ArrayList> targetsBackground = new ArrayList<>();
15 | protected ArrayList> targetsText = new ArrayList<>();
16 |
17 | protected boolean targetCrossfade = false;
18 | protected int targetCrossfadeSpeed = DEFAULT_CROSSFADE_SPEED;
19 | protected static final int DEFAULT_CROSSFADE_SPEED = 300;
20 |
21 | public PaletteTarget(@BitmapPalette.Profile int paletteProfile) {
22 | this.paletteProfile = paletteProfile;
23 | }
24 |
25 | public void clear() {
26 | targetsBackground.clear();
27 | targetsText.clear();
28 |
29 | targetsBackground = null;
30 | targetsText = null;
31 |
32 | targetCrossfade = false;
33 | targetCrossfadeSpeed = DEFAULT_CROSSFADE_SPEED;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | android {
8 | compileSdkVersion 27
9 | defaultConfig {
10 | applicationId "com.wls.wn"
11 | minSdkVersion 15
12 | targetSdkVersion 27
13 | versionCode 1
14 | versionName "1.0"
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation fileTree(include: ['*.jar'], dir: 'libs')
27 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
28 | implementation 'com.android.support:appcompat-v7:27.1.1'
29 | implementation 'com.android.support.constraint:constraint-layout:1.1.2'
30 | testImplementation 'junit:junit:4.12'
31 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
33 | api project(':wnlibrary')
34 | }
35 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/utils/HttpUtil.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.utils;
3 |
4 | import java.nio.charset.Charset;
5 | import java.util.Map;
6 |
7 | /**
8 | * 描述:http工具类
9 |
10 | */
11 | public class HttpUtil {
12 | public static final Charset UTF8 = Charset.forName("UTF-8");
13 | public static String createUrlFromParams(String url, Map params) {
14 | try {
15 | StringBuilder sb = new StringBuilder();
16 | sb.append(url);
17 | if (url.indexOf('&') > 0 || url.indexOf('?') > 0) sb.append("&");
18 | else sb.append("?");
19 | for (Map.Entry urlParams : params.entrySet()) {
20 | String urlValues = urlParams.getValue();
21 | //对参数进行 utf-8 编码,防止头信息传中文
22 | //String urlValue = URLEncoder.encode(urlValues, UTF8.name());
23 | sb.append(urlParams.getKey()).append("=").append(urlValues).append("&");
24 | }
25 | sb.deleteCharAt(sb.length() - 1);
26 | return sb.toString();
27 | } catch (Exception e) {
28 | HttpLog.e(e.getMessage());
29 | }
30 | return url;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/func/HttpResponseFunc.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 zhouyou(478319399@qq.com)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wls.wnlibrary.utils.net.func;
18 |
19 |
20 | import com.wls.wnlibrary.utils.net.exception.ApiException;
21 |
22 | import io.reactivex.Observable;
23 | import io.reactivex.annotations.NonNull;
24 | import io.reactivex.functions.Function;
25 |
26 | /**
27 | * 描述:异常转换处理
28 | */
29 | public class HttpResponseFunc implements Function> {
30 | @Override
31 | public Observable apply(@NonNull Throwable throwable) throws Exception {
32 | return Observable.error(ApiException.handleException(throwable));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/model/CacheMode.java:
--------------------------------------------------------------------------------
1 |
2 |
3 | package com.wls.wnlibrary.utils.net.cache.model;
4 |
5 | /**
6 | * 描述:网络请求策略
7 | */
8 | public enum CacheMode {
9 | /**
10 | * 不使用缓存,该模式下,cacheKey,cacheMaxAge 参数均无效
11 | **/
12 | NO_CACHE("NoStrategy"),
13 | /**
14 | * 完全按照HTTP协议的默认缓存规则,走OKhttp的Cache缓存
15 | **/
16 | DEFAULT("NoStrategy"),
17 | /**
18 | * 先请求网络,请求网络失败后再加载缓存
19 | */
20 | FIRSTREMOTE("FirstRemoteStrategy"),
21 |
22 | /**
23 | * 先加载缓存,缓存没有再去请求网络
24 | */
25 | FIRSTCACHE("FirstCacheStategy"),
26 |
27 | /**
28 | * 仅加载网络,但数据依然会被缓存
29 | */
30 | ONLYREMOTE("OnlyRemoteStrategy"),
31 |
32 | /**
33 | * 只读取缓存
34 | */
35 | ONLYCACHE("OnlyCacheStrategy"),
36 |
37 | /**
38 | * 先使用缓存,不管是否存在,仍然请求网络,会回调两次
39 | */
40 | CACHEANDREMOTE("CacheAndRemoteStrategy"),
41 | /**
42 | * 先使用缓存,不管是否存在,仍然请求网络,会先把缓存回调给你,
43 | * 等网络请求回来发现数据是一样的就不会再返回,否则再返回
44 | * (这样做的目的是防止数据是一样的你也需要刷新界面)
45 | */
46 | CACHEANDREMOTEDISTINCT("CacheAndRemoteDistinctStrategy");
47 |
48 | private final String className;
49 |
50 | CacheMode(String className) {
51 | this.className = className;
52 | }
53 |
54 | public String getClassName() {
55 | return className;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/stategy/CacheAndRemoteStrategy.java:
--------------------------------------------------------------------------------
1 |
2 |
3 | package com.wls.wnlibrary.utils.net.cache.stategy;
4 |
5 |
6 | import com.wls.wnlibrary.utils.net.cache.RxCache;
7 | import com.wls.wnlibrary.utils.net.cache.model.CacheResult;
8 |
9 | import java.lang.reflect.Type;
10 |
11 | import io.reactivex.Observable;
12 | import io.reactivex.annotations.NonNull;
13 | import io.reactivex.functions.Predicate;
14 |
15 |
16 | /**
17 | * 描述:先显示缓存,再请求网络
18 | * <-------此类加载用的是反射 所以类名是灰色的 没有直接引用 不要误删---------------->
19 | */
20 | public final class CacheAndRemoteStrategy extends BaseStrategy {
21 | @Override
22 | public Observable> execute(RxCache rxCache, String key, long time, Observable source, Type type) {
23 | Observable> cache = loadCache(rxCache, type, key, time, true);
24 | Observable> remote = loadRemote(rxCache, key, source, false);
25 | return Observable.concat(cache, remote)
26 | .filter(new Predicate>() {
27 | @Override
28 | public boolean test(@NonNull CacheResult tCacheResult) throws Exception {
29 | return tCacheResult != null && tCacheResult.data != null;
30 | }
31 | });
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/callback/CallClazzProxy.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.callback;
3 |
4 | import com.google.gson.internal.$Gson$Types;
5 | import com.wls.wnlibrary.utils.net.model.ApiResult;
6 | import com.wls.wnlibrary.utils.net.utils.Utils;
7 |
8 |
9 | import java.lang.reflect.ParameterizedType;
10 | import java.lang.reflect.Type;
11 |
12 | import okhttp3.ResponseBody;
13 |
14 | /**
15 | * 描述:提供Clazz回调代理
16 | * 主要用于可以自定义ApiResult
17 | */
18 | public abstract class CallClazzProxy, R> implements IType {
19 | private Type type;
20 |
21 |
22 | public CallClazzProxy(Type type) {
23 | this.type = type;
24 | }
25 |
26 | public Type getCallType() {
27 | return type;
28 | }
29 |
30 | @Override
31 | public Type getType() {//CallClazz代理方式,获取需要解析的Type
32 | Type typeArguments = null;
33 | if (type != null) {
34 | typeArguments = type;
35 | }
36 | if (typeArguments == null) {
37 | typeArguments = ResponseBody.class;
38 | }
39 | Type rawType = Utils.findNeedType(getClass());
40 | if (rawType instanceof ParameterizedType) {
41 | rawType = ((ParameterizedType) rawType).getRawType();
42 | }
43 | return $Gson$Types.newParameterizedTypeWithOwner(null, rawType, typeArguments);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/stategy/OnlyRemoteStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 zhouyou(478319399@qq.com)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wls.wnlibrary.utils.net.cache.stategy;
18 |
19 |
20 | import com.wls.wnlibrary.utils.net.cache.RxCache;
21 | import com.wls.wnlibrary.utils.net.cache.model.CacheResult;
22 |
23 | import java.lang.reflect.Type;
24 |
25 | import io.reactivex.Observable;
26 |
27 | /**
28 | * 描述:只请求网络
29 | *<-------此类加载用的是反射 所以类名是灰色的 没有直接引用 不要误删---------------->
30 | */
31 | public final class OnlyRemoteStrategy extends BaseStrategy{
32 | @Override
33 | public Observable> execute(RxCache rxCache, String key, long time, Observable source, Type type) {
34 | return loadRemote(rxCache,key, source,false);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/interceptor/HeadersInterceptor.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.interceptor;
3 | import com.wls.wnlibrary.utils.net.model.HttpHeaders;
4 | import com.wls.wnlibrary.utils.net.utils.HttpLog;
5 |
6 | import java.io.IOException;
7 | import java.util.Map;
8 |
9 | import okhttp3.Interceptor;
10 | import okhttp3.Request;
11 | import okhttp3.Response;
12 |
13 | /**
14 | * 描述:配置公共头部
15 | */
16 | public class HeadersInterceptor implements Interceptor {
17 |
18 | private HttpHeaders headers;
19 |
20 | public HeadersInterceptor(HttpHeaders headers) {
21 | this.headers = headers;
22 | }
23 |
24 |
25 | @Override
26 | public Response intercept(Chain chain) throws IOException {
27 | Request.Builder builder = chain.request().newBuilder();
28 | if (headers.headersMap.isEmpty()) return chain.proceed(builder.build());
29 | try {
30 | for (Map.Entry entry : headers.headersMap.entrySet()) {
31 | //去除重复的header
32 | //builder.removeHeader(entry.getKey());
33 | //builder.addHeader(entry.getKey(), entry.getValue()).build();
34 | builder.header(entry.getKey(), entry.getValue()).build();
35 | }
36 | } catch (Exception e) {
37 | HttpLog.e(e);
38 | }
39 | return chain.proceed(builder.build());
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/callback/CallBack.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 zhouyou(478319399@qq.com)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wls.wnlibrary.utils.net.callback;
18 |
19 |
20 | import com.wls.wnlibrary.utils.net.exception.ApiException;
21 | import com.wls.wnlibrary.utils.net.utils.Utils;
22 |
23 | import java.lang.reflect.Type;
24 |
25 | /**
26 | * 描述:网络请求回调
27 | */
28 | public abstract class CallBack implements IType {
29 | public abstract void onStart();
30 |
31 | public abstract void onCompleted();
32 |
33 | public abstract void onError(ApiException e);
34 |
35 | public abstract void onSuccess(T t);
36 |
37 | @Override
38 | public Type getType() {//获取需要解析的泛型T类型
39 | return Utils.findNeedClass(getClass());
40 | }
41 |
42 | public Type getRawType() {//获取需要解析的泛型T raw类型
43 | return Utils.findRawType(getClass());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/body/RequestBodyUtils.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.body;
3 |
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | import okhttp3.MediaType;
8 | import okhttp3.RequestBody;
9 | import okhttp3.internal.Util;
10 | import okio.BufferedSink;
11 | import okio.Okio;
12 | import okio.Source;
13 |
14 | /**
15 | * 描述:请求体处理工具类
16 | */
17 | public class RequestBodyUtils {
18 |
19 | //public final static MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
20 |
21 | public static RequestBody create(final MediaType mediaType, final InputStream inputStream) {
22 | return new RequestBody() {
23 | @Override
24 | public MediaType contentType() {
25 | return mediaType;
26 | }
27 |
28 | @Override
29 | public long contentLength() {
30 | try {
31 | return inputStream.available();
32 | } catch (IOException e) {
33 | return 0;
34 | }
35 | }
36 |
37 | @Override
38 | public void writeTo(BufferedSink sink) throws IOException {
39 | Source source = null;
40 | try {
41 | source = Okio.source(inputStream);
42 | sink.writeAll(source);
43 | } finally {
44 | Util.closeQuietly(source);
45 | }
46 | }
47 | };
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/stategy/NoStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 zhouyou(478319399@qq.com)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wls.wnlibrary.utils.net.cache.stategy;
18 |
19 | import com.wls.wnlibrary.utils.net.cache.RxCache;
20 | import com.wls.wnlibrary.utils.net.cache.model.CacheResult;
21 |
22 | import java.lang.reflect.Type;
23 |
24 | import io.reactivex.Observable;
25 | import io.reactivex.annotations.NonNull;
26 | import io.reactivex.functions.Function;
27 |
28 | /**
29 | * 描述:网络加载,不缓存
30 | */
31 | public class NoStrategy implements IStrategy {
32 | @Override
33 | public Observable> execute(RxCache rxCache, String cacheKey, long cacheTime, Observable source, Type type) {
34 | return source.map(new Function>() {
35 | @Override
36 | public CacheResult apply(@NonNull T t) throws Exception {
37 | return new CacheResult(false, t);
38 | }
39 | });
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/subsciber/CallBackSubsciber.java:
--------------------------------------------------------------------------------
1 |
2 |
3 | package com.wls.wnlibrary.utils.net.subsciber;
4 |
5 | import android.content.Context;
6 |
7 |
8 | import com.wls.wnlibrary.utils.net.callback.CallBack;
9 | import com.wls.wnlibrary.utils.net.callback.ProgressDialogCallBack;
10 | import com.wls.wnlibrary.utils.net.exception.ApiException;
11 |
12 | import io.reactivex.annotations.NonNull;
13 |
14 |
15 | /**
16 | * 描述:带有callBack的回调
17 | * 主要作用是不需要用户订阅,只要实现callback回调
18 | */
19 | public class CallBackSubsciber extends BaseSubscriber {
20 | public CallBack mCallBack;
21 |
22 |
23 | public CallBackSubsciber(Context context, CallBack callBack) {
24 | super(context);
25 | mCallBack = callBack;
26 | if (callBack instanceof ProgressDialogCallBack) {
27 | ((ProgressDialogCallBack) callBack).subscription(this);
28 | }
29 | }
30 |
31 |
32 | @Override
33 | protected void onStart() {
34 | super.onStart();
35 | if (mCallBack != null) {
36 | mCallBack.onStart();
37 | }
38 | }
39 |
40 | @Override
41 | public void onError(ApiException e) {
42 | if (mCallBack != null) {
43 | mCallBack.onError(e);
44 | }
45 | }
46 |
47 | @Override
48 | public void onNext(@NonNull T t) {
49 | super.onNext(t);
50 | if (mCallBack != null) {
51 | mCallBack.onSuccess(t);
52 | }
53 | }
54 |
55 | @Override
56 | public void onComplete() {
57 | super.onComplete();
58 | if (mCallBack != null) {
59 | mCallBack.onCompleted();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/wnlibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.github.dcendents.android-maven'
3 | group='com.github.wlsj'
4 | android {
5 | compileSdkVersion 27
6 |
7 |
8 |
9 | defaultConfig {
10 | minSdkVersion 15
11 | targetSdkVersion 27
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
16 |
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | }
27 |
28 | dependencies {
29 | compile fileTree(include: ['*.jar'], dir: 'libs')
30 | implementation 'com.android.support:appcompat-v7:27.1.1'
31 | testImplementation 'junit:junit:4.12'
32 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
33 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
34 | compile 'com.android.support:percent:27.1.1'
35 | compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
36 | compile 'com.squareup.okhttp3:okhttp:3.4.1'
37 | compile 'com.jakewharton:disklrucache:2.0.2'
38 | compile 'io.reactivex.rxjava2:rxjava:2.1.1'
39 | compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
40 | compile 'com.squareup.retrofit2:retrofit:2.3.0'
41 | compile 'com.squareup.retrofit2:converter-gson:2.3.0'
42 | compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
43 | compile 'com.android.support:design:27.1.1'
44 | compile 'com.google.code.gson:gson:2.0.5'
45 | compile 'com.github.bumptech.glide:glide:4.8.0'
46 | compile 'com.android.support:palette-v7:27.1.1'
47 | }
48 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/stategy/FirstRemoteStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2017 zhouyou(478319399@qq.com)
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.wls.wnlibrary.utils.net.cache.stategy;
18 | import com.wls.wnlibrary.utils.net.cache.RxCache;
19 | import com.wls.wnlibrary.utils.net.cache.model.CacheResult;
20 |
21 | import java.lang.reflect.Type;
22 | import java.util.Arrays;
23 |
24 | import io.reactivex.Observable;
25 |
26 |
27 | /**
28 | * 描述:先请求网络,网络请求失败,再加载缓存
29 | * <-------此类加载用的是反射 所以类名是灰色的 没有直接引用 不要误删---------------->
30 | */
31 | public final class FirstRemoteStrategy extends BaseStrategy {
32 | @Override
33 | public Observable> execute(RxCache rxCache, String key, long time, Observable source, Type type) {
34 | Observable> cache = loadCache(rxCache, type, key, time, true);
35 | Observable> remote = loadRemote(rxCache, key, source, false);
36 | //return remote.switchIfEmpty(cache);
37 | return Observable
38 | .concatDelayError(Arrays.asList(remote, cache))
39 | .take(1);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/converter/SerializableDiskConverter.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.cache.converter;
3 |
4 |
5 | import com.wls.wnlibrary.utils.net.utils.HttpLog;
6 | import com.wls.wnlibrary.utils.net.utils.Utils;
7 |
8 |
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.ObjectInputStream;
12 | import java.io.ObjectOutputStream;
13 | import java.io.OutputStream;
14 | import java.lang.reflect.Type;
15 |
16 | /**
17 | * 描述:序列化对象的转换器
18 | * 1.使用改转换器,对象&对象中的其它所有对象都必须是要实现Serializable接口(序列化)
19 | * 优点:
20 | * 速度快
21 | * 《-------骚年,自己根据实际需求选择吧!!!------------》
22 | */
23 | @SuppressWarnings(value={"unchecked", "deprecation"})
24 | public class SerializableDiskConverter implements IDiskConverter {
25 |
26 | @Override
27 | public T load(InputStream source, Type type) {
28 | //序列化的缓存不需要用到clazz
29 | T value = null;
30 | ObjectInputStream oin = null;
31 | try {
32 | oin = new ObjectInputStream(source);
33 | value = (T) oin.readObject();
34 | } catch (IOException | ClassNotFoundException e) {
35 | HttpLog.e(e);
36 | } finally {
37 | Utils.close(oin);
38 | }
39 | return value;
40 | }
41 |
42 | @Override
43 | public boolean writer(OutputStream sink, Object data) {
44 | ObjectOutputStream oos = null;
45 | try {
46 | oos = new ObjectOutputStream(sink);
47 | oos.writeObject(data);
48 | oos.flush();
49 | return true;
50 | } catch (IOException e) {
51 | HttpLog.e(e);
52 | } finally {
53 | Utils.close(oos);
54 | }
55 | return false;
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cache/stategy/CacheAndRemoteDistinctStrategy.java:
--------------------------------------------------------------------------------
1 |
2 |
3 | package com.wls.wnlibrary.utils.net.cache.stategy;
4 |
5 |
6 |
7 | import com.wls.wnlibrary.utils.net.cache.RxCache;
8 | import com.wls.wnlibrary.utils.net.cache.model.CacheResult;
9 |
10 | import java.lang.reflect.Type;
11 |
12 | import io.reactivex.Observable;
13 | import io.reactivex.annotations.NonNull;
14 | import io.reactivex.functions.Function;
15 | import io.reactivex.functions.Predicate;
16 | import okio.ByteString;
17 |
18 | /**
19 | * 描述:先显示缓存,再请求网络
20 | * <-------此类加载用的是反射 所以类名是灰色的 没有直接引用 不要误删---------------->
21 | */
22 | public final class CacheAndRemoteDistinctStrategy extends BaseStrategy {
23 | @Override
24 | public Observable> execute(RxCache rxCache, String key, long time, Observable source, Type type) {
25 | Observable> cache = loadCache(rxCache, type, key, time,true);
26 | Observable> remote = loadRemote(rxCache, key, source,false);
27 | return Observable.concat(cache, remote)
28 | .filter(new Predicate>() {
29 | @Override
30 | public boolean test(@NonNull CacheResult tCacheResult) throws Exception {
31 | return tCacheResult != null && tCacheResult.data != null;
32 | }
33 | }).distinctUntilChanged(new Function, String>() {
34 | @Override
35 | public String apply(@NonNull CacheResult tCacheResult) throws Exception {
36 | return ByteString.of(tCacheResult.data.toString().getBytes()).md5().hex();
37 | }
38 | });
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cookie/CookieManger.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.cookie;
3 |
4 | import android.content.Context;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import okhttp3.Cookie;
10 | import okhttp3.CookieJar;
11 | import okhttp3.HttpUrl;
12 |
13 |
14 | /**
15 | * 描述:cookie管理器
16 | */
17 | public class CookieManger implements CookieJar {
18 |
19 | private static Context mContext;
20 | private static PersistentCookieStore cookieStore;
21 |
22 | public CookieManger(Context context) {
23 | mContext = context;
24 | if (cookieStore == null) {
25 | cookieStore = new PersistentCookieStore(mContext);
26 | }
27 | }
28 |
29 | public void addCookies(List cookies) {
30 | cookieStore.addCookies(cookies);
31 | }
32 |
33 | public void saveFromResponse(HttpUrl url, Cookie cookie) {
34 | if (cookie != null) {
35 | cookieStore.add(url, cookie);
36 | }
37 | }
38 |
39 | public PersistentCookieStore getCookieStore() {
40 | return cookieStore;
41 | }
42 |
43 | @Override
44 | public void saveFromResponse(HttpUrl url, List cookies) {
45 | if (cookies != null && cookies.size() > 0) {
46 | for (Cookie item : cookies) {
47 | cookieStore.add(url, item);
48 | }
49 | }
50 | }
51 |
52 |
53 | @Override
54 | public List loadForRequest(HttpUrl url) {
55 | List cookies = cookieStore.get(url);
56 | return cookies != null ? cookies : new ArrayList();
57 | }
58 |
59 | public void remove(HttpUrl url, Cookie cookie) {
60 | cookieStore.remove(url, cookie);
61 | }
62 |
63 | public void removeAll() {
64 | cookieStore.removeAll();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/callback/CallBackProxy.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.callback;
3 |
4 | import com.google.gson.internal.$Gson$Types;
5 | import com.wls.wnlibrary.utils.net.cache.model.CacheResult;
6 | import com.wls.wnlibrary.utils.net.model.ApiResult;
7 | import com.wls.wnlibrary.utils.net.utils.Utils;
8 |
9 | import java.lang.reflect.ParameterizedType;
10 | import java.lang.reflect.Type;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | import okhttp3.ResponseBody;
15 |
16 | /**
17 | * 描述:提供回调代理
18 | * 主要用于可以自定义ApiResult
19 | */
20 | public abstract class CallBackProxy, R> implements IType {
21 | CallBack mCallBack;
22 |
23 | public CallBackProxy(CallBack callBack) {
24 | mCallBack = callBack;
25 | }
26 |
27 | public CallBack getCallBack() {
28 | return mCallBack;
29 | }
30 |
31 | @Override
32 | public Type getType() {//CallBack代理方式,获取需要解析的Type
33 | Type typeArguments = null;
34 | if (mCallBack != null) {
35 | Type rawType = mCallBack.getRawType();//如果用户的信息是返回List需单独处理
36 | if (List.class.isAssignableFrom(Utils.getClass(rawType, 0)) || Map.class.isAssignableFrom(Utils.getClass(rawType, 0))) {
37 | typeArguments = mCallBack.getType();
38 | } else if (CacheResult.class.isAssignableFrom(Utils.getClass(rawType, 0))) {
39 | Type type = mCallBack.getType();
40 | typeArguments = Utils.getParameterizedType(type, 0);
41 | } else {
42 | Type type = mCallBack.getType();
43 | typeArguments = Utils.getClass(type, 0);
44 | }
45 | }
46 | if (typeArguments == null) {
47 | typeArguments = ResponseBody.class;
48 | }
49 | Type rawType = Utils.findNeedType(getClass());
50 | if (rawType instanceof ParameterizedType) {
51 | rawType = ((ParameterizedType) rawType).getRawType();
52 | }
53 | return $Gson$Types.newParameterizedTypeWithOwner(null, rawType, typeArguments);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/subsciber/BaseSubscriber.java:
--------------------------------------------------------------------------------
1 |
2 |
3 | package com.wls.wnlibrary.utils.net.subsciber;
4 |
5 | import android.content.Context;
6 |
7 |
8 | import com.wls.wnlibrary.utils.net.exception.ApiException;
9 | import com.wls.wnlibrary.utils.net.utils.HttpLog;
10 |
11 | import java.lang.ref.WeakReference;
12 |
13 | import io.reactivex.annotations.NonNull;
14 | import io.reactivex.observers.DisposableObserver;
15 |
16 | import static com.wls.wnlibrary.utils.net.utils.Utils.isNetworkAvailable;
17 |
18 | /**
19 | * 描述:订阅的基类
20 | * 1.可以防止内存泄露。
21 | * 2.在onStart()没有网络时直接onCompleted();
22 | * 3.统一处理了异常
23 |
24 | */
25 | public abstract class BaseSubscriber extends DisposableObserver {
26 | public WeakReference contextWeakReference;
27 |
28 | public BaseSubscriber() {
29 | }
30 |
31 | @Override
32 | protected void onStart() {
33 | HttpLog.e("-->http is onStart");
34 | if (contextWeakReference != null && contextWeakReference.get() != null && !isNetworkAvailable(contextWeakReference.get())) {
35 | //Toast.makeText(context, "无网络,读取缓存数据", Toast.LENGTH_SHORT).show();
36 | onComplete();
37 | }
38 | }
39 |
40 |
41 | public BaseSubscriber(Context context) {
42 | if (context != null) {
43 | contextWeakReference = new WeakReference<>(context);
44 | }
45 | }
46 |
47 | @Override
48 | public void onNext(@NonNull T t) {
49 | HttpLog.e("-->http is onNext");
50 | }
51 |
52 | @Override
53 | public final void onError(Throwable e) {
54 | HttpLog.e("-->http is onError");
55 | if (e instanceof ApiException) {
56 | HttpLog.e("--> e instanceof ApiException err:" + e);
57 | onError((ApiException) e);
58 | } else {
59 | HttpLog.e("--> e !instanceof ApiException err:" + e);
60 | onError(ApiException.handleException(e));
61 | }
62 | }
63 |
64 | @Override
65 | public void onComplete() {
66 | HttpLog.e("-->http is onComplete");
67 | }
68 |
69 |
70 | public abstract void onError(ApiException e);
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/cookie/SerializableOkHttpCookies.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.cookie;
3 |
4 | import java.io.IOException;
5 | import java.io.ObjectInputStream;
6 | import java.io.ObjectOutputStream;
7 | import java.io.Serializable;
8 |
9 | import okhttp3.Cookie;
10 |
11 | /**
12 | * 描述:对存储的cookie进行序列化
13 | */
14 | public class SerializableOkHttpCookies implements Serializable {
15 |
16 | private transient final Cookie cookies;
17 | private transient Cookie clientCookies;
18 |
19 | public SerializableOkHttpCookies(Cookie cookies) {
20 | this.cookies = cookies;
21 | }
22 |
23 | public Cookie getCookies() {
24 | Cookie bestCookies = cookies;
25 | if (clientCookies != null) {
26 | bestCookies = clientCookies;
27 | }
28 | return bestCookies;
29 | }
30 |
31 | private void writeObject(ObjectOutputStream out) throws IOException {
32 | out.writeObject(cookies.name());
33 | out.writeObject(cookies.value());
34 | out.writeLong(cookies.expiresAt());
35 | out.writeObject(cookies.domain());
36 | out.writeObject(cookies.path());
37 | out.writeBoolean(cookies.secure());
38 | out.writeBoolean(cookies.httpOnly());
39 | out.writeBoolean(cookies.hostOnly());
40 | out.writeBoolean(cookies.persistent());
41 | }
42 |
43 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
44 | String name = (String) in.readObject();
45 | String value = (String) in.readObject();
46 | long expiresAt = in.readLong();
47 | String domain = (String) in.readObject();
48 | String path = (String) in.readObject();
49 | boolean secure = in.readBoolean();
50 | boolean httpOnly = in.readBoolean();
51 | boolean hostOnly = in.readBoolean();
52 | //boolean persistent = in.readBoolean();
53 | Cookie.Builder builder = new Cookie.Builder();
54 | builder = builder.name(name);
55 | builder = builder.value(value);
56 | builder = builder.expiresAt(expiresAt);
57 | builder = hostOnly ? builder.hostOnlyDomain(domain) : builder.domain(domain);
58 | builder = builder.path(path);
59 | builder = secure ? builder.secure() : builder;
60 | builder = httpOnly ? builder.httpOnly() : builder;
61 | clientCookies =builder.build();
62 | }
63 | }
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/interceptor/CacheInterceptor.java:
--------------------------------------------------------------------------------
1 |
2 | package com.wls.wnlibrary.utils.net.interceptor;
3 |
4 | import android.content.Context;
5 | import android.text.TextUtils;
6 |
7 |
8 | import com.wls.wnlibrary.utils.net.utils.HttpLog;
9 |
10 | import java.io.IOException;
11 |
12 | import okhttp3.Interceptor;
13 | import okhttp3.Response;
14 |
15 | /**
16 | * 描述:设置缓存功能
17 | */
18 | public class CacheInterceptor implements Interceptor {
19 |
20 | protected Context context;
21 | protected String cacheControlValue_Offline;
22 | protected String cacheControlValue_Online;
23 | //set cahe times is 3 days
24 | protected static final int maxStale = 60 * 60 * 24 * 3;
25 | // read from cache for 60 s
26 | protected static final int maxStaleOnline = 60;
27 |
28 | public CacheInterceptor(Context context) {
29 | this(context, String.format("max-age=%d", maxStaleOnline));
30 | }
31 |
32 | public CacheInterceptor(Context context, String cacheControlValue) {
33 | this(context, cacheControlValue, String.format("max-age=%d", maxStale));
34 | }
35 |
36 | public CacheInterceptor(Context context, String cacheControlValueOffline, String cacheControlValueOnline) {
37 | this.context = context;
38 | this.cacheControlValue_Offline = cacheControlValueOffline;
39 | this.cacheControlValue_Online = cacheControlValueOnline;
40 | }
41 |
42 | @Override
43 | public Response intercept(Chain chain) throws IOException {
44 | //Request request = chain.request();
45 | Response originalResponse = chain.proceed(chain.request());
46 | String cacheControl = originalResponse.header("Cache-Control");
47 | //String cacheControl = request.cacheControl().toString();
48 | HttpLog.e( maxStaleOnline + "s load cache:" + cacheControl);
49 | if (TextUtils.isEmpty(cacheControl) || cacheControl.contains("no-store") || cacheControl.contains("no-cache") ||
50 | cacheControl.contains("must-revalidate") || cacheControl.contains("max-age") || cacheControl.contains("max-stale")) {
51 | return originalResponse.newBuilder()
52 | .removeHeader("Pragma")
53 | .removeHeader("Cache-Control")
54 | .header("Cache-Control", "public, max-age=" + maxStale)
55 | .build();
56 |
57 | } else {
58 | return originalResponse;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/wnlibrary/src/main/java/com/wls/wnlibrary/utils/net/JsonJieXi.java:
--------------------------------------------------------------------------------
1 | package com.wls.wnlibrary.utils.net;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.reflect.TypeToken;
5 |
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | public class JsonJieXi {
10 | private static Gson gson = null;
11 |
12 | static {
13 | if (gson == null) {
14 | gson = new Gson();
15 | }
16 | }
17 |
18 | private JsonJieXi() {
19 | }
20 |
21 | /**
22 | * 转成json
23 | *
24 | * @param object
25 | * @return
26 | */
27 | public static String GsonString(Object object) {
28 | String gsonString = null;
29 | if (gson != null) {
30 | gsonString = gson.toJson(object);
31 | }
32 | return gsonString;
33 | }
34 |
35 | /**
36 | * 转成bean
37 | *
38 | * @param gsonString
39 | * @param cls
40 | * @return
41 | */
42 | public static T GsonToBean(String gsonString, Class cls) {
43 | T t = null;
44 | if (gson != null) {
45 | t = gson.fromJson(gsonString, cls);
46 | }
47 | return t;
48 | }
49 |
50 | /**
51 | * 转成list
52 | *
53 | * @param gsonString
54 | * @param cls
55 | * @return
56 | */
57 | public static List GsonToList(String gsonString, Class cls) {
58 | List list = null;
59 | if (gson != null) {
60 | list = gson.fromJson(gsonString, new TypeToken>() {
61 | }.getType());
62 | }
63 | return list;
64 | }
65 |
66 | /**
67 | * 转成list中有map的
68 | *
69 | * @param gsonString
70 | * @return
71 | */
72 | public static List