?) : Interceptor {
8 | @Throws(IOException::class)
9 | override fun intercept(chain: Interceptor.Chain): Response {
10 | val builder = chain.request()
11 | .newBuilder()
12 | if (headers != null && headers.isNotEmpty()) {
13 | val keys = headers.keys
14 | for (headerKey in keys) {
15 | builder.addHeader(headerKey, headers[headerKey]).build()
16 | }
17 | }
18 | //请求信息
19 | return chain.proceed(builder.build())
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/http/interceptor/CacheInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.http.interceptor
2 |
3 | import android.content.Context
4 | import com.wzq.mvvmsmart.http.NetworkUtil
5 | import okhttp3.CacheControl
6 | import okhttp3.Interceptor
7 | import okhttp3.Response
8 | import java.io.IOException
9 |
10 | /**
11 | * 无网络状态下智能读取缓存的拦截器
12 | */
13 | class CacheInterceptor(private val context: Context) : Interceptor {
14 | @Throws(IOException::class)
15 | override fun intercept(chain: Interceptor.Chain): Response {
16 | var request = chain.request()
17 | return if (NetworkUtil.isNetworkAvailable(context)) {
18 | val response = chain.proceed(request)
19 | // read from cache for 60 s
20 | val maxAge = 60
21 | response.newBuilder()
22 | .removeHeader("Pragma")
23 | .removeHeader("Cache-Control")
24 | .header("Cache-Control", "public, max-age=$maxAge")
25 | .build()
26 | } else {
27 | //读取缓存信息
28 | request = request.newBuilder()
29 | .cacheControl(CacheControl.FORCE_CACHE)
30 | .build()
31 | val response = chain.proceed(request)
32 | //set cache times is 3 days
33 | val maxStale = 60 * 60 * 24 * 3
34 | response.newBuilder()
35 | .removeHeader("Pragma")
36 | .removeHeader("Cache-Control")
37 | .header("Cache-Control", "public, only-if-cached, max-stale=$maxStale")
38 | .build()
39 | }
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/http/interceptor/ProgressInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.http.interceptor
2 |
3 | import com.wzq.mvvmsmart.http.download.ProgressResponseBody
4 | import okhttp3.Interceptor
5 | import okhttp3.Response
6 | import java.io.IOException
7 |
8 | class ProgressInterceptor : Interceptor {
9 | @Throws(IOException::class)
10 | override fun intercept(chain: Interceptor.Chain): Response {
11 | val originalResponse = chain.proceed(chain.request())
12 | return originalResponse.newBuilder()
13 | .body(ProgressResponseBody(originalResponse.body()))
14 | .build()
15 | }
16 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/http/interceptor/logging/I.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.http.interceptor.logging
2 |
3 | import okhttp3.internal.platform.Platform
4 | import java.util.logging.Level
5 | import java.util.logging.Logger
6 |
7 | /**
8 | * @author ihsan on 10/02/2017.
9 | */
10 | internal class I protected constructor() {
11 | companion object {
12 | fun log(type: Int, tag: String?, msg: String?) {
13 | val logger = Logger.getLogger(tag)
14 | when (type) {
15 | Platform.INFO -> logger.log(Level.INFO, msg)
16 | else -> logger.log(Level.WARNING, msg)
17 | }
18 | }
19 | }
20 |
21 | init {
22 | throw UnsupportedOperationException()
23 | }
24 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/http/interceptor/logging/Level.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.http.interceptor.logging
2 |
3 | /**
4 | * @author ihsan on 21/02/2017.
5 | */
6 | enum class Level {
7 | /**
8 | * No logs.
9 | */
10 | NONE,
11 |
12 | /**
13 | *
14 | * Example:
15 | * `- URL
16 | * - Method
17 | * - Headers
18 | * - Body
19 | `
*
20 | */
21 | BASIC,
22 |
23 | /**
24 | *
25 | * Example:
26 | * `- URL
27 | * - Method
28 | * - Headers
29 | `
*
30 | */
31 | HEADERS,
32 |
33 | /**
34 | *
35 | * Example:
36 | * `- URL
37 | * - Method
38 | * - Body
39 | `
*
40 | */
41 | BODY
42 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/http/interceptor/logging/Logger.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.http.interceptor.logging
2 |
3 | import okhttp3.internal.platform.Platform
4 |
5 | /**
6 | * @author ihsan on 11/07/2017.
7 | */
8 | interface Logger {
9 | fun log(level: Int, tag: String?, msg: String?)
10 |
11 | companion object {
12 | val DEFAULT: Logger = object : Logger {
13 | override fun log(level: Int, tag: String?, message: String?) {
14 | Platform.get().log(level, message, null)
15 | }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/utils/CloseUtils.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.utils
2 |
3 | import java.io.Closeable
4 | import java.io.IOException
5 |
6 | /**
7 | * 关闭相关工具类
8 | */
9 | class CloseUtils private constructor() {
10 | companion object {
11 | /**
12 | * 关闭IO
13 | *
14 | * @param closeables closeables
15 | */
16 | fun closeIO(vararg closeables: Closeable?) {
17 | if (closeables == null) return
18 | for (closeable in closeables) {
19 | if (closeable != null) {
20 | try {
21 | closeable.close()
22 | } catch (e: IOException) {
23 | e.printStackTrace()
24 | }
25 | }
26 | }
27 | }
28 |
29 | /**
30 | * 安静关闭IO
31 | *
32 | * @param closeables closeables
33 | */
34 | fun closeIOQuietly(vararg closeables: Closeable?) {
35 | if (closeables == null) return
36 | for (closeable in closeables) {
37 | if (closeable != null) {
38 | try {
39 | closeable.close()
40 | } catch (ignored: IOException) {
41 | }
42 | }
43 | }
44 | }
45 | }
46 |
47 | init {
48 | throw UnsupportedOperationException("u can't instantiate me...")
49 | }
50 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/utils/RxUtils.java:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.utils;
2 |
3 | import com.wzq.mvvmsmart.http.BaseResponse;
4 | import com.wzq.mvvmsmart.http.ExceptionHandle;
5 |
6 | import io.reactivex.Observable;
7 | import io.reactivex.ObservableTransformer;
8 | import io.reactivex.android.schedulers.AndroidSchedulers;
9 | import io.reactivex.functions.Function;
10 | import io.reactivex.schedulers.Schedulers;
11 |
12 |
13 | /**
14 | * 有关Rx的工具类
15 | */
16 | public class RxUtils {
17 |
18 | /**
19 | * 线程调度器
20 | */
21 |
22 | public static ObservableTransformer observableToMain() {
23 | return upstream -> upstream.subscribeOn(Schedulers.io())
24 | .observeOn(AndroidSchedulers.mainThread());
25 | }
26 |
27 | public static ObservableTransformer observableBothToIo() {
28 | return upstream -> upstream.subscribeOn(Schedulers.io())
29 | .observeOn(Schedulers.io());
30 | }
31 |
32 | public static ObservableTransformer exceptionTransformer() {
33 | return observable -> observable
34 | // .map(new HandleFuc()) //这里可以取出BaseResponse中的Result
35 | .onErrorResumeNext(new HttpResponseFunc());
36 | }
37 |
38 | private static class HttpResponseFunc implements Function> {
39 | @Override
40 | public Observable apply(Throwable t) {
41 | return Observable.error(ExceptionHandle.handleException(t));
42 | }
43 | }
44 |
45 | private static class HandleFuc implements Function, T> {
46 | @Override
47 | public T apply(BaseResponse response) {
48 | if (!response.isOk())
49 | throw new RuntimeException(!"".equals(response.getCode() + "" + response.getMessage()) ? response.getMessage() : "");
50 | return response.getResult();
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/utils/Tasks.java:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.utils;
2 |
3 | import android.os.Handler;
4 | import android.os.HandlerThread;
5 | import android.os.Looper;
6 |
7 | /**
8 | * 一些任务:需要运行在进程的UI主线程,或者运行在进程的HandlerThread
9 | */
10 | public final class Tasks {
11 |
12 | private static Handler sMainHandler;
13 |
14 | private static final Object sLock = new Object();
15 |
16 | private static Handler sThreadHandler;
17 |
18 |
19 | public static boolean post2UI(Runnable r) {
20 | return sMainHandler.post(r);
21 | }
22 |
23 |
24 | public static boolean postDelayed2UI(Runnable r, long delayMillis) {
25 | return sMainHandler.postDelayed(r, delayMillis);
26 | }
27 |
28 | /**
29 | * 取消UI线程任务
30 | */
31 | public static void cancelTask(Runnable r) {
32 | initThread();
33 | sMainHandler.removeCallbacks(r);
34 | }
35 |
36 |
37 | public static boolean post2Thread(Runnable r) {
38 | initThread();
39 | return sThreadHandler.post(r);
40 | }
41 |
42 |
43 | public static boolean postDelayed2Thread(Runnable r, long delayMillis) {
44 | initThread();
45 | return sThreadHandler.postDelayed(r, delayMillis);
46 | }
47 |
48 | /**
49 | * 取消后台线程任务
50 | */
51 | public static void cancelThreadTask(Runnable r) {
52 | initThread();
53 | sThreadHandler.removeCallbacks(r);
54 | }
55 |
56 | /**
57 | * 内部接口
58 | */
59 | public static void init() {
60 | sMainHandler = new Handler(Looper.getMainLooper());
61 | }
62 |
63 | private static void initThread() {
64 | synchronized (sLock) {
65 | if (sThreadHandler == null) {
66 | HandlerThread handlerThread = new HandlerThread("daemon-handler-thread");
67 | handlerThread.start();
68 | sThreadHandler = new Handler(handlerThread.getLooper());
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/utils/Utils.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.utils
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 |
6 | /**
7 | * 常用工具类
8 | */
9 | class Utils private constructor() {
10 | companion object {
11 | @SuppressLint("StaticFieldLeak")
12 | private var context: Context? = null
13 |
14 | /**
15 | * 初始化工具类
16 | *
17 | * @param context 上下文
18 | */
19 | fun init(context: Context) {
20 | Companion.context = context.applicationContext
21 | }
22 |
23 | /**
24 | * 获取ApplicationContext
25 | *
26 | * @return ApplicationContext
27 | */
28 | fun getContext(): Context? {
29 | if (context != null) {
30 | return context
31 | }
32 | throw NullPointerException("should be initialized in application")
33 | }
34 | }
35 |
36 | init {
37 | throw UnsupportedOperationException("u can't instantiate me...")
38 | }
39 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/utils/constant/MemoryConstants.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.utils.constant
2 |
3 | import androidx.annotation.IntDef
4 |
5 | /**
6 | * 存储相关常量
7 | */
8 | object MemoryConstants {
9 | /**
10 | * Byte与Byte的倍数
11 | */
12 | const val BYTE = 1
13 |
14 | /**
15 | * KB与Byte的倍数
16 | */
17 | const val KB = 1024
18 |
19 | /**
20 | * MB与Byte的倍数
21 | */
22 | const val MB = 1048576
23 |
24 | /**
25 | * GB与Byte的倍数
26 | */
27 | const val GB = 1073741824
28 |
29 | @IntDef(BYTE, KB, MB, GB)
30 | @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
31 | annotation class Unit
32 | }
--------------------------------------------------------------------------------
/mvvmsmart/src/main/java/com/wzq/mvvmsmart/utils/constant/RegexConstants.kt:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart.utils.constant
2 |
3 | /**
4 | * 正则相关常量
5 | */
6 | object RegexConstants {
7 | /**
8 | * 正则:手机号(简单)
9 | */
10 | const val REGEX_MOBILE_SIMPLE = "^[1]\\d{10}$"
11 |
12 | /**
13 | * 正则:手机号(精确)
14 | *
15 | * 移动:134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188
16 | *
17 | * 联通:130、131、132、145、155、156、175、176、185、186
18 | *
19 | * 电信:133、153、173、177、180、181、189
20 | *
21 | * 全球星:1349
22 | *
23 | * 虚拟运营商:170
24 | */
25 | const val REGEX_MOBILE_EXACT = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|(147))\\d{8}$"
26 |
27 | /**
28 | * 正则:电话号码
29 | */
30 | const val REGEX_TEL = "^0\\d{2,3}[- ]?\\d{7,8}"
31 |
32 | /**
33 | * 正则:身份证号码15位
34 | */
35 | const val REGEX_ID_CARD15 = "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$"
36 |
37 | /**
38 | * 正则:身份证号码18位
39 | */
40 | const val REGEX_ID_CARD18 = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9Xx])$"
41 |
42 | /**
43 | * 正则:邮箱
44 | */
45 | const val REGEX_EMAIL = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"
46 |
47 | /**
48 | * 正则:URL
49 | */
50 | const val REGEX_URL = "[a-zA-z]+://[^\\s]*"
51 |
52 | /**
53 | * 正则:汉字
54 | */
55 | const val REGEX_ZH = "^[\\u4e00-\\u9fa5]+$"
56 |
57 | /**
58 | * 正则:用户名,取值范围为a-z,A-Z,0-9,"_",汉字,不能以"_"结尾,用户名必须是6-20位
59 | */
60 | const val REGEX_USERNAME = "^[\\w\\u4e00-\\u9fa5]{6,20}(?
2 |
11 |
12 |
18 |
19 |
27 |
28 |
39 |
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/mipmap-hdpi/ic_launcher_mvvmsmart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wzqjava/MVVMSmart-kotlin/95bf5e2ab434147b9f6c58e966e3bf1b85297b0a/mvvmsmart/src/main/res/mipmap-hdpi/ic_launcher_mvvmsmart.png
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/mipmap-mdpi/ic_launcher_mvvmsmart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wzqjava/MVVMSmart-kotlin/95bf5e2ab434147b9f6c58e966e3bf1b85297b0a/mvvmsmart/src/main/res/mipmap-mdpi/ic_launcher_mvvmsmart.png
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/mipmap-xhdpi/ic_launcher_mvvmsmart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wzqjava/MVVMSmart-kotlin/95bf5e2ab434147b9f6c58e966e3bf1b85297b0a/mvvmsmart/src/main/res/mipmap-xhdpi/ic_launcher_mvvmsmart.png
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/mipmap-xxhdpi/ic_launcher_mvvmsmart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wzqjava/MVVMSmart-kotlin/95bf5e2ab434147b9f6c58e966e3bf1b85297b0a/mvvmsmart/src/main/res/mipmap-xxhdpi/ic_launcher_mvvmsmart.png
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/mipmap-xxxhdpi/ic_launcher_mvvmsmart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wzqjava/MVVMSmart-kotlin/95bf5e2ab434147b9f6c58e966e3bf1b85297b0a/mvvmsmart/src/main/res/mipmap-xxxhdpi/ic_launcher_mvvmsmart.png
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | mvvmsmart
4 | 我是图片
5 | 关闭程序
6 | 错误日志
7 | 错误信息
8 | 日志已复制
9 | 复制日志
10 | 错误详情
11 | 发生意外错误。
12 | 重新启动
13 | 关闭
14 |
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
5 |
6 |
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 | 12sp
7 |
8 |
--------------------------------------------------------------------------------
/mvvmsmart/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | mvvmsmart
3 | I am Image
4 | Close App
5 | Error log
6 | Error message
7 | shut down
8 | Logs copied
9 | Copy log
10 | Error details
11 | An unexpected error occurred.
12 | Restart
13 |
14 |
--------------------------------------------------------------------------------
/mvvmsmart/src/test/java/com/wzq/mvvmsmart/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.wzq.mvvmsmart;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':mvvmsmart'
2 |
--------------------------------------------------------------------------------
/todo:
--------------------------------------------------------------------------------
1 | diff条目实现
2 | 重复点击功能 https://github.com/zhujiang521/AndroidAOP // android-aspectjx,https://juejin.im/post/5ea66d64f265da480836d2b2?utm_source=gold_browser_extension
3 | 网络框架优化
4 | HttpDataSourceImpl
5 | TokenInterceptor
6 | gson解析,字段少了问题
7 | HttpDisposableObserver Disposable
8 | BaseObserver和HttpDisposableObserver 考虑合并处理
9 | DADA_ENVIRONMENT 封装为常量的来龙去脉
10 |
11 |
12 |
15 |
16 | test
17 |
18 |
19 |
--------------------------------------------------------------------------------
/wzq.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wzqjava/MVVMSmart-kotlin/95bf5e2ab434147b9f6c58e966e3bf1b85297b0a/wzq.jks
--------------------------------------------------------------------------------