├── .gitignore
├── .idea
├── .gitignore
├── compiler.xml
├── deploymentTargetSelector.xml
├── gradle.xml
├── kotlinc.xml
├── migrations.xml
├── misc.xml
└── vcs.xml
├── LICENSE
├── NetworkApiData
├── build.gradle
├── libs
│ └── annotations.jar
└── src
│ └── main
│ └── java
│ └── com
│ └── wx
│ └── test
│ └── api
│ ├── data
│ ├── BaiDuImageResponse.kt
│ ├── BaiduDataBean.kt
│ ├── BaseResponse.kt
│ └── wanandroid
│ │ ├── CommonResult.kt
│ │ └── home
│ │ ├── HomeData.kt
│ │ ├── HomeItemBean.kt
│ │ └── WanAndroidHome.kt
│ ├── net
│ └── NetApi.kt
│ └── retrofit
│ ├── HeaderInterceptor.kt
│ ├── RequestBodyCreate.kt
│ ├── RequestBodyWrapper.kt
│ └── RetrofitUtils.kt
├── README.md
├── annotation_compiler
├── .gitignore
├── build.gradle
├── libs
│ └── javax.inject-1.jar
└── src
│ └── main
│ └── java
│ └── com
│ └── annotation_compiler
│ ├── AnnotationsCompiler.java
│ └── AptProcessor.kt
├── app_wx1
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── wx
│ │ └── architecture
│ │ ├── MyApp.kt
│ │ ├── code
│ │ ├── app
│ │ │ └── AppGlobals.kt
│ │ ├── base
│ │ │ ├── BaseFragment.kt
│ │ │ ├── BaseViewModel.kt
│ │ │ └── BaseViewModelActivity.kt
│ │ ├── data
│ │ │ └── DialogBean.kt
│ │ ├── dialog
│ │ │ └── ShowUIDialog.kt
│ │ ├── ex
│ │ │ ├── ExceptionEX.kt
│ │ │ ├── Flow.kt
│ │ │ └── Throwable.kt
│ │ └── utils
│ │ │ └── NetWorkHelp.kt
│ │ ├── data_source
│ │ ├── repository
│ │ │ └── NetRepository.kt
│ │ └── tata.kt
│ │ └── ui
│ │ ├── activity
│ │ └── MainActivity.kt
│ │ └── viewmodel
│ │ └── MainViewModel.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable-xhdpi
│ └── ic_loading.webp
│ ├── drawable
│ ├── ic_launcher_background.xml
│ └── progressbar_shape.xml
│ ├── layout
│ ├── activity_main.xml
│ └── layout_loading.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values-night
│ └── themes.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── app_wx2
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── wx
│ │ └── architecture
│ │ ├── MyApp.kt
│ │ ├── code
│ │ ├── app
│ │ │ └── AppGlobals.kt
│ │ ├── base
│ │ │ ├── BaseFragment.kt
│ │ │ ├── BaseViewModel.kt
│ │ │ └── BaseViewModelActivity.kt
│ │ ├── data
│ │ │ └── DialogBean.kt
│ │ ├── dialog
│ │ │ └── ShowUIDialog.kt
│ │ ├── ex
│ │ │ ├── ExceptionEX.kt
│ │ │ ├── Flow.kt
│ │ │ └── Throwable.kt
│ │ └── utils
│ │ │ └── NetWorkHelp.kt
│ │ ├── data_source
│ │ ├── kapt
│ │ │ └── KaptComponet.kt
│ │ ├── repository
│ │ │ └── BaseRepository.kt
│ │ └── tata.kt
│ │ └── ui
│ │ ├── activity
│ │ └── MainActivity.kt
│ │ └── viewmodel
│ │ └── MainViewModel.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable-xhdpi
│ └── ic_loading.webp
│ ├── drawable
│ ├── ic_launcher_background.xml
│ └── progressbar_shape.xml
│ ├── layout
│ ├── activity_main.xml
│ └── layout_loading.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values-night
│ └── themes.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── app_wx3
├── .gitignore
├── build.gradle
├── libs
│ ├── annotation_compiler.jar
│ └── annotations.jar
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── wx
│ │ └── architecture
│ │ ├── MyApp.kt
│ │ ├── code
│ │ ├── app
│ │ │ └── AppGlobals.kt
│ │ ├── base
│ │ │ ├── BaseFragment.kt
│ │ │ ├── BaseRepositoryProxy.kt
│ │ │ ├── BaseViewModel.kt
│ │ │ └── BaseViewModelActivity.kt
│ │ ├── data
│ │ │ └── DialogBean.kt
│ │ ├── dialog
│ │ │ └── ShowUIDialog.kt
│ │ ├── ex
│ │ │ ├── ExceptionEX.kt
│ │ │ ├── Flow.kt
│ │ │ └── Throwable.kt
│ │ └── utils
│ │ │ └── NetWorkHelp.kt
│ │ ├── data_source
│ │ ├── kapt
│ │ │ └── KaptInterface.kt
│ │ ├── repository
│ │ │ └── RepositoryPoxy.kt
│ │ └── tata.kt
│ │ └── ui
│ │ ├── activity
│ │ └── MainActivity.kt
│ │ └── viewmodel
│ │ └── MainViewModel.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable-xhdpi
│ └── ic_loading.webp
│ ├── drawable
│ ├── ic_launcher_background.xml
│ └── progressbar_shape.xml
│ ├── layout
│ ├── activity_main.xml
│ └── layout_loading.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values-night
│ └── themes.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── app_wx4
├── .gitignore
├── build.gradle
├── libs
│ ├── annotation_compiler.jar
│ └── annotations.jar
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── wx
│ │ └── architecture
│ │ ├── MyApp.kt
│ │ ├── code
│ │ ├── app
│ │ │ └── AppGlobals.kt
│ │ ├── base
│ │ │ ├── BaseFragment.kt
│ │ │ ├── BaseRepositoryProxy.kt
│ │ │ ├── BaseViewModel.kt
│ │ │ └── BaseViewModelActivity.kt
│ │ ├── data
│ │ │ └── DialogBean.kt
│ │ ├── dialog
│ │ │ └── ShowUIDialog.kt
│ │ ├── ex
│ │ │ ├── ExceptionEX.kt
│ │ │ ├── Flow.kt
│ │ │ └── Throwable.kt
│ │ └── utils
│ │ │ └── NetWorkHelp.kt
│ │ ├── data_source
│ │ ├── repository
│ │ │ └── RepositoryPoxy.kt
│ │ └── tata.kt
│ │ └── ui
│ │ ├── activity
│ │ └── MainActivity.kt
│ │ └── viewmodel
│ │ └── MainViewModel.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable-xhdpi
│ └── ic_loading.webp
│ ├── drawable
│ ├── ic_launcher_background.xml
│ └── progressbar_shape.xml
│ ├── layout
│ ├── activity_main.xml
│ └── layout_loading.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values-night
│ └── themes.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── app_wx_switch_net
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── wx
│ │ └── architecture
│ │ ├── MyApp.kt
│ │ ├── code
│ │ ├── app
│ │ │ └── AppGlobals.kt
│ │ ├── base
│ │ │ ├── BaseFragment.kt
│ │ │ ├── BaseViewModel.kt
│ │ │ └── BaseViewModelActivity.kt
│ │ ├── data
│ │ │ └── DialogBean.kt
│ │ ├── dialog
│ │ │ └── ShowUIDialog.kt
│ │ ├── ex
│ │ │ ├── ExceptionEX.kt
│ │ │ ├── Flow.kt
│ │ │ └── Throwable.kt
│ │ └── utils
│ │ │ ├── BuildParamUtils.kt
│ │ │ ├── NetWorkHelp.kt
│ │ │ └── RequestBodyCreate.kt
│ │ ├── data_source
│ │ ├── data
│ │ │ ├── CommonResult.kt
│ │ │ ├── HomeData.kt
│ │ │ ├── HomeItemBean.kt
│ │ │ └── WanAndroidHome.kt
│ │ ├── dl_hilt
│ │ │ ├── AbstractHttp.kt
│ │ │ └── annotation
│ │ │ │ ├── BindHttpUrlConnection.kt
│ │ │ │ └── BindOkhttp.kt
│ │ ├── net
│ │ │ ├── HttpUrlConnectionImpl.kt
│ │ │ ├── INetApi.kt
│ │ │ ├── OkhttpImpl.kt
│ │ │ └── http
│ │ │ │ ├── HttpURLConnectionUtils.kt
│ │ │ │ └── HttpUrlConnectionRequest.kt
│ │ ├── repository
│ │ │ └── NetRepository.kt
│ │ └── tata.kt
│ │ └── ui
│ │ ├── activity
│ │ └── MainActivity.kt
│ │ └── viewmodel
│ │ └── MainViewModel.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable-xhdpi
│ └── ic_loading.webp
│ ├── drawable
│ ├── ic_launcher_background.xml
│ └── progressbar_shape.xml
│ ├── layout
│ ├── activity_main.xml
│ └── layout_loading.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-mdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.webp
│ └── ic_launcher_round.webp
│ ├── values-night
│ └── themes.xml
│ ├── values
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── backup_rules.xml
│ └── data_extraction_rules.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
17 | # Project exclude paths
18 | /NetworkApiData/build/
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetSelector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
26 |
27 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/NetworkApiData/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java-library'
3 | id 'kotlin'
4 | }
5 |
6 | java {
7 | sourceCompatibility = JavaVersion.VERSION_1_8
8 | targetCompatibility = JavaVersion.VERSION_1_8
9 | }
10 |
11 |
12 | dependencies {
13 |
14 | api fileTree(dir: 'libs', include: ['*.jar'])
15 |
16 | implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.0"
17 |
18 | //网络层 retrofit okhttp 相关 start
19 | api 'com.squareup.retrofit2:retrofit:2.9.0'
20 | api 'com.squareup.retrofit2:retrofit:2.9.0'
21 | api 'com.squareup.retrofit2:converter-scalars:2.9.0'
22 | api 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
23 | api 'com.squareup.okhttp3:logging-interceptor:4.0.0'
24 | api 'com.squareup.retrofit2:converter-gson:2.9.0'
25 | api 'com.squareup.retrofit2:converter-scalars:2.1.0'
26 | //网络层 retrofit okhttp 相关 end
27 |
28 | // api project(path: ':annotations')
29 | }
--------------------------------------------------------------------------------
/NetworkApiData/libs/annotations.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/NetworkApiData/libs/annotations.jar
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/data/BaiDuImageResponse.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.data
2 |
3 | import java.util.ArrayList
4 |
5 | class BaiDuImageResponse() {
6 | var gsm:String?=null
7 | var data: ArrayList?=null
8 | }
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/data/BaiduDataBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.data
2 |
3 | data class BaiduDataBean(var adType: Int, var thumbURL: String, var middleURL: String)
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/data/BaseResponse.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.data
2 |
3 | //data class BaseResponse(val code :Int,var errorMsg:String,var t:T) {
4 | data class BaseResponse(var gsm: String, var data: T)
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/data/wanandroid/CommonResult.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.data.wanandroid
2 |
3 | open class CommonResult {
4 | var data: T? = null
5 | var errorCode: Int? = 0
6 | var errorMsg: String? = null
7 | }
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/data/wanandroid/home/HomeData.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.data.wanandroid.home
2 |
3 | import com.wx.test.api.data.wanandroid.CommonResult
4 |
5 | class HomeData : CommonResult() {
6 | }
7 |
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/data/wanandroid/home/HomeItemBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.data.wanandroid.home
2 |
3 | data class HomeItemBean(
4 | val author:String,
5 | val chapterName:String,
6 | val link:String,
7 | val title:String
8 | )
9 |
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/data/wanandroid/home/WanAndroidHome.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.data.wanandroid.home
2 |
3 | data class WanAndroidHome(
4 | val datas: MutableList,
5 | val curPage: Int,
6 | val size: Int,
7 | val total: Int
8 | )
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/retrofit/HeaderInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.retrofit
2 |
3 | import okhttp3.Interceptor
4 | import okhttp3.Request
5 | import okhttp3.Response
6 | import java.io.IOException
7 |
8 | class HeaderInterceptor : Interceptor {
9 |
10 | @Throws(IOException::class)
11 | override fun intercept(chain: Interceptor.Chain): Response {
12 | val request: Request = chain.request()
13 | val authorised = request
14 | .newBuilder()
15 | .addHeader("Connection", "keep-alive") //
16 | .addHeader("Accept-Language", "zh-CN,zh;q=0.9") //
17 | .addHeader(
18 | "Authorization",
19 | "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjaGFudElkIjo1OTIsInVzZXJfbmFtZSI6IjE4OTgyOTkwNzAyIiwib3BlbmlkIjpudWxsLCJzY29wZSI6WyJhbGwiXSwiaWQiOjY5MSwiY2xpZW50X3NvdXJjZSI6bnVsbCwiZXhwIjoxNzI2MjIzNzYyLCJhdXRob3JpdGllcyI6WyJyYmFjXzEzX-aXoOS6uuWUruWNluWVhuWutiJdLCJqdGkiOiJmYmVhMGRlZi01MjNmLTRkYTctYjY3Yy1lMjljZjJkYmU1YzUiLCJjbGllbnRfaWQiOiJjdXN0b21lci1hcHAiLCJyZWFsbmFtZSI6bnVsbH0.f4QtuwWdj096Dzp2o4aVyEnDof3-7gR7NX-LX-j8KbBmXwdYtKG32AvRKxY5t5ubwhTqe0IHkobZZqTcub4bnd8DdmSUJa0Q8UQP1EgMWuUubSuojHifOctNzZFlc74v28NUbzlhslmQNzHL5f7zxjP7zVdMfKvGD9eSjeHlG8w"
20 | ) //
21 | .addHeader("Accept", "application/json, text/javascript, */*") //
22 | // .addHeader("Referer", " https://wwz.lanzouj.com/ihT5x20ulecf") //https
23 | // .addHeader("Upgrade-insecure-Requests", "1") //
24 | // .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36") //
25 | // if (request.header("User-Agent") == null) {
26 | authorised.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36") //
27 | // }
28 | return chain.proceed(authorised.build())
29 | // return chain.proceed(authorised.build())
30 | }
31 | }
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/retrofit/RequestBodyCreate.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.retrofit
2 |
3 | import okhttp3.MediaType.Companion.toMediaTypeOrNull
4 | import okhttp3.RequestBody
5 |
6 | object RequestBodyCreate {
7 |
8 | fun toBody(body: String) = RequestBody.create("application/json; charset=utf-8".toMediaTypeOrNull(), body)
9 | }
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/retrofit/RequestBodyWrapper.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.retrofit
2 |
3 | import okhttp3.MediaType
4 | import okhttp3.MediaType.Companion.toMediaTypeOrNull
5 | import okhttp3.RequestBody
6 | import okio.BufferedSink
7 |
8 | class RequestBodyWrapper constructor(val postBody: String) : RequestBody() {
9 |
10 | override fun contentType(): MediaType? {
11 | return "application/json; charset=utf-8".toMediaTypeOrNull()
12 | }
13 |
14 | override fun writeTo(sink: BufferedSink) {
15 | sink.write(postBody.toByteArray(), 0, postBody.toByteArray().size)
16 | }
17 | }
--------------------------------------------------------------------------------
/NetworkApiData/src/main/java/com/wx/test/api/retrofit/RetrofitUtils.kt:
--------------------------------------------------------------------------------
1 | package com.wx.test.api.retrofit
2 |
3 | import okhttp3.OkHttpClient
4 | import okhttp3.logging.HttpLoggingInterceptor
5 | import retrofit2.Retrofit
6 | import retrofit2.converter.gson.GsonConverterFactory
7 | import retrofit2.converter.scalars.ScalarsConverterFactory
8 | import java.util.concurrent.TimeUnit
9 |
10 | class RetrofitUtils private constructor() {
11 | val baseUrl = "https://www.wanandroid.com/"
12 |
13 | companion object {
14 | val instance by lazy { RetrofitUtils() }
15 | }
16 |
17 | private inline val retrofit: Retrofit
18 | get() {
19 | val logging = HttpLoggingInterceptor()
20 | val timeout = 30000L
21 | val okHttpClient = OkHttpClient.Builder()
22 | .addInterceptor(HeaderInterceptor())
23 | .addInterceptor(logging)
24 | // .addInterceptor(RetrofitClient.BaseUrlInterceptor())
25 | .callTimeout(timeout, TimeUnit.MILLISECONDS)
26 | //设置连接超时
27 | .connectTimeout(timeout, TimeUnit.MILLISECONDS)
28 | //设置从主机读信息超时
29 | .readTimeout(timeout, TimeUnit.MILLISECONDS)
30 | //设置写信息超时
31 | .writeTimeout(timeout, TimeUnit.MILLISECONDS)
32 | .retryOnConnectionFailure(true)//设置出现错误进行重新连接。
33 | .build();
34 | return Retrofit.Builder()
35 | .client(okHttpClient)
36 | .addConverterFactory(ScalarsConverterFactory.create())
37 | .addConverterFactory(GsonConverterFactory.create())
38 | .baseUrl(baseUrl)
39 | .build()
40 | }
41 |
42 | fun create(service: Class?): T {
43 | if (service == null) {
44 | throw RuntimeException("Api service is null!")
45 | }
46 | return retrofit.create(service)!!
47 | }
48 | }
--------------------------------------------------------------------------------
/annotation_compiler/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/annotation_compiler/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | id 'java-library'
4 | id 'kotlin'
5 | id 'kotlin-kapt'
6 | }
7 |
8 |
9 | dependencies {
10 | implementation fileTree(dir: 'libs', include: ['*.jar'])
11 | implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.0"
12 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
13 | // annotationProcessor 'com.google.auto.service:auto-service:1.0-rc4' java 用法
14 | // implementation 'com.google.auto.service:auto-service:1.0-rc4' java 用法
15 |
16 | implementation "com.google.auto.service:auto-service:1.0-rc4" // kotlin 用法
17 | kapt "com.google.auto.service:auto-service:1.0" // kotlin 用法
18 | implementation "com.squareup:kotlinpoet:1.8.0"
19 | implementation 'com.squareup.retrofit2:retrofit:2.9.0'
20 |
21 | // implementation project(path: ':annotations')
22 | implementation project(path: ':NetworkApiData')
23 | }
24 | java {
25 | sourceCompatibility = JavaVersion.VERSION_1_8
26 | targetCompatibility = JavaVersion.VERSION_1_8
27 | }
--------------------------------------------------------------------------------
/annotation_compiler/libs/javax.inject-1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/annotation_compiler/libs/javax.inject-1.jar
--------------------------------------------------------------------------------
/app_wx1/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app_wx1/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | }
5 |
6 | android {
7 | compileSdk 32
8 |
9 | defaultConfig {
10 | applicationId "com.wx.wxnetarchitecture"
11 | minSdk 21
12 | targetSdk 32
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | // testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | compileOptions {
26 | sourceCompatibility JavaVersion.VERSION_1_8
27 | targetCompatibility JavaVersion.VERSION_1_8
28 | }
29 | kotlinOptions {
30 | jvmTarget = '1.8'
31 | }
32 | }
33 |
34 | dependencies {
35 |
36 | implementation 'androidx.core:core-ktx:1.7.0'
37 | implementation 'androidx.appcompat:appcompat:1.3.0'
38 | implementation 'com.google.android.material:material:1.4.0'
39 |
40 | implementation 'com.squareup.retrofit2:retrofit:2.9.0'
41 | implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
42 | implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
43 | implementation 'com.squareup.okhttp3:okhttp:4.9.3'
44 | implementation 'com.squareup.okio:okio:2.10.0'
45 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
46 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
47 |
48 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
49 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
50 | implementation 'androidx.activity:activity-ktx:1.3.0-rc01'
51 | implementation 'androidx.fragment:fragment-ktx:1.4.0-alpha04'
52 |
53 | implementation project(path: ':NetworkApiData')
54 |
55 | // testImplementation 'junit:junit:4.13.2'
56 | // androidTestImplementation 'androidx.test.ext:junit:1.1.3'
57 | // androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
58 | }
--------------------------------------------------------------------------------
/app_wx1/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
--------------------------------------------------------------------------------
/app_wx1/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/MyApp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture
2 |
3 | import android.app.Application
4 | import com.wx.architecture.code.app.AppGlobals
5 |
6 | class MyApp : Application() {
7 |
8 | override fun onCreate() {
9 | super.onCreate()
10 | AppGlobals.sApplication = this
11 | }
12 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/app/AppGlobals.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.app
2 |
3 | import android.app.Application
4 |
5 | object AppGlobals {
6 | lateinit var sApplication: Application
7 |
8 | fun getApplication(): Application {
9 | if (!this::sApplication.isInitialized) {
10 | //去反射得到
11 | try {
12 | val aClass = Class.forName("android.app.ActivityThread")
13 | //获取里面的currentApplication
14 | val currentApplication = aClass.getDeclaredMethod("currentApplication")
15 | sApplication = currentApplication.invoke(null, *emptyArray()) as Application
16 | } catch (e: Exception) {
17 | e.printStackTrace()
18 | }
19 | }
20 | return sApplication
21 | }
22 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.fragment.app.Fragment
4 |
5 | class BaseFragment : Fragment() {
6 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.viewModelScope
6 | import com.wx.architecture.code.data.DialogBean
7 | import com.wx.architecture.code.ex.flowOnIOAndCatch
8 | import com.wx.test.api.data.wanandroid.CommonResult
9 | import kotlinx.coroutines.CoroutineScope
10 | import kotlinx.coroutines.NonCancellable.start
11 | import kotlinx.coroutines.cancel
12 | import kotlinx.coroutines.flow.Flow
13 | import kotlinx.coroutines.flow.collect
14 | import kotlinx.coroutines.flow.onCompletion
15 | import kotlinx.coroutines.flow.onStart
16 | import kotlinx.coroutines.launch
17 |
18 | open class BaseViewModel : ViewModel() {
19 | val errorMsgLiveData by lazy { MutableLiveData() }
20 | val showUIDialog by lazy { MutableLiveData() }
21 |
22 | fun show(strMessage: String = "正在请求数据") {
23 | val showBean = showUIDialog.value ?: DialogBean(strMessage, true)
24 | showBean.isShow = true
25 | showBean.msg = strMessage
26 | showUIDialog.postValue(showBean)
27 | }
28 |
29 | fun hide() {
30 | val showBean = showUIDialog.value ?: DialogBean("", true)
31 | showBean.isShow = false
32 | showUIDialog.postValue(showBean)
33 | }
34 |
35 | override fun onCleared() {
36 | viewModelScope.cancel()
37 | }
38 |
39 | protected fun Flow.flowOnIOAndCatch(): Flow = flowOnIOAndCatch(errorMsgLiveData)
40 |
41 | protected fun Flow.onStartAndShow(strMessage: String = "正在请求数据"): Flow = onStart {
42 | show()
43 | }
44 |
45 | protected fun Flow.onCompletionAndHide(): Flow = onCompletion {
46 | hide()
47 | }
48 |
49 | protected suspend fun Flow.onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect() {
50 | onStartAndShow().onCompletionAndHide().flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
51 | }
52 |
53 | fun flowAsyncWorkOnViewModelScopeLaunch(flowAsyncWork: suspend () -> Flow) {
54 | viewModelScope.launch {
55 | flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
56 | }
57 | }
58 |
59 | fun flowAsyncWorkOnViewModelScopeLaunch2(block: suspend CoroutineScope.() -> Unit) {
60 | viewModelScope.launch {
61 | block.invoke(this)
62 | // flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
63 | }
64 | }
65 |
66 | // block: suspend CoroutineScope.() -> Unit
67 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/base/BaseViewModelActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import android.os.Bundle
4 | import android.widget.Toast
5 | import androidx.annotation.LayoutRes
6 | import androidx.annotation.MainThread
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.lifecycle.ViewModelLazy
9 | import com.wx.architecture.code.dialog.ShowUIDialog
10 | import java.lang.reflect.ParameterizedType
11 |
12 |
13 | open class BaseViewModelActivity(@LayoutRes val layResID: Int) : AppCompatActivity() {
14 | private var loading: ShowUIDialog? = null
15 |
16 | protected val viewModel by lazyViewModels()
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(layResID)
21 | initX()
22 | }
23 |
24 | protected fun initX() {
25 | bindObserve()
26 | }
27 |
28 | //是否loading
29 | open fun isShowloading(): Boolean? {
30 | return loading?.isShowing()
31 | }
32 |
33 | open fun showloading(showText: String?) {
34 | if (null == loading) loading = ShowUIDialog(this)
35 | if (isShowloading() == true) return
36 | if (showText != null) loading?.show(showText)
37 | }
38 |
39 | open fun hideLoading() {
40 | loading?.dismiss()
41 | loading = null
42 | }
43 |
44 | override fun onDestroy() {
45 | hideLoading()
46 | super.onDestroy()
47 | }
48 |
49 | protected fun bindObserve() {
50 | viewModel?.run {
51 | showUIDialog.observe(this@BaseViewModelActivity) { it ->
52 | if (it.isShow) showloading(it.msg) else hideLoading()
53 | }
54 | errorMsgLiveData.observe(this@BaseViewModelActivity) {
55 | //公共toast 提示样式可以自行封装
56 | Toast.makeText(this@BaseViewModelActivity, it, Toast.LENGTH_SHORT).show()
57 | }
58 | }
59 | }
60 |
61 | @MainThread
62 | inline fun lazyViewModels(): Lazy {
63 | val cls = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class
64 | return ViewModelLazy(cls.kotlin, { viewModelStore }, { defaultViewModelProviderFactory })
65 | }
66 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/data/DialogBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.data
2 |
3 | data class DialogBean(var msg:String, var isShow:Boolean){
4 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/dialog/ShowUIDialog.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.dialog
2 |
3 | import android.app.Dialog
4 | import android.content.Context
5 | import android.view.Gravity
6 | import android.view.View
7 | import android.widget.TextView
8 | import androidx.appcompat.app.AppCompatDialog
9 | import com.wx.architecture.R
10 |
11 | class ShowUIDialog : AppCompatDialog {
12 |
13 | lateinit var txt_loading_text: TextView
14 |
15 | constructor (context: Context) : super(context, R.style.Loading) {
16 | setContentView(R.layout.layout_loading)
17 | window?.run {
18 | txt_loading_text = findViewById(R.id.txt_loading_text)
19 | attributes.gravity = Gravity.CENTER
20 | }
21 | }
22 |
23 | fun show(showText: String) {
24 | txt_loading_text?.apply {
25 | if (showText.isNotEmpty()) {
26 | text = showText
27 | visibility = View.VISIBLE
28 | } else {
29 | visibility = View.GONE
30 | }
31 | }
32 | if (!isShowing()) {
33 | show()
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/ex/ExceptionEX.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | class ExceptionEX(val errorCode: Int, val errorMessage: String) : Exception(errorMessage) {
4 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/ex/Flow.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.wx.test.api.data.wanandroid.CommonResult
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.flow.*
7 | import java.lang.Exception
8 |
9 |
10 | fun Flow.flowOnIOAndCatch(errorMsgLiveData: MutableLiveData? = null): Flow =
11 | flowOn(Dispatchers.IO)
12 | .catch {
13 | it.printStackTrace()
14 | errorMsgLiveData?.value = it.parseErrorString();
15 | }
16 |
17 | suspend fun Flow.flowOnIOAndCatchAAndCollect() {
18 | flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
19 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/ex/Throwable.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import com.google.gson.JsonSyntaxException
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.app.AppGlobals
6 | import com.wx.architecture.code.utils.isNetWorkActive
7 | import retrofit2.HttpException
8 | import java.io.InterruptedIOException
9 | import java.net.ConnectException
10 | import java.net.SocketException
11 | import java.net.SocketTimeoutException
12 | import java.net.UnknownHostException
13 | import java.util.concurrent.TimeoutException
14 |
15 | fun Throwable?.parseErrorString(): String = when (this) {
16 | is ConnectException, is SocketException -> {
17 | if (message?.contains("Network is unreachable") == true)
18 | getString(R.string.Mobilenetuseless_msg)
19 | if (message?.contains("Failed to connect to") == true)
20 | getString(R.string.failed_to_connect_to)
21 | else
22 | getString(R.string.ConnectException)
23 | }
24 | is HttpException -> {
25 | if (message?.contains("HTTP 50") == true) {
26 | message!!.substring(0, 8)
27 | } else {
28 | getString(R.string.HttpException)
29 | }
30 | }
31 | is InterruptedIOException -> {
32 | if (message?.contains("timeout") == true)
33 | getString(R.string.SocketTimeoutException)
34 | else
35 | getString(R.string.ConnectException)
36 | }
37 | is UnknownHostException -> getString(R.string.UnknownHostException)
38 | is JsonSyntaxException -> getString(R.string.JsonSyntaxException)
39 | is SocketTimeoutException, is TimeoutException -> getString(R.string.SocketTimeoutException)
40 | is IllegalArgumentException -> {
41 | if (message?.contains("baseUrl must end in ") == true)
42 | if (AppGlobals.getApplication().isNetWorkActive()) getString(R.string.HostBaseUrlError)
43 | else getString(R.string.Mobilenetuseless_msg)
44 | else message ?: getString(R.string.ElseNetException)
45 | }
46 | else -> getString(R.string.ElseNetException)
47 | }
48 |
49 | fun getString(resID: Int) = AppGlobals.getApplication().getString(resID)
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/code/utils/NetWorkHelp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.utils
2 | import android.app.Application
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.NetworkCapabilities
6 | import android.os.Build
7 |
8 | fun Application.isNetWorkActive(): Boolean {
9 | val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
10 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
11 | val network = connectivityManager.activeNetwork ?: return false
12 | val activeNetwork =
13 | connectivityManager.getNetworkCapabilities(network) ?: return false
14 | return when {
15 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
16 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
17 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
18 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
19 | else -> false
20 | }
21 | } else {
22 | @Suppress("DEPRECATION") val networkInfo =
23 | connectivityManager.activeNetworkInfo ?: return false
24 | @Suppress("DEPRECATION")
25 | return networkInfo.isConnected
26 | }
27 | return true
28 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/data_source/tata.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source
2 |
3 | class tata {
4 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/ui/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.activity
2 |
3 | import android.view.View
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.base.BaseViewModelActivity
6 | import com.wx.architecture.ui.viewmodel.MainViewModel
7 |
8 | class MainActivity : BaseViewModelActivity(R.layout.activity_main), View.OnClickListener {
9 |
10 | override fun onClick(v: View?) {
11 | when (v?.id) {
12 | R.id.btn1 -> {
13 | viewModel.getHomeList(1)
14 | }
15 | else -> {}
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/java/com/wx/architecture/ui/viewmodel/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.viewmodel
2 |
3 | import com.wx.architecture.code.base.BaseViewModel
4 | import com.wx.architecture.data_source.repository.NetRepository
5 | import kotlinx.coroutines.flow.onEach
6 |
7 | class MainViewModel : BaseViewModel() {
8 |
9 | private val repository by lazy { NetRepository.instance }
10 |
11 | fun getHomeList(page: Int) {
12 | flowAsyncWorkOnViewModelScopeLaunch {
13 | repository.getHomeList(page).onEach {
14 | errorMsgLiveData.postValue(it.data?.datas!![0].title)
15 | android.util.Log.e("MainViewModel", "one 111 ${it.data?.datas!![0].title}")
16 | }
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/app_wx1/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/drawable-xhdpi/ic_loading.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/drawable-xhdpi/ic_loading.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/drawable/progressbar_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/layout/layout_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx1/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx1/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WXNetArchitecture
3 |
4 |
5 | 未知错误异常
6 | 网络超时
7 | 网络超时
8 | 网络错误
9 | 网络错误
10 | 服务器异常
11 | 无网络连接
12 | 请求地址错误
13 | 当前网络不可用
14 | 无法连接到服务器
15 | 数据错误,json解析错误
16 |
17 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
32 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app_wx1/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app_wx2/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app_wx2/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | id 'kotlin-kapt'
5 | }
6 |
7 | android {
8 | compileSdk 32
9 |
10 | defaultConfig {
11 | applicationId "com.wx.wxnetarchitecture"
12 | minSdk 21
13 | targetSdk 32
14 | versionCode 1
15 | versionName "1.0"
16 |
17 | // testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | compileOptions {
27 | sourceCompatibility JavaVersion.VERSION_1_8
28 | targetCompatibility JavaVersion.VERSION_1_8
29 | }
30 | kotlinOptions {
31 | jvmTarget = '1.8'
32 | }
33 | kapt {
34 | generateStubs = true
35 | }
36 | }
37 |
38 | dependencies {
39 | // implementation fileTree(dir: 'libs', include: ['*.jar'])
40 |
41 | implementation 'androidx.core:core-ktx:1.7.0'
42 | implementation 'androidx.appcompat:appcompat:1.3.0'
43 | implementation 'com.google.android.material:material:1.4.0'
44 |
45 | implementation 'com.squareup.retrofit2:retrofit:2.9.0'
46 | implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
47 | implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
48 | implementation 'com.squareup.okhttp3:okhttp:4.9.3'
49 | implementation 'com.squareup.okio:okio:2.10.0'
50 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
51 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
52 |
53 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
54 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
55 | implementation 'androidx.activity:activity-ktx:1.3.0-rc01'
56 | implementation 'androidx.fragment:fragment-ktx:1.4.0-alpha04'
57 |
58 | implementation project(path: ':NetworkApiData')
59 | kapt project(path: ':annotation_compiler')
60 |
61 | // testImplementation 'junit:junit:4.13.2'
62 | // androidTestImplementation 'androidx.test.ext:junit:1.1.3'
63 | // androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
64 | }
--------------------------------------------------------------------------------
/app_wx2/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
--------------------------------------------------------------------------------
/app_wx2/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/MyApp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture
2 |
3 | import android.app.Application
4 | import com.wx.architecture.code.app.AppGlobals
5 |
6 | class MyApp : Application() {
7 |
8 | override fun onCreate() {
9 | super.onCreate()
10 | AppGlobals.sApplication = this
11 | }
12 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/app/AppGlobals.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.app
2 |
3 | import android.app.Application
4 |
5 | object AppGlobals {
6 | lateinit var sApplication: Application
7 |
8 | fun getApplication(): Application {
9 | if (!this::sApplication.isInitialized) {
10 | //去反射得到
11 | try {
12 | val aClass = Class.forName("android.app.ActivityThread")
13 | //获取里面的currentApplication
14 | val currentApplication = aClass.getDeclaredMethod("currentApplication")
15 | sApplication = currentApplication.invoke(null, *emptyArray()) as Application
16 | } catch (e: Exception) {
17 | e.printStackTrace()
18 | }
19 | }
20 | return sApplication
21 | }
22 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.fragment.app.Fragment
4 |
5 | class BaseFragment : Fragment() {
6 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.viewModelScope
6 | import com.wx.architecture.code.data.DialogBean
7 | import com.wx.architecture.code.ex.flowOnIOAndCatch
8 | import com.wx.test.api.data.wanandroid.CommonResult
9 | import kotlinx.coroutines.CoroutineScope
10 | import kotlinx.coroutines.NonCancellable.start
11 | import kotlinx.coroutines.cancel
12 | import kotlinx.coroutines.flow.Flow
13 | import kotlinx.coroutines.flow.collect
14 | import kotlinx.coroutines.flow.onCompletion
15 | import kotlinx.coroutines.flow.onStart
16 | import kotlinx.coroutines.launch
17 |
18 | open class BaseViewModel : ViewModel() {
19 | val errorMsgLiveData by lazy { MutableLiveData() }
20 | val showUIDialog by lazy { MutableLiveData() }
21 |
22 | fun show(strMessage: String = "正在请求数据") {
23 | val showBean = showUIDialog.value ?: DialogBean(strMessage, true)
24 | showBean.isShow = true
25 | showBean.msg = strMessage
26 | showUIDialog.postValue(showBean)
27 | }
28 |
29 | fun hide() {
30 | val showBean = showUIDialog.value ?: DialogBean("", true)
31 | showBean.isShow = false
32 | showUIDialog.postValue(showBean)
33 | }
34 |
35 | override fun onCleared() {
36 | viewModelScope.cancel()
37 | }
38 |
39 | protected fun Flow.flowOnIOAndCatch(): Flow = flowOnIOAndCatch(errorMsgLiveData)
40 |
41 | protected fun Flow.onStartAndShow(strMessage: String = "正在请求数据"): Flow = onStart {
42 | show()
43 | }
44 |
45 | protected fun Flow.onCompletionAndHide(): Flow = onCompletion {
46 | hide()
47 | }
48 |
49 | protected suspend fun Flow.onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect() {
50 | onStartAndShow().onCompletionAndHide().flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
51 | }
52 |
53 | fun flowAsyncWorkOnViewModelScopeLaunch(flowAsyncWork: suspend () -> Flow) {
54 | viewModelScope.launch {
55 | flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
56 | }
57 | }
58 |
59 | fun flowAsyncWorkOnViewModelScopeLaunch2(block: suspend CoroutineScope.() -> Unit) {
60 | viewModelScope.launch {
61 | block.invoke(this)
62 | // flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
63 | }
64 | }
65 |
66 | // block: suspend CoroutineScope.() -> Unit
67 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/base/BaseViewModelActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import android.os.Bundle
4 | import android.widget.Toast
5 | import androidx.annotation.LayoutRes
6 | import androidx.annotation.MainThread
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.lifecycle.ViewModelLazy
9 | import com.wx.architecture.code.dialog.ShowUIDialog
10 | import java.lang.reflect.ParameterizedType
11 |
12 |
13 | open class BaseViewModelActivity(@LayoutRes val layResID: Int) : AppCompatActivity() {
14 | private var loading: ShowUIDialog? = null
15 |
16 | protected val viewModel by lazyViewModels()
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(layResID)
21 | initX()
22 | }
23 |
24 | protected fun initX() {
25 | bindObserve()
26 | }
27 |
28 | //是否loading
29 | open fun isShowloading(): Boolean? {
30 | return loading?.isShowing()
31 | }
32 |
33 | open fun showloading(showText: String?) {
34 | if (null == loading) loading = ShowUIDialog(this)
35 | if (isShowloading() == true) return
36 | if (showText != null) loading?.show(showText)
37 | }
38 |
39 | open fun hideLoading() {
40 | loading?.dismiss()
41 | loading = null
42 | }
43 |
44 | override fun onDestroy() {
45 | hideLoading()
46 | super.onDestroy()
47 | }
48 |
49 | protected fun bindObserve() {
50 | viewModel?.run {
51 | showUIDialog.observe(this@BaseViewModelActivity) { it ->
52 | if (it.isShow) showloading(it.msg) else hideLoading()
53 | }
54 | errorMsgLiveData.observe(this@BaseViewModelActivity) {
55 | //公共toast 提示样式可以自行封装
56 | Toast.makeText(this@BaseViewModelActivity, it, Toast.LENGTH_SHORT).show()
57 | }
58 | }
59 | }
60 |
61 | @MainThread
62 | inline fun lazyViewModels(): Lazy {
63 | val cls = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class
64 | return ViewModelLazy(cls.kotlin, { viewModelStore }, { defaultViewModelProviderFactory })
65 | }
66 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/data/DialogBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.data
2 |
3 | data class DialogBean(var msg:String, var isShow:Boolean){
4 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/dialog/ShowUIDialog.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.dialog
2 |
3 | import android.app.Dialog
4 | import android.content.Context
5 | import android.view.Gravity
6 | import android.view.View
7 | import android.widget.TextView
8 | import androidx.appcompat.app.AppCompatDialog
9 | import com.wx.architecture.R
10 |
11 | class ShowUIDialog : AppCompatDialog {
12 |
13 | lateinit var txt_loading_text: TextView
14 |
15 | constructor (context: Context) : super(context, R.style.Loading) {
16 | setContentView(R.layout.layout_loading)
17 | window?.run {
18 | txt_loading_text = findViewById(R.id.txt_loading_text)
19 | attributes.gravity = Gravity.CENTER
20 | }
21 | }
22 |
23 | fun show(showText: String) {
24 | txt_loading_text?.apply {
25 | if (showText.isNotEmpty()) {
26 | text = showText
27 | visibility = View.VISIBLE
28 | } else {
29 | visibility = View.GONE
30 | }
31 | }
32 | if (!isShowing()) {
33 | show()
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/ex/ExceptionEX.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | class ExceptionEX(val errorCode: Int, val errorMessage: String) : Exception(errorMessage) {
4 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/ex/Flow.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.wx.test.api.data.wanandroid.CommonResult
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.flow.*
7 | import java.lang.Exception
8 |
9 |
10 | fun Flow.flowOnIOAndCatch(errorMsgLiveData: MutableLiveData? = null): Flow =
11 | flowOn(Dispatchers.IO)
12 | .catch {
13 | it.printStackTrace()
14 | errorMsgLiveData?.value = it.parseErrorString();
15 | }
16 |
17 | suspend fun Flow.flowOnIOAndCatchAAndCollect() {
18 | flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
19 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/ex/Throwable.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import com.google.gson.JsonSyntaxException
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.app.AppGlobals
6 | import com.wx.architecture.code.utils.isNetWorkActive
7 | import retrofit2.HttpException
8 | import java.io.InterruptedIOException
9 | import java.net.ConnectException
10 | import java.net.SocketException
11 | import java.net.SocketTimeoutException
12 | import java.net.UnknownHostException
13 | import java.util.concurrent.TimeoutException
14 |
15 | fun Throwable?.parseErrorString(): String = when (this) {
16 | is ConnectException, is SocketException -> {
17 | if (message?.contains("Network is unreachable") == true)
18 | getString(R.string.Mobilenetuseless_msg)
19 | if (message?.contains("Failed to connect to") == true)
20 | getString(R.string.failed_to_connect_to)
21 | else
22 | getString(R.string.ConnectException)
23 | }
24 | is HttpException -> {
25 | if (message?.contains("HTTP 50") == true) {
26 | message!!.substring(0, 8)
27 | } else {
28 | getString(R.string.HttpException)
29 | }
30 | }
31 | is InterruptedIOException -> {
32 | if (message?.contains("timeout") == true)
33 | getString(R.string.SocketTimeoutException)
34 | else
35 | getString(R.string.ConnectException)
36 | }
37 | is UnknownHostException -> getString(R.string.UnknownHostException)
38 | is JsonSyntaxException -> getString(R.string.JsonSyntaxException)
39 | is SocketTimeoutException, is TimeoutException -> getString(R.string.SocketTimeoutException)
40 | is IllegalArgumentException -> {
41 | if (message?.contains("baseUrl must end in ") == true)
42 | if (AppGlobals.sApplication.isNetWorkActive()) getString(R.string.HostBaseUrlError)
43 | else getString(R.string.Mobilenetuseless_msg)
44 | else message ?: getString(R.string.ElseNetException)
45 | }
46 | else -> getString(R.string.ElseNetException)
47 | }
48 |
49 | fun getString(resID: Int) = AppGlobals.sApplication.getString(resID)
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/code/utils/NetWorkHelp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.utils
2 | import android.app.Application
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.NetworkCapabilities
6 | import android.os.Build
7 |
8 | fun Application.isNetWorkActive(): Boolean {
9 | val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
10 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
11 | val network = connectivityManager.activeNetwork ?: return false
12 | val activeNetwork =
13 | connectivityManager.getNetworkCapabilities(network) ?: return false
14 | return when {
15 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
16 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
17 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
18 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
19 | else -> false
20 | }
21 | } else {
22 | @Suppress("DEPRECATION") val networkInfo =
23 | connectivityManager.activeNetworkInfo ?: return false
24 | @Suppress("DEPRECATION")
25 | return networkInfo.isConnected
26 | }
27 | return true
28 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/data_source/kapt/KaptComponet.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.kapt
2 |
3 | import com.wx.annotations.AutoCreateRepository
4 |
5 | /**
6 | * interfaceApi: 接口类名字,
7 | * superClass : 自动生成的类的继承的父类
8 | **/
9 | @AutoCreateRepository(interfaceApi = "com.wx.test.api.net.NetApi", superClass = "com.wx.architecture.data_source.repository.BaseRepository")
10 | class KaptComponet {
11 | }
12 |
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/data_source/repository/BaseRepository.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.repository
2 |
3 | import com.wx.test.api.retrofit.RetrofitUtils
4 | import com.wx.test.api.data.BaseResponse
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.withContext
7 | import java.lang.reflect.ParameterizedType
8 |
9 | open class BaseRepository() {
10 | val service by lazy { createService() }
11 |
12 | private fun createService(): T {
13 | val clazz = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class
14 | return RetrofitUtils.instance.create(clazz)
15 | }
16 |
17 | //
18 | suspend fun apiCall(api: suspend () -> BaseResponse): BaseResponse = withContext(Dispatchers.IO) { api.invoke() }
19 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/data_source/tata.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source
2 |
3 | class tata {
4 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/ui/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.activity
2 |
3 | import android.view.View
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.base.BaseViewModelActivity
6 | import com.wx.architecture.ui.viewmodel.MainViewModel
7 |
8 | class MainActivity : BaseViewModelActivity(R.layout.activity_main), View.OnClickListener {
9 |
10 | override fun onClick(v: View?) {
11 | when (v?.id) {
12 | R.id.btn1 -> {
13 | viewModel.getHomeList(1)
14 | }
15 | else -> {}
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/java/com/wx/architecture/ui/viewmodel/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.viewmodel
2 |
3 | import com.wx.architecture.code.base.BaseViewModel
4 | import com.wx.architecture.data_source.kapt.RNetApiRepository
5 | import kotlinx.coroutines.flow.onEach
6 |
7 | class MainViewModel : BaseViewModel() {
8 |
9 | private val repository by lazy { RNetApiRepository() }
10 |
11 | fun getHomeList(page: Int) {
12 | flowAsyncWorkOnViewModelScopeLaunch {
13 | val time = System.currentTimeMillis()
14 | repository.getHomeList(page).onEach {
15 | errorMsgLiveData.postValue(it.data?.datas!![0].title)
16 | android.util.Log.e("MainViewModel", "two 222 ${it.data?.datas!![0].title}")
17 | android.util.Log.e("MainViewModel", "耗时:${(System.currentTimeMillis() - time)} ms")
18 | }
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/app_wx2/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/drawable-xhdpi/ic_loading.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/drawable-xhdpi/ic_loading.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/drawable/progressbar_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/layout/layout_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx2/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx2/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WXNetArchitecture
3 |
4 |
5 | 未知错误异常
6 | 网络超时
7 | 网络超时
8 | 网络错误
9 | 网络错误
10 | 服务器异常
11 | 无网络连接
12 | 请求地址错误
13 | 当前网络不可用
14 | 无法连接到服务器
15 | 数据错误,json解析错误
16 |
17 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
32 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app_wx2/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app_wx3/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app_wx3/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | id 'kotlin-kapt'
5 | }
6 |
7 | android {
8 | compileSdk 32
9 |
10 | defaultConfig {
11 | applicationId "com.wx.wxnetarchitecture"
12 | minSdk 21
13 | targetSdk 32
14 | versionCode 1
15 | versionName "1.0"
16 |
17 | // testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | compileOptions {
27 | sourceCompatibility JavaVersion.VERSION_1_8
28 | targetCompatibility JavaVersion.VERSION_1_8
29 | }
30 | kotlinOptions {
31 | jvmTarget = '1.8'
32 | }
33 | kapt {
34 | generateStubs = true
35 | }
36 | }
37 |
38 | dependencies {
39 | // implementation fileTree(dir: 'libs', include: ['*.jar'])
40 | implementation 'org.jetbrains.kotlin:kotlin-reflect:1.7.0'
41 |
42 | implementation 'androidx.core:core-ktx:1.7.0'
43 | implementation 'androidx.appcompat:appcompat:1.3.0'
44 | implementation 'com.google.android.material:material:1.4.0'
45 |
46 | implementation 'com.squareup.retrofit2:retrofit:2.9.0'
47 | implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
48 | implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
49 | implementation 'com.squareup.okhttp3:okhttp:4.9.3'
50 | implementation 'com.squareup.okio:okio:2.10.0'
51 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
52 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
53 |
54 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
55 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
56 | implementation 'androidx.activity:activity-ktx:1.3.0-rc01'
57 | implementation 'androidx.fragment:fragment-ktx:1.4.0-alpha04'
58 |
59 | implementation project(path: ':NetworkApiData')
60 | kapt project(path: ':annotation_compiler')
61 |
62 | // testImplementation 'junit:junit:4.13.2'
63 | // androidTestImplementation 'androidx.test.ext:junit:1.1.3'
64 | // androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
65 | }
--------------------------------------------------------------------------------
/app_wx3/libs/annotation_compiler.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/libs/annotation_compiler.jar
--------------------------------------------------------------------------------
/app_wx3/libs/annotations.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/libs/annotations.jar
--------------------------------------------------------------------------------
/app_wx3/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
--------------------------------------------------------------------------------
/app_wx3/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/MyApp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture
2 |
3 | import android.app.Application
4 | import com.wx.architecture.code.app.AppGlobals
5 |
6 | class MyApp : Application() {
7 |
8 | override fun onCreate() {
9 | super.onCreate()
10 | AppGlobals.sApplication = this
11 | }
12 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/app/AppGlobals.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.app
2 |
3 | import android.app.Application
4 |
5 | object AppGlobals {
6 | lateinit var sApplication: Application
7 |
8 | fun getApplication(): Application {
9 | if (!this::sApplication.isInitialized) {
10 | //去反射得到
11 | try {
12 | val aClass = Class.forName("android.app.ActivityThread")
13 | //获取里面的currentApplication
14 | val currentApplication = aClass.getDeclaredMethod("currentApplication")
15 | sApplication = currentApplication.invoke(null, *emptyArray()) as Application
16 | } catch (e: Exception) {
17 | e.printStackTrace()
18 | }
19 | }
20 | return sApplication
21 | }
22 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.fragment.app.Fragment
4 |
5 | class BaseFragment : Fragment() {
6 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/base/BaseRepositoryProxy.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import okhttp3.MultipartBody
4 | import okhttp3.RequestBody
5 | import kotlin.reflect.KFunction
6 | import kotlin.reflect.full.callSuspend
7 | import kotlin.reflect.full.memberFunctions
8 | import kotlin.reflect.javaType
9 |
10 | open class BaseRepositoryProxy {
11 |
12 | private val map by lazy { mutableMapOf?>() }
13 | private val sb by lazy { StringBuffer() }
14 |
15 | @OptIn(ExperimentalStdlibApi::class)
16 | fun findSuspendMethod(service: Class, methodName: String, args: Array): KFunction<*>? {
17 | sb.delete(0, sb.length)
18 | sb.append(service.name)
19 | .append(methodName)
20 | args.forEach {
21 | sb.append(it.javaClass.typeName)
22 | }
23 | val key = sb.toString()
24 | if (!map.containsKey(key)) {
25 | val function = service.kotlin.memberFunctions.find { f ->
26 | var isRight = 0
27 | if (f.name == methodName && f.isSuspend) {
28 | if (args.size == 0 && f.parameters.size == 1) {
29 | isRight = 2
30 | } else {
31 | f.parameters.forEachIndexed { index, it ->
32 | if (index > 0 && args.size > 0) {
33 | if (args.size == 0) {
34 | isRight = 2
35 | return@forEachIndexed
36 | }
37 | if (it.type.javaType.typeName == javaClassTransform(args[index - 1].javaClass).typeName) {
38 | isRight = 2
39 | } else {
40 | isRight = 1
41 | return@forEachIndexed
42 | }
43 | }
44 | }
45 | }
46 | }
47 | //方法名一直 是挂起函数 方法参数个数一致, 参数类型一致
48 | f.name == methodName && f.isSuspend && f.parameters.size - 1 == args.size && isRight == 2
49 | }
50 | map[key] = function
51 | }
52 | return map[key]
53 | }
54 |
55 | private fun javaClassTransform(clazz: Class) = when (clazz.typeName) {
56 | "java.lang.Integer" -> Int::class.java
57 | "java.lang.String" -> String::class.java
58 | "java.lang.Float" -> Float::class.java
59 | "java.lang.Long" -> Long::class.java
60 | "java.lang.Boolean" -> Boolean::class.java
61 | "java.lang.Double" -> Double::class.java
62 | "java.lang.Byte" -> Byte::class.java
63 | "java.lang.Short" -> Short::class.java
64 | "java.lang.Character" -> Char::class.java
65 | "SingletonMap" -> Map::class.java
66 | "LinkedHashMap" -> MutableMap::class.java
67 | "HashMap" -> HashMap::class.java
68 | "Part" -> MultipartBody.Part::class.java
69 | "RequestBody" -> RequestBody::class.java
70 | else -> {
71 | if ("RequestBody" == clazz.superclass.simpleName) {
72 | RequestBody::class.java
73 | } else {
74 | Any::class.java
75 | }
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.viewModelScope
6 | import com.wx.architecture.code.data.DialogBean
7 | import com.wx.architecture.code.ex.flowOnIOAndCatch
8 | import com.wx.test.api.data.wanandroid.CommonResult
9 | import kotlinx.coroutines.CoroutineScope
10 | import kotlinx.coroutines.NonCancellable.start
11 | import kotlinx.coroutines.cancel
12 | import kotlinx.coroutines.flow.Flow
13 | import kotlinx.coroutines.flow.collect
14 | import kotlinx.coroutines.flow.onCompletion
15 | import kotlinx.coroutines.flow.onStart
16 | import kotlinx.coroutines.launch
17 |
18 | open class BaseViewModel : ViewModel() {
19 | val errorMsgLiveData by lazy { MutableLiveData() }
20 | val showUIDialog by lazy { MutableLiveData() }
21 |
22 | fun show(strMessage: String = "正在请求数据") {
23 | val showBean = showUIDialog.value ?: DialogBean(strMessage, true)
24 | showBean.isShow = true
25 | showBean.msg = strMessage
26 | showUIDialog.postValue(showBean)
27 | }
28 |
29 | fun hide() {
30 | val showBean = showUIDialog.value ?: DialogBean("", true)
31 | showBean.isShow = false
32 | showUIDialog.postValue(showBean)
33 | }
34 |
35 | override fun onCleared() {
36 | viewModelScope.cancel()
37 | }
38 |
39 | protected fun Flow.flowOnIOAndCatch(): Flow = flowOnIOAndCatch(errorMsgLiveData)
40 |
41 | protected fun Flow.onStartAndShow(strMessage: String = "正在请求数据"): Flow = onStart {
42 | show()
43 | }
44 |
45 | protected fun Flow.onCompletionAndHide(): Flow = onCompletion {
46 | hide()
47 | }
48 |
49 | protected suspend fun Flow.onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect() {
50 | onStartAndShow().onCompletionAndHide().flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
51 | }
52 |
53 | fun flowAsyncWorkOnViewModelScopeLaunch(flowAsyncWork: suspend () -> Flow) {
54 | viewModelScope.launch {
55 | flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
56 | }
57 | }
58 |
59 | // fun flowAsyncWorkOnViewModelScopeLaunch2(block: suspend CoroutineScope.() -> Unit) {
60 | // viewModelScope.launch {
61 | // val b = block.invoke(this)
62 | // b. onStartAndShow().onCompletionAndHide().flowOnIOAndCatch()
63 | // b
64 | //// flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
65 | // }
66 | // }
67 |
68 | // block: suspend CoroutineScope.() -> Unit
69 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/base/BaseViewModelActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import android.os.Bundle
4 | import android.widget.Toast
5 | import androidx.annotation.LayoutRes
6 | import androidx.annotation.MainThread
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.lifecycle.ViewModelLazy
9 | import com.wx.architecture.code.dialog.ShowUIDialog
10 | import java.lang.reflect.ParameterizedType
11 |
12 |
13 | open class BaseViewModelActivity(@LayoutRes val layResID: Int) : AppCompatActivity() {
14 | private var loading: ShowUIDialog? = null
15 |
16 | protected val viewModel by lazyViewModels()
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(layResID)
21 | initX()
22 | }
23 |
24 | protected fun initX() {
25 | bindObserve()
26 | }
27 |
28 | //是否loading
29 | open fun isShowloading(): Boolean? {
30 | return loading?.isShowing()
31 | }
32 |
33 | open fun showloading(showText: String?) {
34 | if (null == loading) loading = ShowUIDialog(this)
35 | if (isShowloading() == true) return
36 | if (showText != null) loading?.show(showText)
37 | }
38 |
39 | open fun hideLoading() {
40 | loading?.dismiss()
41 | loading = null
42 | }
43 |
44 | override fun onDestroy() {
45 | hideLoading()
46 | super.onDestroy()
47 | }
48 |
49 | protected fun bindObserve() {
50 | viewModel?.run {
51 | showUIDialog.observe(this@BaseViewModelActivity) { it ->
52 | if (it.isShow) showloading(it.msg) else hideLoading()
53 | }
54 | errorMsgLiveData.observe(this@BaseViewModelActivity) {
55 | //公共toast 提示样式可以自行封装
56 | Toast.makeText(this@BaseViewModelActivity, it, Toast.LENGTH_SHORT).show()
57 | }
58 | }
59 | }
60 |
61 | @MainThread
62 | inline fun lazyViewModels(): Lazy {
63 | val cls = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class
64 | return ViewModelLazy(cls.kotlin, { viewModelStore }, { defaultViewModelProviderFactory })
65 | }
66 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/data/DialogBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.data
2 |
3 | data class DialogBean(var msg:String, var isShow:Boolean){
4 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/dialog/ShowUIDialog.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.dialog
2 |
3 | import android.app.Dialog
4 | import android.content.Context
5 | import android.view.Gravity
6 | import android.view.View
7 | import android.widget.TextView
8 | import androidx.appcompat.app.AppCompatDialog
9 | import com.wx.architecture.R
10 |
11 | class ShowUIDialog : AppCompatDialog {
12 |
13 | lateinit var txt_loading_text: TextView
14 |
15 | constructor (context: Context) : super(context, R.style.Loading) {
16 | setContentView(R.layout.layout_loading)
17 | window?.run {
18 | txt_loading_text = findViewById(R.id.txt_loading_text)
19 | attributes.gravity = Gravity.CENTER
20 | }
21 | }
22 |
23 | fun show(showText: String) {
24 | txt_loading_text?.apply {
25 | if (showText.isNotEmpty()) {
26 | text = showText
27 | visibility = View.VISIBLE
28 | } else {
29 | visibility = View.GONE
30 | }
31 | }
32 | if (!isShowing()) {
33 | show()
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/ex/ExceptionEX.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | class ExceptionEX(val errorCode: Int, val errorMessage: String) : Exception(errorMessage) {
4 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/ex/Flow.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.wx.test.api.data.wanandroid.CommonResult
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.flow.*
7 | import java.lang.Exception
8 |
9 |
10 | fun Flow.flowOnIOAndCatch(errorMsgLiveData: MutableLiveData? = null): Flow =
11 | flowOn(Dispatchers.IO)
12 | .catch {
13 | it.printStackTrace()
14 | errorMsgLiveData?.value = it.parseErrorString();
15 | }
16 |
17 | suspend fun Flow.flowOnIOAndCatchAAndCollect() {
18 | flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
19 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/ex/Throwable.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import com.google.gson.JsonSyntaxException
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.app.AppGlobals
6 | import com.wx.architecture.code.utils.isNetWorkActive
7 | import retrofit2.HttpException
8 | import java.io.InterruptedIOException
9 | import java.net.ConnectException
10 | import java.net.SocketException
11 | import java.net.SocketTimeoutException
12 | import java.net.UnknownHostException
13 | import java.util.concurrent.TimeoutException
14 |
15 | fun Throwable?.parseErrorString(): String = when (this) {
16 | is ConnectException, is SocketException -> {
17 | if (message?.contains("Network is unreachable") == true)
18 | getString(R.string.Mobilenetuseless_msg)
19 | if (message?.contains("Failed to connect to") == true)
20 | getString(R.string.failed_to_connect_to)
21 | else
22 | getString(R.string.ConnectException)
23 | }
24 | is HttpException -> {
25 | if (message?.contains("HTTP 50") == true) {
26 | message!!.substring(0, 8)
27 | } else {
28 | getString(R.string.HttpException)
29 | }
30 | }
31 | is InterruptedIOException -> {
32 | if (message?.contains("timeout") == true)
33 | getString(R.string.SocketTimeoutException)
34 | else
35 | getString(R.string.ConnectException)
36 | }
37 | is UnknownHostException -> getString(R.string.UnknownHostException)
38 | is JsonSyntaxException -> getString(R.string.JsonSyntaxException)
39 | is SocketTimeoutException, is TimeoutException -> getString(R.string.SocketTimeoutException)
40 | is IllegalArgumentException -> {
41 | if (message?.contains("baseUrl must end in ") == true)
42 | if (AppGlobals.sApplication.isNetWorkActive()) getString(R.string.HostBaseUrlError)
43 | else getString(R.string.Mobilenetuseless_msg)
44 | else message ?: getString(R.string.ElseNetException)
45 | }
46 | else -> getString(R.string.ElseNetException)
47 | }
48 |
49 | fun getString(resID: Int) = AppGlobals.sApplication.getString(resID)
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/code/utils/NetWorkHelp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.utils
2 | import android.app.Application
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.NetworkCapabilities
6 | import android.os.Build
7 |
8 | fun Application.isNetWorkActive(): Boolean {
9 | val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
10 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
11 | val network = connectivityManager.activeNetwork ?: return false
12 | val activeNetwork =
13 | connectivityManager.getNetworkCapabilities(network) ?: return false
14 | return when {
15 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
16 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
17 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
18 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
19 | else -> false
20 | }
21 | } else {
22 | @Suppress("DEPRECATION") val networkInfo =
23 | connectivityManager.activeNetworkInfo ?: return false
24 | @Suppress("DEPRECATION")
25 | return networkInfo.isConnected
26 | }
27 | return true
28 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/data_source/kapt/KaptInterface.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.kapt
2 |
3 | import com.wx.annotations.AutoCreateRepositoryInterface
4 |
5 | @AutoCreateRepositoryInterface(interfaceApi = "com.wx.test.api.net.NetApi")
6 | class KaptInterface {
7 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/data_source/repository/RepositoryPoxy.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.repository
2 |
3 | import com.wx.architecture.code.base.BaseRepositoryProxy
4 | import com.wx.test.api.net.NetApi
5 | import com.wx.test.api.retrofit.RetrofitUtils
6 | import kotlinx.coroutines.flow.catch
7 | import kotlinx.coroutines.flow.flow
8 | import okhttp3.MultipartBody
9 | import okhttp3.RequestBody
10 | import java.lang.reflect.InvocationTargetException
11 | import java.lang.reflect.Proxy
12 | import kotlin.reflect.full.callSuspend
13 | import kotlin.reflect.full.memberFunctions
14 | import kotlin.reflect.javaType
15 |
16 | class RepositoryPoxy private constructor() : BaseRepositoryProxy() {
17 |
18 | val service = NetApi::class.java
19 | val api by lazy { RetrofitUtils.instance.create(service) }
20 |
21 |
22 | companion object {
23 | val instance by lazy { RepositoryPoxy() }
24 | }
25 |
26 | fun callApiMethod(serviceR: Class): R {
27 | return Proxy.newProxyInstance(serviceR.classLoader, arrayOf(serviceR)) { proxy, method, args ->
28 | flow {
29 | val funcds = findSuspendMethod(service, method.name, args)
30 | if (args == null) {
31 | emit(funcds?.callSuspend(api))
32 | } else {
33 | emit(funcds?.callSuspend(api, *args))
34 | }
35 | // emit((service.getMethod(method.name, *parameterTypes)?.invoke(api, *(args ?: emptyArray())) as Call).execute().body())
36 | }.catch {
37 | if (it is InvocationTargetException) {
38 | throw Throwable(it.targetException)
39 | } else {
40 | it.printStackTrace()
41 | throw it
42 | }
43 | }
44 | } as R
45 | }
46 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/data_source/tata.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source
2 |
3 | class tata {
4 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/ui/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.activity
2 |
3 | import android.view.View
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.base.BaseViewModelActivity
6 | import com.wx.architecture.ui.viewmodel.MainViewModel
7 |
8 | class MainActivity : BaseViewModelActivity(R.layout.activity_main), View.OnClickListener {
9 |
10 | override fun onClick(v: View?) {
11 | when (v?.id) {
12 | R.id.btn1 -> {
13 | viewModel.getHomeList(1)
14 | }
15 | else -> {}
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/java/com/wx/architecture/ui/viewmodel/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.viewmodel
2 |
3 | import com.wx.architecture.code.base.BaseViewModel
4 | import com.wx.architecture.data_source.kapt.INetApiRepository
5 | import com.wx.architecture.data_source.repository.RepositoryPoxy
6 | import kotlinx.coroutines.flow.collect
7 | import kotlinx.coroutines.flow.onEach
8 |
9 | class MainViewModel : BaseViewModel() {
10 |
11 | private val repository by lazy { RepositoryPoxy.instance }
12 |
13 | fun getHomeList(page: Int) {
14 | flowAsyncWorkOnViewModelScopeLaunch {
15 | val time = System.currentTimeMillis()
16 | repository.callApiMethod(INetApiRepository::class.java).getHomeList(page).onEach {
17 | errorMsgLiveData.postValue(it.data?.datas!![0].title)
18 | android.util.Log.e("MainViewModel", "three 333 ${it.data?.datas!![0].title}")
19 | android.util.Log.e("MainViewModel", "耗时:${(System.currentTimeMillis() - time)} ms")
20 | }
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/app_wx3/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/drawable-xhdpi/ic_loading.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/drawable-xhdpi/ic_loading.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/drawable/progressbar_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/layout/layout_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx3/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx3/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WXNetArchitecture
3 |
4 |
5 | 未知错误异常
6 | 网络超时
7 | 网络超时
8 | 网络错误
9 | 网络错误
10 | 服务器异常
11 | 无网络连接
12 | 请求地址错误
13 | 当前网络不可用
14 | 无法连接到服务器
15 | 数据错误,json解析错误
16 |
17 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
32 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app_wx3/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app_wx4/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app_wx4/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | id 'kotlin-kapt'
5 | }
6 |
7 | android {
8 | compileSdk 32
9 |
10 | defaultConfig {
11 | applicationId "com.wx.wxnetarchitecture"
12 | minSdk 21
13 | targetSdk 32
14 | versionCode 1
15 | versionName "1.0"
16 |
17 | // testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 | compileOptions {
27 | sourceCompatibility JavaVersion.VERSION_1_8
28 | targetCompatibility JavaVersion.VERSION_1_8
29 | }
30 | kotlinOptions {
31 | jvmTarget = '1.8'
32 | }
33 | kapt {
34 | generateStubs = true
35 | }
36 | }
37 |
38 | dependencies {
39 | // implementation fileTree(dir: 'libs', include: ['*.jar'])
40 | implementation 'org.jetbrains.kotlin:kotlin-reflect:1.7.0'
41 |
42 | implementation 'androidx.core:core-ktx:1.7.0'
43 | implementation 'androidx.appcompat:appcompat:1.3.0'
44 | implementation 'com.google.android.material:material:1.4.0'
45 |
46 | implementation 'com.squareup.retrofit2:retrofit:2.9.0'
47 | implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
48 | implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
49 | implementation 'com.squareup.okhttp3:okhttp:4.9.3'
50 | implementation 'com.squareup.okio:okio:2.10.0'
51 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
52 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
53 |
54 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
55 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
56 | implementation 'androidx.activity:activity-ktx:1.3.0-rc01'
57 | implementation 'androidx.fragment:fragment-ktx:1.4.0-alpha04'
58 |
59 | implementation project(path: ':NetworkApiData')
60 |
61 | // testImplementation 'junit:junit:4.13.2'
62 | // androidTestImplementation 'androidx.test.ext:junit:1.1.3'
63 | // androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
64 | }
--------------------------------------------------------------------------------
/app_wx4/libs/annotation_compiler.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/libs/annotation_compiler.jar
--------------------------------------------------------------------------------
/app_wx4/libs/annotations.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/libs/annotations.jar
--------------------------------------------------------------------------------
/app_wx4/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
--------------------------------------------------------------------------------
/app_wx4/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/MyApp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture
2 |
3 | import android.app.Application
4 | import com.wx.architecture.code.app.AppGlobals
5 |
6 | class MyApp : Application() {
7 |
8 | override fun onCreate() {
9 | super.onCreate()
10 | AppGlobals.sApplication = this
11 | }
12 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/app/AppGlobals.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.app
2 |
3 | import android.app.Application
4 |
5 | object AppGlobals {
6 | lateinit var sApplication: Application
7 |
8 | fun getApplication(): Application {
9 | if (!this::sApplication.isInitialized) {
10 | //去反射得到
11 | try {
12 | val aClass = Class.forName("android.app.ActivityThread")
13 | //获取里面的currentApplication
14 | val currentApplication = aClass.getDeclaredMethod("currentApplication")
15 | sApplication = currentApplication.invoke(null, *emptyArray()) as Application
16 | } catch (e: Exception) {
17 | e.printStackTrace()
18 | }
19 | }
20 | return sApplication
21 | }
22 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.fragment.app.Fragment
4 |
5 | class BaseFragment : Fragment() {
6 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/base/BaseRepositoryProxy.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import okhttp3.MultipartBody
4 | import okhttp3.RequestBody
5 | import kotlin.reflect.KFunction
6 | import kotlin.reflect.full.callSuspend
7 | import kotlin.reflect.full.memberFunctions
8 | import kotlin.reflect.javaType
9 |
10 | open class BaseRepositoryProxy {
11 | private val map by lazy { mutableMapOf?>() }
12 | private val sb by lazy { StringBuffer() }
13 |
14 | @OptIn(ExperimentalStdlibApi::class)
15 | fun findSuspendMethod(service: Class, methodName: String, args: Array): KFunction<*>? {
16 | sb.delete(0, sb.length)
17 | sb.append(service.name)
18 | .append(methodName)
19 | args.forEach {
20 | sb.append(it.javaClass.typeName)
21 | }
22 | val key = sb.toString()
23 | if (!map.containsKey(key)) {
24 | val function = service.kotlin.memberFunctions.find { f ->
25 | var isRight = 0
26 | if (f.name == methodName && f.isSuspend) {
27 | if (args.size == 0 && f.parameters.size == 1) {
28 | isRight = 2
29 | } else {
30 | f.parameters.forEachIndexed { index, it ->
31 | if (index > 0 && args.size > 0) {
32 | if (args.size == 0) {
33 | isRight = 2
34 | return@forEachIndexed
35 | }
36 | if (it.type.javaType.typeName == javaClassTransform(args[index - 1].javaClass).typeName) {
37 | isRight = 2
38 | } else {
39 | isRight = 1
40 | return@forEachIndexed
41 | }
42 | }
43 | }
44 | }
45 | }
46 | //方法名一直 是挂起函数 方法参数个数一致, 参数类型一致
47 | f.name == methodName && f.isSuspend && f.parameters.size - 1 == args.size && isRight == 2
48 | }
49 | map[key] = function
50 | }
51 | return map[key]
52 | }
53 |
54 | fun javaClassTransform(clazz: Class) = when (clazz.typeName) {
55 | "java.lang.Integer" -> Int::class.java
56 | "java.lang.String" -> String::class.java
57 | "java.lang.Float" -> Float::class.java
58 | "java.lang.Long" -> Long::class.java
59 | "java.lang.Boolean" -> Boolean::class.java
60 | "java.lang.Double" -> Double::class.java
61 | "java.lang.Byte" -> Byte::class.java
62 | "java.lang.Short" -> Short::class.java
63 | "java.lang.Character" -> Char::class.java
64 | "SingletonMap" -> Map::class.java
65 | "LinkedHashMap" -> MutableMap::class.java
66 | "HashMap" -> HashMap::class.java
67 | "Part" -> MultipartBody.Part::class.java
68 | "RequestBody" -> RequestBody::class.java
69 | else -> {
70 | if ("RequestBody" == clazz.superclass.simpleName) {
71 | RequestBody::class.java
72 | } else {
73 | Any::class.java
74 | }
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.viewModelScope
6 | import com.wx.architecture.code.data.DialogBean
7 | import com.wx.architecture.code.ex.flowOnIOAndCatch
8 | import com.wx.test.api.data.wanandroid.CommonResult
9 | import kotlinx.coroutines.CoroutineScope
10 | import kotlinx.coroutines.NonCancellable.start
11 | import kotlinx.coroutines.cancel
12 | import kotlinx.coroutines.flow.Flow
13 | import kotlinx.coroutines.flow.collect
14 | import kotlinx.coroutines.flow.onCompletion
15 | import kotlinx.coroutines.flow.onStart
16 | import kotlinx.coroutines.launch
17 |
18 | open class BaseViewModel : ViewModel() {
19 | val errorMsgLiveData by lazy { MutableLiveData() }
20 | val showUIDialog by lazy { MutableLiveData() }
21 |
22 | fun show(strMessage: String = "正在请求数据") {
23 | val showBean = showUIDialog.value ?: DialogBean(strMessage, true)
24 | showBean.isShow = true
25 | showBean.msg = strMessage
26 | showUIDialog.postValue(showBean)
27 | }
28 |
29 | fun hide() {
30 | val showBean = showUIDialog.value ?: DialogBean("", true)
31 | showBean.isShow = false
32 | showUIDialog.postValue(showBean)
33 | }
34 |
35 | override fun onCleared() {
36 | viewModelScope.cancel()
37 | }
38 |
39 | protected fun Flow.flowOnIOAndCatch(): Flow = flowOnIOAndCatch(errorMsgLiveData)
40 |
41 | protected fun Flow.onStartAndShow(strMessage: String = "正在请求数据"): Flow = onStart {
42 | show()
43 | }
44 |
45 | protected fun Flow.onCompletionAndHide(): Flow = onCompletion {
46 | hide()
47 | }
48 |
49 | protected suspend fun Flow.onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect() {
50 | onStartAndShow().onCompletionAndHide().flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
51 | }
52 |
53 | fun flowAsyncWorkOnViewModelScopeLaunch(flowAsyncWork: suspend () -> Flow) {
54 | viewModelScope.launch {
55 | flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
56 | }
57 | }
58 |
59 | fun flowAsyncWorkOnViewModelScopeLaunch2(block: suspend CoroutineScope.() -> Unit) {
60 | viewModelScope.launch {
61 | block.invoke(this)
62 | // flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
63 | }
64 | }
65 |
66 | // block: suspend CoroutineScope.() -> Unit
67 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/base/BaseViewModelActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import android.os.Bundle
4 | import android.widget.Toast
5 | import androidx.annotation.LayoutRes
6 | import androidx.annotation.MainThread
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.lifecycle.ViewModelLazy
9 | import com.wx.architecture.code.dialog.ShowUIDialog
10 | import java.lang.reflect.ParameterizedType
11 |
12 |
13 | open class BaseViewModelActivity(@LayoutRes val layResID: Int) : AppCompatActivity() {
14 | private var loading: ShowUIDialog? = null
15 |
16 | protected val viewModel by lazyViewModels()
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(layResID)
21 | initX()
22 | }
23 |
24 | protected fun initX() {
25 | bindObserve()
26 | }
27 |
28 | //是否loading
29 | open fun isShowloading(): Boolean? {
30 | return loading?.isShowing()
31 | }
32 |
33 | open fun showloading(showText: String?) {
34 | if (null == loading) loading = ShowUIDialog(this)
35 | if (isShowloading() == true) return
36 | if (showText != null) loading?.show(showText)
37 | }
38 |
39 | open fun hideLoading() {
40 | loading?.dismiss()
41 | loading = null
42 | }
43 |
44 | override fun onDestroy() {
45 | hideLoading()
46 | super.onDestroy()
47 | }
48 |
49 | protected fun bindObserve() {
50 | viewModel?.run {
51 | showUIDialog.observe(this@BaseViewModelActivity) { it ->
52 | if (it.isShow) showloading(it.msg) else hideLoading()
53 | }
54 | errorMsgLiveData.observe(this@BaseViewModelActivity) {
55 | //公共toast 提示样式可以自行封装
56 | Toast.makeText(this@BaseViewModelActivity, it, Toast.LENGTH_SHORT).show()
57 | }
58 | }
59 | }
60 |
61 | @MainThread
62 | inline fun lazyViewModels(): Lazy {
63 | val cls = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class
64 | return ViewModelLazy(cls.kotlin, { viewModelStore }, { defaultViewModelProviderFactory })
65 | }
66 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/data/DialogBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.data
2 |
3 | data class DialogBean(var msg:String, var isShow:Boolean){
4 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/dialog/ShowUIDialog.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.dialog
2 |
3 | import android.app.Dialog
4 | import android.content.Context
5 | import android.view.Gravity
6 | import android.view.View
7 | import android.widget.TextView
8 | import androidx.appcompat.app.AppCompatDialog
9 | import com.wx.architecture.R
10 |
11 | class ShowUIDialog : AppCompatDialog {
12 |
13 | lateinit var txt_loading_text: TextView
14 |
15 | constructor (context: Context) : super(context, R.style.Loading) {
16 | setContentView(R.layout.layout_loading)
17 | window?.run {
18 | txt_loading_text = findViewById(R.id.txt_loading_text)
19 | attributes.gravity = Gravity.CENTER
20 | }
21 | }
22 |
23 | fun show(showText: String) {
24 | txt_loading_text?.apply {
25 | if (showText.isNotEmpty()) {
26 | text = showText
27 | visibility = View.VISIBLE
28 | } else {
29 | visibility = View.GONE
30 | }
31 | }
32 | if (!isShowing()) {
33 | show()
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/ex/ExceptionEX.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | class ExceptionEX(val errorCode: Int, val errorMessage: String) : Exception(errorMessage) {
4 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/ex/Flow.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.wx.test.api.data.wanandroid.CommonResult
5 | import kotlinx.coroutines.Dispatchers
6 | import kotlinx.coroutines.flow.*
7 | import java.lang.Exception
8 |
9 |
10 | fun Flow.flowOnIOAndCatch(errorMsgLiveData: MutableLiveData? = null): Flow =
11 | flowOn(Dispatchers.IO)
12 | .catch {
13 | it.printStackTrace()
14 | errorMsgLiveData?.value = it.parseErrorString();
15 | }
16 |
17 | suspend fun Flow.flowOnIOAndCatchAAndCollect() {
18 | flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
19 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/ex/Throwable.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import com.google.gson.JsonSyntaxException
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.app.AppGlobals
6 | import com.wx.architecture.code.utils.isNetWorkActive
7 | import retrofit2.HttpException
8 | import java.io.InterruptedIOException
9 | import java.net.ConnectException
10 | import java.net.SocketException
11 | import java.net.SocketTimeoutException
12 | import java.net.UnknownHostException
13 | import java.util.concurrent.TimeoutException
14 |
15 | fun Throwable?.parseErrorString(): String = when (this) {
16 | is ConnectException, is SocketException -> {
17 | if (message?.contains("Network is unreachable") == true)
18 | getString(R.string.Mobilenetuseless_msg)
19 | if (message?.contains("Failed to connect to") == true)
20 | getString(R.string.failed_to_connect_to)
21 | else
22 | getString(R.string.ConnectException)
23 | }
24 | is HttpException -> {
25 | if (message?.contains("HTTP 50") == true) {
26 | message!!.substring(0, 8)
27 | } else {
28 | getString(R.string.HttpException)
29 | }
30 | }
31 | is InterruptedIOException -> {
32 | if (message?.contains("timeout") == true)
33 | getString(R.string.SocketTimeoutException)
34 | else
35 | getString(R.string.ConnectException)
36 | }
37 | is UnknownHostException -> getString(R.string.UnknownHostException)
38 | is JsonSyntaxException -> getString(R.string.JsonSyntaxException)
39 | is SocketTimeoutException, is TimeoutException -> getString(R.string.SocketTimeoutException)
40 | is IllegalArgumentException -> {
41 | if (message?.contains("baseUrl must end in ") == true)
42 | if (AppGlobals.sApplication.isNetWorkActive()) getString(R.string.HostBaseUrlError)
43 | else getString(R.string.Mobilenetuseless_msg)
44 | else message ?: getString(R.string.ElseNetException)
45 | }
46 | else -> getString(R.string.ElseNetException)
47 | }
48 |
49 | fun getString(resID: Int) = AppGlobals.sApplication.getString(resID)
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/code/utils/NetWorkHelp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.utils
2 | import android.app.Application
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.NetworkCapabilities
6 | import android.os.Build
7 |
8 | fun Application.isNetWorkActive(): Boolean {
9 | val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
10 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
11 | val network = connectivityManager.activeNetwork ?: return false
12 | val activeNetwork =
13 | connectivityManager.getNetworkCapabilities(network) ?: return false
14 | return when {
15 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
16 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
17 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
18 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
19 | else -> false
20 | }
21 | } else {
22 | @Suppress("DEPRECATION") val networkInfo =
23 | connectivityManager.activeNetworkInfo ?: return false
24 | @Suppress("DEPRECATION")
25 | return networkInfo.isConnected
26 | }
27 | return true
28 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/data_source/repository/RepositoryPoxy.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.repository
2 |
3 | import com.wx.architecture.code.base.BaseRepositoryProxy
4 | import com.wx.test.api.net.NetApi
5 | import com.wx.test.api.retrofit.RetrofitUtils
6 | import kotlinx.coroutines.flow.Flow
7 | import kotlinx.coroutines.flow.flow
8 | import okhttp3.MultipartBody
9 | import okhttp3.RequestBody
10 | import retrofit2.Call
11 | import kotlin.reflect.full.callSuspend
12 | import kotlin.reflect.full.memberFunctions
13 | import kotlin.reflect.javaType
14 |
15 | class RepositoryPoxy private constructor() : BaseRepositoryProxy() {
16 |
17 | val service = NetApi::class.java
18 | val api by lazy { RetrofitUtils.instance.create(service) }
19 |
20 |
21 | companion object {
22 | val instance by lazy { RepositoryPoxy() }
23 | }
24 |
25 | fun callApiMethod(clazzR: Class, methodName: String, vararg args: Any): Flow {
26 | return flow {
27 | val clssss = mutableListOf>()
28 | args?.forEach {
29 | clssss.add(javaClassTransform(it.javaClass))
30 | }
31 | val parameterTypes = clssss.toTypedArray()
32 | val call = (service.getMethod(methodName, *parameterTypes)?.invoke(api, *(args ?: emptyArray())) as Call)
33 | call?.execute()?.body()?.let {
34 | emit(it as R)
35 | }
36 | }
37 | }
38 |
39 | @OptIn(ExperimentalStdlibApi::class)
40 | fun callApiSuspendMethod(clazzR: Class, methodName: String, vararg args: Any): Flow {
41 | return flow {
42 | val funcds = findSuspendMethod(service, methodName, args)
43 | if (args == null) {
44 | emit(funcds?.callSuspend(api) as R)
45 | } else {
46 | emit(funcds?.callSuspend(api, *args) as R)
47 | }
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/data_source/tata.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source
2 |
3 | class tata {
4 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/ui/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.activity
2 |
3 | import android.view.View
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.base.BaseViewModelActivity
6 | import com.wx.architecture.ui.viewmodel.MainViewModel
7 |
8 | class MainActivity : BaseViewModelActivity(R.layout.activity_main), View.OnClickListener {
9 |
10 | override fun onClick(v: View?) {
11 | when (v?.id) {
12 | R.id.btn1 -> {
13 | viewModel.getHomeList(1)
14 | }
15 | else -> {}
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/java/com/wx/architecture/ui/viewmodel/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.viewmodel
2 |
3 | import com.wx.architecture.code.base.BaseViewModel
4 | import com.wx.architecture.data_source.repository.RepositoryPoxy
5 | import com.wx.test.api.data.wanandroid.home.HomeData
6 | import kotlinx.coroutines.flow.onEach
7 |
8 | class MainViewModel : BaseViewModel() {
9 |
10 | private val repository by lazy { RepositoryPoxy.instance }
11 |
12 | fun getHomeList(page: Int) {
13 | flowAsyncWorkOnViewModelScopeLaunch {
14 | val time = System.currentTimeMillis()
15 | repository.callApiSuspendMethod(HomeData::class.java, "getHomeListB", page).onEach {
16 | errorMsgLiveData.postValue(it.data?.datas!![0].title)
17 | android.util.Log.e("MainViewModel", "four 444 ${it.data?.datas!![0].title}")
18 | android.util.Log.e("MainViewModel", "耗时:${(System.currentTimeMillis() - time)} ms")
19 | }
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/app_wx4/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/drawable-xhdpi/ic_loading.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/drawable-xhdpi/ic_loading.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/drawable/progressbar_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/layout/layout_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx4/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx4/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WXNetArchitecture
3 |
4 |
5 | 未知错误异常
6 | 网络超时
7 | 网络超时
8 | 网络错误
9 | 网络错误
10 | 服务器异常
11 | 无网络连接
12 | 请求地址错误
13 | 当前网络不可用
14 | 无法连接到服务器
15 | 数据错误,json解析错误
16 |
17 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
32 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app_wx4/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/app_wx_switch_net/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app_wx_switch_net/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'org.jetbrains.kotlin.android'
4 | id 'dagger.hilt.android.plugin'
5 | id 'kotlin-kapt'
6 | }
7 |
8 | android {
9 | compileSdk 32
10 |
11 | defaultConfig {
12 | applicationId "com.wx.wxnetarchitecture5"
13 | minSdk 21
14 | targetSdk 32
15 | versionCode 1
16 | versionName "1.0"
17 |
18 | // testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
19 | }
20 |
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | compileOptions {
28 | sourceCompatibility JavaVersion.VERSION_1_8
29 | targetCompatibility JavaVersion.VERSION_1_8
30 | }
31 | kotlinOptions {
32 | jvmTarget = '1.8'
33 | }
34 |
35 | kapt {
36 | generateStubs = true
37 | }
38 | }
39 |
40 | dependencies {
41 |
42 | implementation 'androidx.core:core-ktx:1.7.0'
43 | implementation 'androidx.appcompat:appcompat:1.3.0'
44 | implementation 'com.google.android.material:material:1.4.0'
45 |
46 | implementation 'com.squareup.retrofit2:retrofit:2.9.0'
47 | implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
48 | implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
49 | implementation 'com.squareup.okhttp3:okhttp:4.9.3'
50 | implementation 'com.squareup.okio:okio:2.10.0'
51 | implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
52 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
53 |
54 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
55 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
56 | implementation 'androidx.activity:activity-ktx:1.3.0-rc01'
57 | implementation 'androidx.fragment:fragment-ktx:1.4.0-alpha04'
58 |
59 | //hilt
60 | implementation "com.google.dagger:hilt-android:2.42"
61 | kapt "com.google.dagger:hilt-android-compiler:2.42"
62 | kapt 'androidx.hilt:hilt-compiler:1.0.0'
63 |
64 | implementation 'com.android.volley:volley:1.2.0'
65 |
66 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/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
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/MyApp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture
2 |
3 | import android.app.Application
4 | import com.wx.architecture.code.app.AppGlobals
5 | import dagger.hilt.android.HiltAndroidApp
6 |
7 | @HiltAndroidApp
8 | class MyApp : Application() {
9 |
10 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/app/AppGlobals.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.app
2 |
3 | import android.app.Application
4 |
5 | object AppGlobals {
6 | lateinit var sApplication: Application
7 |
8 | fun getApplication(): Application {
9 | if (!this::sApplication.isInitialized) {
10 | //去反射得到
11 | try {
12 | val aClass = Class.forName("android.app.ActivityThread")
13 | //获取里面的currentApplication
14 | val currentApplication = aClass.getDeclaredMethod("currentApplication")
15 | sApplication = currentApplication.invoke(null, *emptyArray()) as Application
16 | } catch (e: Exception) {
17 | e.printStackTrace()
18 | }
19 | }
20 | return sApplication
21 | }
22 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/base/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.fragment.app.Fragment
4 |
5 | class BaseFragment : Fragment() {
6 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.viewModelScope
6 | import com.wx.architecture.code.data.DialogBean
7 | import com.wx.architecture.code.ex.flowOnIOAndCatch
8 | import kotlinx.coroutines.CoroutineScope
9 | import kotlinx.coroutines.cancel
10 | import kotlinx.coroutines.flow.Flow
11 | import kotlinx.coroutines.flow.collect
12 | import kotlinx.coroutines.flow.onCompletion
13 | import kotlinx.coroutines.flow.onStart
14 | import kotlinx.coroutines.launch
15 |
16 | open class BaseViewModel : ViewModel() {
17 | val errorMsgLiveData by lazy { MutableLiveData() }
18 | val showUIDialog by lazy { MutableLiveData() }
19 |
20 | fun show(strMessage: String = "正在请求数据") {
21 | val showBean = showUIDialog.value ?: DialogBean(strMessage, true)
22 | showBean.isShow = true
23 | showBean.msg = strMessage
24 | showUIDialog.postValue(showBean)
25 | }
26 |
27 | fun hide() {
28 | val showBean = showUIDialog.value ?: DialogBean("", true)
29 | showBean.isShow = false
30 | showUIDialog.postValue(showBean)
31 | }
32 |
33 | override fun onCleared() {
34 | viewModelScope.cancel()
35 | }
36 |
37 | protected fun Flow.flowOnIOAndCatch(): Flow = flowOnIOAndCatch(errorMsgLiveData)
38 |
39 | protected fun Flow.onStartAndShow(strMessage: String = "正在请求数据"): Flow = onStart {
40 | show()
41 | }
42 |
43 | protected fun Flow.onCompletionAndHide(): Flow = onCompletion {
44 | hide()
45 | }
46 |
47 | protected suspend fun Flow.onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect() {
48 | onStartAndShow().onCompletionAndHide().flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
49 | }
50 |
51 | fun flowAsyncWorkOnViewModelScopeLaunch(flowAsyncWork: suspend () -> Flow) {
52 | viewModelScope.launch {
53 | flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
54 | }
55 | }
56 |
57 | fun flowAsyncWorkOnViewModelScopeLaunch2(block: suspend CoroutineScope.() -> Unit) {
58 | viewModelScope.launch {
59 | block.invoke(this)
60 | // flowAsyncWork.invoke().onStartShowAndFlowOnIOAndCatchAndOnCompletionAndHideAndCollect()
61 | }
62 | }
63 |
64 | // block: suspend CoroutineScope.() -> Unit
65 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/base/BaseViewModelActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.base
2 |
3 | import android.os.Bundle
4 | import android.widget.Toast
5 | import androidx.annotation.LayoutRes
6 | import androidx.annotation.MainThread
7 | import androidx.appcompat.app.AppCompatActivity
8 | import androidx.lifecycle.ViewModelLazy
9 | import com.wx.architecture.code.dialog.ShowUIDialog
10 | import java.lang.reflect.ParameterizedType
11 |
12 |
13 | open class BaseViewModelActivity(@LayoutRes val layResID: Int) : AppCompatActivity() {
14 | private var loading: ShowUIDialog? = null
15 |
16 | protected val viewModel by lazyViewModels()
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(layResID)
21 | initX()
22 | }
23 |
24 | protected fun initX() {
25 | bindObserve()
26 | }
27 |
28 | //是否loading
29 | open fun isShowloading(): Boolean? {
30 | return loading?.isShowing()
31 | }
32 |
33 | open fun showloading(showText: String?) {
34 | if (null == loading) loading = ShowUIDialog(this)
35 | if (isShowloading() == true) return
36 | if (showText != null) loading?.show(showText)
37 | }
38 |
39 | open fun hideLoading() {
40 | loading?.dismiss()
41 | loading = null
42 | }
43 |
44 | override fun onDestroy() {
45 | hideLoading()
46 | super.onDestroy()
47 | }
48 |
49 | protected fun bindObserve() {
50 | viewModel?.run {
51 | showUIDialog.observe(this@BaseViewModelActivity) { it ->
52 | if (it.isShow) showloading(it.msg) else hideLoading()
53 | }
54 | errorMsgLiveData.observe(this@BaseViewModelActivity) {
55 | //公共toast 提示样式可以自行封装
56 | Toast.makeText(this@BaseViewModelActivity, it, Toast.LENGTH_SHORT).show()
57 | }
58 | }
59 | }
60 |
61 | @MainThread
62 | inline fun lazyViewModels(): Lazy {
63 | val cls = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class
64 | return ViewModelLazy(cls.kotlin, { viewModelStore }, { defaultViewModelProviderFactory })
65 | }
66 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/data/DialogBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.data
2 |
3 | data class DialogBean(var msg:String, var isShow:Boolean){
4 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/dialog/ShowUIDialog.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.dialog
2 |
3 | import android.app.Dialog
4 | import android.content.Context
5 | import android.view.Gravity
6 | import android.view.View
7 | import android.widget.TextView
8 | import androidx.appcompat.app.AppCompatDialog
9 | import com.wx.architecture.R
10 |
11 | class ShowUIDialog : AppCompatDialog {
12 |
13 | lateinit var txt_loading_text: TextView
14 |
15 | constructor (context: Context) : super(context, R.style.Loading) {
16 | setContentView(R.layout.layout_loading)
17 | window?.run {
18 | txt_loading_text = findViewById(R.id.txt_loading_text)
19 | attributes.gravity = Gravity.CENTER
20 | }
21 | }
22 |
23 | fun show(showText: String) {
24 | txt_loading_text?.apply {
25 | if (showText.isNotEmpty()) {
26 | text = showText
27 | visibility = View.VISIBLE
28 | } else {
29 | visibility = View.GONE
30 | }
31 | }
32 | if (!isShowing()) {
33 | show()
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/ex/ExceptionEX.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | class ExceptionEX(val errorCode: Int, val errorMessage: String) : Exception(errorMessage) {
4 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/ex/Flow.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import kotlinx.coroutines.Dispatchers
5 | import kotlinx.coroutines.flow.*
6 | import java.lang.Exception
7 |
8 |
9 | fun Flow.flowOnIOAndCatch(errorMsgLiveData: MutableLiveData? = null): Flow =
10 | flowOn(Dispatchers.IO)
11 | .catch {
12 | it.printStackTrace()
13 | errorMsgLiveData?.value = it.parseErrorString();
14 | }
15 |
16 | suspend fun Flow.flowOnIOAndCatchAAndCollect() {
17 | flowOnIOAndCatch().collect()//这里,开始结束全放在异步里面处理
18 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/ex/Throwable.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.ex
2 |
3 | import com.google.gson.JsonSyntaxException
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.app.AppGlobals
6 | import com.wx.architecture.code.utils.isNetWorkActive
7 | import retrofit2.HttpException
8 | import java.io.InterruptedIOException
9 | import java.net.ConnectException
10 | import java.net.SocketException
11 | import java.net.SocketTimeoutException
12 | import java.net.UnknownHostException
13 | import java.util.concurrent.TimeoutException
14 |
15 | fun Throwable?.parseErrorString(): String = when (this) {
16 | is ConnectException, is SocketException -> {
17 | if (message?.contains("Network is unreachable") == true)
18 | getString(R.string.Mobilenetuseless_msg)
19 | if (message?.contains("Failed to connect to") == true)
20 | getString(R.string.failed_to_connect_to)
21 | else
22 | getString(R.string.ConnectException)
23 | }
24 | is HttpException -> {
25 | if (message?.contains("HTTP 50") == true) {
26 | message!!.substring(0, 8)
27 | } else {
28 | getString(R.string.HttpException)
29 | }
30 | }
31 | is InterruptedIOException -> {
32 | if (message?.contains("timeout") == true)
33 | getString(R.string.SocketTimeoutException)
34 | else
35 | getString(R.string.ConnectException)
36 | }
37 | is UnknownHostException -> getString(R.string.UnknownHostException)
38 | is JsonSyntaxException -> getString(R.string.JsonSyntaxException)
39 | is SocketTimeoutException, is TimeoutException -> getString(R.string.SocketTimeoutException)
40 | is IllegalArgumentException -> {
41 | if (message?.contains("baseUrl must end in ") == true)
42 | if (AppGlobals.getApplication().isNetWorkActive()) getString(R.string.HostBaseUrlError)
43 | else getString(R.string.Mobilenetuseless_msg)
44 | else message ?: getString(R.string.ElseNetException)
45 | }
46 | else -> getString(R.string.ElseNetException)
47 | }
48 |
49 | fun getString(resID: Int) = AppGlobals.getApplication().getString(resID)
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/utils/BuildParamUtils.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.utils
2 |
3 | import okhttp3.RequestBody
4 |
5 | object BuildParamUtils {
6 |
7 | fun buildParamUrl(url: String, map: MutableMap? = null): String {
8 | val sb = StringBuilder(url)
9 | .append("?")
10 | map?.forEach {
11 | sb.append(it.key)
12 | sb.append("=")
13 | sb.append(it.value)
14 | }
15 | return sb.toString()
16 | }
17 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/utils/NetWorkHelp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.utils
2 | import android.app.Application
3 | import android.content.Context
4 | import android.net.ConnectivityManager
5 | import android.net.NetworkCapabilities
6 | import android.os.Build
7 |
8 | fun Application.isNetWorkActive(): Boolean {
9 | val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
10 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
11 | val network = connectivityManager.activeNetwork ?: return false
12 | val activeNetwork =
13 | connectivityManager.getNetworkCapabilities(network) ?: return false
14 | return when {
15 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
16 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
17 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
18 | activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
19 | else -> false
20 | }
21 | } else {
22 | @Suppress("DEPRECATION") val networkInfo =
23 | connectivityManager.activeNetworkInfo ?: return false
24 | @Suppress("DEPRECATION")
25 | return networkInfo.isConnected
26 | }
27 | return true
28 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/code/utils/RequestBodyCreate.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.code.utils
2 |
3 | import okhttp3.MediaType.Companion.toMediaTypeOrNull
4 | import okhttp3.RequestBody
5 |
6 | object RequestBodyCreate {
7 |
8 | fun toBody(body: String) = RequestBody.create("application/json; charset=utf-8".toMediaTypeOrNull(), body)
9 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/data/CommonResult.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.data
2 |
3 | open class CommonResult {
4 | var data: T? = null
5 | var errorCode: Int? = 0
6 | var errorMsg: String? = null
7 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/data/HomeData.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.data
2 |
3 |
4 | class HomeData : CommonResult() {
5 | }
6 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/data/HomeItemBean.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.data
2 |
3 | data class HomeItemBean(
4 | val author:String,
5 | val chapterName:String,
6 | val link:String,
7 | val title:String
8 | )
9 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/data/WanAndroidHome.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.data
2 |
3 | data class WanAndroidHome(
4 | val datas: MutableList,
5 | val curPage: Int,
6 | val size: Int,
7 | val total: Int
8 | )
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/dl_hilt/AbstractHttp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.dl_hilt
2 |
3 | import com.wx.architecture.data_source.dl_hilt.annotation.BindHttpUrlConnection
4 | import com.wx.architecture.data_source.dl_hilt.annotation.BindOkhttp
5 | import com.wx.architecture.data_source.net.HttpUrlConnectionImpl
6 | import com.wx.architecture.data_source.net.INetApi
7 | import com.wx.architecture.data_source.net.OkhttpImpl
8 | import dagger.Binds
9 | import dagger.Module
10 | import dagger.hilt.InstallIn
11 | import dagger.hilt.components.SingletonComponent
12 | import javax.inject.Singleton
13 |
14 | @InstallIn(SingletonComponent::class)
15 | @Module
16 | abstract class AbstractHttp {
17 |
18 | @BindOkhttp
19 | @Singleton
20 | @Binds
21 | abstract fun bindOkhttp(h: OkhttpImpl): INetApi
22 |
23 | @BindHttpUrlConnection
24 | @Singleton
25 | @Binds
26 | abstract fun bindHttpUrlConnection(h: HttpUrlConnectionImpl): INetApi
27 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/dl_hilt/annotation/BindHttpUrlConnection.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.dl_hilt.annotation
2 |
3 | import java.lang.annotation.Retention
4 | import java.lang.annotation.RetentionPolicy
5 | import javax.inject.Qualifier
6 |
7 | @Qualifier
8 | @Retention(RetentionPolicy.RUNTIME)
9 | annotation class BindHttpUrlConnection()
10 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/dl_hilt/annotation/BindOkhttp.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.dl_hilt.annotation
2 |
3 | import java.lang.annotation.Retention
4 | import java.lang.annotation.RetentionPolicy
5 | import javax.inject.Qualifier
6 |
7 | @Qualifier
8 | @Retention(RetentionPolicy.RUNTIME)
9 | annotation class BindOkhttp()
10 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/net/HttpUrlConnectionImpl.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.net
2 |
3 | import com.google.gson.Gson
4 | import com.wx.architecture.code.utils.BuildParamUtils
5 | import com.wx.architecture.data_source.net.http.HttpUrlConnectionRequest
6 | import javax.inject.Inject
7 |
8 | class HttpUrlConnectionImpl @Inject constructor() : INetApi {
9 | private val gson by lazy { Gson() }
10 |
11 | override suspend fun getApi(url: String, clazzR: Class, header: MutableMap?, map: MutableMap?): R {
12 | val json = HttpUrlConnectionRequest.getResult(BuildParamUtils.buildParamUrl(url, map), header)
13 | android.util.Log.e("OkhttpImpl", "HttpUrlConnection 请求:${json}")
14 | return gson.fromJson(json, clazzR)
15 | }
16 |
17 | override suspend fun postApi(url: String, clazzR: Class, header: MutableMap?, body: String?): R {
18 | val json = HttpUrlConnectionRequest.postData(url, header, body)
19 | return gson.fromJson(json, clazzR)
20 | }
21 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/net/INetApi.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.net
2 |
3 | interface INetApi {
4 | /**
5 | * Get请求
6 | * @param url:请求地址
7 | * @param clazzR:返回对象类型
8 | * @param header:请求头
9 | * @param map:请求参数
10 | */
11 |
12 | suspend fun getApi(url: String, clazzR: Class, header: MutableMap? = null, map: MutableMap? = null): R
13 |
14 | /**
15 | * Get请求
16 | * @param url:请求地址
17 | * @param clazzR:返回对象类型
18 | * @param header:请求头
19 | * @param map:请求参数
20 | * @param body:请求body
21 | */
22 | suspend fun postApi(url: String, clazzR: Class, header: MutableMap? = null, body: String? = null): R
23 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/net/OkhttpImpl.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.net
2 |
3 | import com.google.gson.Gson
4 | import com.wx.architecture.code.utils.BuildParamUtils.buildParamUrl
5 | import com.wx.architecture.code.utils.RequestBodyCreate
6 | import okhttp3.OkHttpClient
7 | import okhttp3.Request
8 | import javax.inject.Inject
9 |
10 | class OkhttpImpl @Inject constructor() : INetApi {
11 |
12 | private val okHttpClient by lazy { OkHttpClient() }
13 | private val gson by lazy { Gson() }
14 |
15 | override suspend fun getApi(url: String, clazzR: Class, header: MutableMap?, map: MutableMap?): R {
16 | try {
17 | val request = Request.Builder().url(buildParamUrl(url, map))
18 | header?.forEach {
19 | request.addHeader(it.key, it.value)
20 | }
21 | val response = okHttpClient.newCall(request.build()).execute()
22 | if (response.isSuccessful) {
23 | val json = response.body?.string()
24 | android.util.Log.e("OkhttpImpl","okhttp 请求:${json}")
25 | return gson.fromJson(json, clazzR)
26 | } else {
27 | throw RuntimeException("response fail")
28 | }
29 | } catch (e: Exception) {
30 | throw e
31 | }
32 | }
33 |
34 | override suspend fun postApi(url: String, clazzR: Class, header: MutableMap?, body: String?): R {
35 | try {
36 | val request = Request.Builder().url(url)
37 | header?.forEach {
38 | request.addHeader(it.key, it.value)
39 | }
40 | body?.let {
41 | request.post(RequestBodyCreate.toBody(it))
42 | }
43 | val response = okHttpClient.newCall(request.build()).execute()
44 | if (response.isSuccessful) {
45 | return gson.fromJson(response.body.toString(), clazzR)
46 | } else {
47 | throw RuntimeException("response fail")
48 | }
49 | } catch (e: Exception) {
50 | throw e
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/net/http/HttpURLConnectionUtils.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.net.http
2 |
3 | import java.security.SecureRandom
4 | import java.security.cert.CertificateException
5 | import java.security.cert.X509Certificate
6 | import javax.net.ssl.*
7 |
8 | object HttpURLConnectionUtils {
9 | var mSSLSocketFactory: SSLSocketFactory? = null
10 |
11 | /**
12 | * 信任所有host
13 | */
14 | val hnv = HostnameVerifier { _, _ -> true }
15 |
16 | /**
17 | * 设置https
18 | *
19 | * @author :Atar
20 | * @createTime:2015-9-17下午4:57:39
21 | * @version:1.0.0
22 | * @modifyTime:
23 | * @modifyAuthor:
24 | * @description:
25 | */
26 | fun trustAllHosts() {
27 | try {
28 | val trustAllCerts = arrayOf(object : X509TrustManager {
29 | override fun getAcceptedIssuers(): Array {
30 | return arrayOf()
31 | }
32 |
33 | @Throws(CertificateException::class)
34 | override fun checkClientTrusted(chain: Array, authType: String) {
35 | }
36 |
37 | @Throws(CertificateException::class)
38 | override fun checkServerTrusted(chain: Array, authType: String) {
39 | }
40 | })
41 | val sc = SSLContext.getInstance("TLS")
42 | sc.init(null, trustAllCerts, SecureRandom())
43 | if (mSSLSocketFactory == null) {
44 | mSSLSocketFactory = sc.socketFactory
45 | }
46 | HttpsURLConnection.setDefaultHostnameVerifier(hnv)
47 | HttpsURLConnection.setDefaultSSLSocketFactory(mSSLSocketFactory)
48 | } catch (e: Exception) {
49 | e.printStackTrace()
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/repository/NetRepository.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source.repository
2 |
3 | import com.wx.architecture.data_source.data.HomeData
4 | import com.wx.architecture.data_source.data.WanAndroidHome
5 | import com.wx.architecture.data_source.dl_hilt.annotation.BindHttpUrlConnection
6 | import com.wx.architecture.data_source.dl_hilt.annotation.BindOkhttp
7 | import com.wx.architecture.data_source.net.INetApi
8 | import kotlinx.coroutines.flow.Flow
9 | import kotlinx.coroutines.flow.flow
10 | import javax.inject.Inject
11 |
12 |
13 | //class NetRepository @Inject constructor(@BindHttpUrlConnection val netHttp: INetApi) {
14 | class NetRepository @Inject constructor(@BindOkhttp val netHttp: INetApi) {
15 |
16 | suspend fun getHomeList(): Flow {
17 | return flow {
18 | netHttp.getApi("https://www.wanandroid.com/article/list/0/json", HomeData::class.java).data?.let { emit(it) }
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/data_source/tata.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.data_source
2 |
3 | class tata {
4 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/ui/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.activity
2 |
3 | import android.view.View
4 | import com.wx.architecture.R
5 | import com.wx.architecture.code.base.BaseViewModelActivity
6 | import com.wx.architecture.ui.viewmodel.MainViewModel
7 | import dagger.hilt.android.AndroidEntryPoint
8 |
9 | @AndroidEntryPoint
10 | class MainActivity : BaseViewModelActivity(R.layout.activity_main), View.OnClickListener {
11 |
12 | override fun onClick(v: View?) {
13 | when (v?.id) {
14 | R.id.btn1 -> {
15 | viewModel.getHomeList()
16 | }
17 | else -> {}
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/java/com/wx/architecture/ui/viewmodel/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.wx.architecture.ui.viewmodel
2 |
3 | import com.wx.architecture.code.base.BaseViewModel
4 | import com.wx.architecture.data_source.repository.NetRepository
5 | import dagger.hilt.android.lifecycle.HiltViewModel
6 | import kotlinx.coroutines.flow.onEach
7 | import javax.inject.Inject
8 |
9 | @HiltViewModel
10 | class MainViewModel @Inject constructor(private val repository: NetRepository) : BaseViewModel() {
11 |
12 |
13 | fun getHomeList() {
14 | flowAsyncWorkOnViewModelScopeLaunch {
15 | repository.getHomeList().onEach {
16 | val title = it.datas!![0].title
17 | android.util.Log.e("MainViewModel", "one 111 ${title}")
18 | errorMsgLiveData.postValue(title)
19 | }
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/drawable-xhdpi/ic_loading.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/drawable-xhdpi/ic_loading.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/drawable/progressbar_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/layout/layout_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
20 |
21 |
29 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/app_wx_switch_net/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WXNetArchitecture
3 |
4 |
5 | 未知错误异常
6 | 网络超时
7 | 网络超时
8 | 网络错误
9 | 网络错误
10 | 服务器异常
11 | 无网络连接
12 | 请求地址错误
13 | 当前网络不可用
14 | 无法连接到服务器
15 | 数据错误,json解析错误
16 |
17 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
32 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/xml/backup_rules.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/app_wx_switch_net/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 |
13 |
19 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | dependencies {
5 | classpath 'com.google.dagger:hilt-android-gradle-plugin:2.42'
6 | }
7 | }
8 |
9 | plugins {
10 | id 'com.android.application' version '7.2.1' apply false
11 | id 'com.android.library' version '7.2.1' apply false
12 | id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
13 | }
14 |
15 |
16 |
17 | task clean(type: Delete) {
18 | delete rootProject.buildDir
19 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wgllss/WXNetArchitecture/0e8477a47090eb8366d5a4c6735a8b3b39f4145f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 20 17:28:29 CST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 | rootProject.name = "WXNetArchitecture"
16 | include ':app_wx1'
17 | include ':app_wx2'
18 | include ':app_wx3'
19 | include ':app_wx4'
20 | include ':app_wx_switch_net'
21 | include ':annotation_compiler'
22 | include ':NetworkApiData'
23 |
--------------------------------------------------------------------------------