├── net ├── .gitignore ├── consumer-rules.pro ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── drake │ │ │ └── net │ │ │ ├── utils │ │ │ ├── LegacyTLS.kt │ │ │ └── TipUtils.kt │ │ │ ├── time │ │ │ └── IntervalStatus.kt │ │ │ ├── request │ │ │ └── Method.kt │ │ │ ├── reflect │ │ │ └── TypeUtils.kt │ │ │ ├── cache │ │ │ └── CacheMode.kt │ │ │ ├── interceptor │ │ │ └── RequestInterceptor.kt │ │ │ ├── exception │ │ │ ├── NetConnectException.kt │ │ │ ├── NetworkingException.kt │ │ │ ├── NetUnknownHostException.kt │ │ │ ├── HttpFailureException.kt │ │ │ ├── NetSocketTimeoutException.kt │ │ │ ├── URLParseException.kt │ │ │ ├── ConvertException.kt │ │ │ ├── DownloadFileException.kt │ │ │ ├── RequestParamsException.kt │ │ │ ├── ServerResponseException.kt │ │ │ ├── ResponseException.kt │ │ │ ├── HttpResponseException.kt │ │ │ └── NoCacheException.kt │ │ │ ├── transform │ │ │ └── DeferredTransform.kt │ │ │ ├── log │ │ │ └── MessageType.kt │ │ │ ├── okhttp │ │ │ └── OkHttpExtension.kt │ │ │ ├── interfaces │ │ │ └── ProgressListener.kt │ │ │ └── internal │ │ │ └── NetInitializer.kt │ │ └── res │ │ ├── xml │ │ └── network_security_config.xml │ │ └── drawable │ │ ├── ic_limited_time.xml │ │ └── ic_timing.xml └── build.gradle ├── sample ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── raw │ │ │ │ ├── config.json │ │ │ │ ├── user.json │ │ │ │ ├── data.json │ │ │ │ └── array.json │ │ │ ├── drawable │ │ │ │ ├── bg_empty.webp │ │ │ │ ├── bg_error.webp │ │ │ │ ├── bg_input.xml │ │ │ │ ├── bg_card.xml │ │ │ │ ├── ic_convert.xml │ │ │ │ ├── ic_menu.xml │ │ │ │ ├── ic_interceptor.xml │ │ │ │ ├── ic_unique.xml │ │ │ │ ├── ic_fastest.xml │ │ │ │ ├── ic_sync_request.xml │ │ │ │ ├── ic_callback_request.xml │ │ │ │ ├── ic_parallel_network.xml │ │ │ │ ├── ic_pull_refresh.xml │ │ │ │ ├── ic_scope.xml │ │ │ │ ├── ic_async_task.xml │ │ │ │ ├── ic_download_file.xml │ │ │ │ ├── ic_upload_file.xml │ │ │ │ ├── ic_switch_dispatcher.xml │ │ │ │ ├── ic_read_cache.xml │ │ │ │ ├── ic_interval.xml │ │ │ │ ├── ic_simple_request.xml │ │ │ │ ├── ic_state_layout.xml │ │ │ │ ├── ic_view_model.xml │ │ │ │ ├── ic_push_refresh.xml │ │ │ │ ├── ic_exception_trace.xml │ │ │ │ ├── ic_error_handler.xml │ │ │ │ ├── ic_debounce.xml │ │ │ │ ├── ic_config_dialog.xml │ │ │ │ └── ic_https.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── styles.xml │ │ │ │ └── colors.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── menu │ │ │ │ ├── menu_download.xml │ │ │ │ ├── menu_converter.xml │ │ │ │ ├── menu_interval.xml │ │ │ │ └── menu_request_method.xml │ │ │ ├── layout │ │ │ │ ├── layout_loading.xml │ │ │ │ ├── fragment_pull_refresh.xml │ │ │ │ ├── fragment_fastest.xml │ │ │ │ ├── fragment_sync_request.xml │ │ │ │ ├── fragment_async_task.xml │ │ │ │ ├── fragment_callback_request.xml │ │ │ │ ├── fragment_interceptor.xml │ │ │ │ ├── fragment_coroutine_scope.xml │ │ │ │ ├── fragment_exception_trace.xml │ │ │ │ ├── fragment_error_handler.xml │ │ │ │ ├── fragment_parallel_network.xml │ │ │ │ ├── fragment_simple_request.xml │ │ │ │ ├── fragment_switch_dispatcher.xml │ │ │ │ ├── fragment_super_interval.xml │ │ │ │ ├── fragment_auto_dialog.xml │ │ │ │ ├── fragment_read_cache.xml │ │ │ │ ├── fragment_state_layout.xml │ │ │ │ ├── fragment_push_refresh.xml │ │ │ │ ├── fragment_limited_time.xml │ │ │ │ ├── fragment_custom_convert.xml │ │ │ │ ├── item_game.xml │ │ │ │ ├── item_pull_list.xml │ │ │ │ ├── layout_empty.xml │ │ │ │ ├── fragment_edit_debounce.xml │ │ │ │ ├── layout_error.xml │ │ │ │ ├── fragment_https_certificate.xml │ │ │ │ ├── fragment_upload_file.xml │ │ │ │ ├── fragment_view_model_request.xml │ │ │ │ ├── fragment_download_file.xml │ │ │ │ ├── fragment_timing_request.xml │ │ │ │ ├── activity_main.xml │ │ │ │ ├── fragment_unique_request.xml │ │ │ │ └── layout_drawer_nav_header.xml │ │ │ └── navigation │ │ │ │ └── nav_converter.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── drake │ │ │ │ └── net │ │ │ │ └── sample │ │ │ │ ├── model │ │ │ │ ├── ArrayData.kt │ │ │ │ ├── SubData.kt │ │ │ │ ├── BasicData.kt │ │ │ │ ├── ConfigModel.kt │ │ │ │ ├── TokenModel.kt │ │ │ │ ├── UserInfoModel.kt │ │ │ │ └── GameModel.kt │ │ │ │ ├── constants │ │ │ │ ├── UserConfig.kt │ │ │ │ └── Api.kt │ │ │ │ ├── interceptor │ │ │ │ ├── GlobalHeaderInterceptor.kt │ │ │ │ ├── RefreshTokenInterceptor.kt │ │ │ │ └── EncryptDataInterceptor.kt │ │ │ │ ├── converter │ │ │ │ ├── FastJsonConverter.kt │ │ │ │ ├── GsonConverter.kt │ │ │ │ ├── MoshiConverter.kt │ │ │ │ └── ProtobufConverter.kt │ │ │ │ ├── ui │ │ │ │ ├── fragment │ │ │ │ │ ├── StateLayoutFragment.kt │ │ │ │ │ ├── ExceptionTraceFragment.kt │ │ │ │ │ ├── InterceptorFragment.kt │ │ │ │ │ ├── ErrorHandlerFragment.kt │ │ │ │ │ ├── SwitchDispatcherFragment.kt │ │ │ │ │ ├── AsyncTaskFragment.kt │ │ │ │ │ ├── ParallelNetworkFragment.kt │ │ │ │ │ ├── ReadCacheFragment.kt │ │ │ │ │ ├── converter │ │ │ │ │ │ ├── FastJsonConvertFragment.kt │ │ │ │ │ │ ├── GsonConvertFragment.kt │ │ │ │ │ │ ├── MoshiConvertFragment.kt │ │ │ │ │ │ ├── BaseConvertFragment.kt │ │ │ │ │ │ └── SerializationConvertFragment.kt │ │ │ │ │ ├── SyncRequestFragment.kt │ │ │ │ │ ├── UniqueRequestFragment.kt │ │ │ │ │ ├── AutoDialogFragment.kt │ │ │ │ │ ├── PullRefreshFragment.kt │ │ │ │ │ ├── PushRefreshFragment.kt │ │ │ │ │ ├── CallbackRequestFragment.kt │ │ │ │ │ ├── ViewModelRequestFragment.kt │ │ │ │ │ ├── CoroutineScopeFragment.kt │ │ │ │ │ ├── PreviewCacheFragment.kt │ │ │ │ │ ├── LimitedTimeFragment.kt │ │ │ │ │ ├── SuperIntervalFragment.kt │ │ │ │ │ └── HttpsCertificateFragment.kt │ │ │ │ └── activity │ │ │ │ │ └── MainActivity.kt │ │ │ │ ├── contract │ │ │ │ └── AlbumSelectContract.kt │ │ │ │ ├── utils │ │ │ │ ├── HttpUtils.kt │ │ │ │ └── AESUtils.kt │ │ │ │ └── vm │ │ │ │ └── UserViewModel.kt │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── drake │ │ │ └── net │ │ │ └── ExampleUnitTest.kt │ └── androidTest │ │ └── java │ │ └── com │ │ └── drake │ │ └── net │ │ └── ExampleInstrumentedTest.kt └── proguard-rules.pro ├── settings.gradle ├── signed ├── docs ├── img │ ├── logo.gif │ ├── preview.png │ ├── code-preview.png │ ├── book-open.svg │ ├── discussesions.svg │ └── issues.svg ├── api │ ├── styles │ │ ├── logo-styles.css │ │ └── jetbrains-mono.css │ ├── images │ │ ├── logo-icon.svg │ │ ├── copy-icon.svg │ │ ├── footer-go-to-link.svg │ │ ├── arrow_down.svg │ │ ├── copy-successful-icon.svg │ │ ├── go-to-top-icon.svg │ │ ├── anchor-copy-button.svg │ │ └── docs_logo.svg │ └── scripts │ │ ├── sourceset_dependencies.js │ │ └── clipboard.js ├── repeat-request.md ├── track.md ├── callback.md ├── error.md ├── coroutine-request.md ├── issues.md ├── cookie.md ├── sync-request.md ├── error-global.md ├── upload-file.md ├── auto-pull.md ├── cancel.md ├── okhttp-client.md ├── log-notice.md ├── debounce.md ├── error-single.md ├── interval.md ├── timing.md ├── view-model.md ├── https.md ├── download-file.md ├── model-generate.md ├── auto-refresh.md ├── css │ └── extra.css ├── converter.md └── interceptor.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .github ├── workflows │ └── main.yml └── ISSUE_TEMPLATE │ └── ----.md ├── gradle.properties └── LICENSE /net/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release 3 | -------------------------------------------------------------------------------- /sample/src/main/res/raw/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "maintain": false 3 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':sample', ':net' 2 | rootProject.name='Net' 3 | -------------------------------------------------------------------------------- /signed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/signed -------------------------------------------------------------------------------- /docs/img/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/docs/img/logo.gif -------------------------------------------------------------------------------- /docs/api/styles/logo-styles.css: -------------------------------------------------------------------------------- 1 | #logo { 2 | background-image: url(../images/docs_logo.svg); 3 | } -------------------------------------------------------------------------------- /docs/img/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/docs/img/preview.png -------------------------------------------------------------------------------- /net/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -keep class okhttp3.** { *; } 2 | -keep class com.drake.net.exception.** { *; } -------------------------------------------------------------------------------- /docs/img/code-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/docs/img/code-preview.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /sample/src/main/res/raw/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "userId": 23123132, 3 | "username": "test_account", 4 | "age": 17, 5 | "balance": "123.24" 6 | } -------------------------------------------------------------------------------- /sample/src/main/res/drawable/bg_empty.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/drawable/bg_empty.webp -------------------------------------------------------------------------------- /sample/src/main/res/drawable/bg_error.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/drawable/bg_error.webp -------------------------------------------------------------------------------- /sample/src/main/res/raw/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 0, 3 | "msg": "OK", 4 | "data": { 5 | "title": "标题", 6 | "name": "名称" 7 | } 8 | } -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/Net-okhttp3/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/model/ArrayData.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.model 2 | 3 | class ArrayData { 4 | var title: String = "" 5 | var name: String = "" 6 | } -------------------------------------------------------------------------------- /docs/api/images/logo-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/model/SubData.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.model 2 | 3 | class SubData : BasicData() { 4 | var title: String = "" 5 | var name: String = "" 6 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/navEditor.xml 5 | /.idea/assetWizardSettings.xml 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | .cxx 11 | /.idea/ 12 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/model/BasicData.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.model 2 | 3 | open class BasicData { 4 | val code: String = "" 5 | val msg: String = "" 6 | val data: T? = null 7 | } 8 | -------------------------------------------------------------------------------- /docs/img/book-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/model/ConfigModel.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.model 2 | 3 | 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ConfigModel( 8 | var maintain: Boolean = false 9 | ) -------------------------------------------------------------------------------- /docs/api/images/copy-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/api/images/footer-go-to-link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/bg_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/model/TokenModel.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.model 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class TokenModel( 7 | var token: String = "", 8 | var isExpired: Boolean = false 9 | ) -------------------------------------------------------------------------------- /docs/api/images/arrow_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Jul 28 17:18:47 CST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /docs/api/scripts/sourceset_dependencies.js: -------------------------------------------------------------------------------- 1 | sourceset_dependencies='{":net:dokkaHtml/androidTestRelease":[],":net:dokkaHtml/debug":[],":net:dokkaHtml/main":[],":net:dokkaHtml/release":[],":net:dokkaHtml/testFixtures":[],":net:dokkaHtml/testFixturesDebug":[],":net:dokkaHtml/testFixturesRelease":[]}' 2 | -------------------------------------------------------------------------------- /sample/src/main/res/raw/array.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "标题", 4 | "name": "名称" 5 | }, 6 | { 7 | "title": "标题", 8 | "name": "名称" 9 | }, 10 | { 11 | "title": "标题", 12 | "name": "名称" 13 | }, 14 | { 15 | "title": "标题", 16 | "name": "名称" 17 | } 18 | ] -------------------------------------------------------------------------------- /docs/api/images/copy-successful-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/api/images/go-to-top-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Net 3 | 4 | Hello blank fragment 5 | assertk.Assert 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/model/UserInfoModel.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.model 2 | 3 | 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class UserInfoModel( 8 | var userId: Int = 0, 9 | var username: String = "", 10 | var age: Int = 0, 11 | var balance: String = "" 12 | ) -------------------------------------------------------------------------------- /sample/src/main/res/drawable/bg_card.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/res/menu/menu_download.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_convert.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions/setup-python@v2 12 | with: 13 | python-version: 3.x 14 | - run: pip install mkdocs-material 15 | - run: mkdocs gh-deploy --force 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/----.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 提交问题 3 | about: 详细的描述可以快速解决问题 4 | title: '' 5 | labels: 寻求帮助 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 问题描述 11 | 12 | ### 期望行为 13 | 14 | ## 如何复现 15 | 16 | > fork仓库并复现问题可以快速解决, 猜测只会让问题晦涩难懂, 耽误所有人时间 17 | 18 | ## 截图 19 | 20 | 异常堆栈信息或者手机截图/视频(拖拽到输入框即可上传) 21 | 22 | ## 版本 23 | - Net: 24 | - OkHttp: 25 | - Android: 26 | - Gradle: 27 | - Android Studio: 28 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_menu.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_interceptor.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_unique.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_fastest.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_sync_request.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_callback_request.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_parallel_network.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/test/java/com/drake/net/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/repeat-request.md: -------------------------------------------------------------------------------- 1 | 常用于筛选列表请求, 选择新的筛选条件时应将上次未完成的取消后再发起请求 2 | 3 | 在Net禁止重复请求仅2行代码 4 | 5 | ```kotlin hl_lines="4" 6 | var scope: AndroidScope? = null 7 | 8 | btnFilter.setOnClickListener { 9 | scope?.cancel() 10 | 11 | scope = scopeNetLife { 12 | val result = Post(Api.PATH).await() 13 | } 14 | } 15 | ``` 16 | 17 | 当`scope`不为空时表示存在旧请求, 无论旧请求是否完成都可以调用`cancel()`保证取消即可 18 | 19 | 1. [取消请求](cancel.md)
20 | 2. 限制时间强制使用缓存, [配置缓存有效期](cache.md#_3) -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_pull_refresh.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /docs/track.md: -------------------------------------------------------------------------------- 1 | Net中网络请求异常会LogCat输出, 除非开发者修改全局错误处理 2 | 3 | 4 | 演示访问一个不存在的请求路径 5 | ```kotlin 6 | scopeNetLife { 7 | tv.text = Get("https://error.com/net/").await() 8 | } 9 | ``` 10 | 11 | LogCat可以看到异常堆栈信息, 包含具体Url和代码位置 12 | 13 | 14 | 15 | 16 | ### 关闭日志 17 | 18 | 可以关闭日志打印 19 | 20 | ```kotlin 21 | NetConfig.initialize(Api.HOST, this) { 22 | setDebug(false) // 关闭日志, 一般使用 BuildConfig.DEBUG 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_scope.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_async_task.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/layout_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /docs/callback.md: -------------------------------------------------------------------------------- 1 | Net支持OkHttp的原有的队列请求`Callback` 2 | 3 | !!! Failure "不推荐" 4 | Callback属于接口回调, 其代码冗余, 且无法支持并发请求 5 | 6 | 7 | ```kotlin 8 | Net.post(Api.PATH).enqueue(object : Callback { 9 | override fun onFailure(call: Call, e: IOException) { 10 | } 11 | 12 | override fun onResponse(call: Call, response: Response) { 13 | // 此处为子线程 14 | val body = response.body?.string() ?: "无数据" 15 | runMain { 16 | // 此处为主线程 17 | tv.text = body 18 | } 19 | } 20 | }) 21 | ``` -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/constants/UserConfig.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.constants 2 | 3 | import com.drake.serialize.serialize.annotation.SerializeConfig 4 | import com.drake.serialize.serialize.serialLazy 5 | 6 | 7 | /** 8 | * 本单例类使用 https://github.com/liangjingkanji/Serialize 为字段提供持久化存储 9 | */ 10 | @SerializeConfig(mmapID = "user_config") 11 | object UserConfig { 12 | 13 | var token by serialLazy(default = "6cad0ff06f5a214b9cfdf2a4a7c432339") 14 | 15 | var isLogin by serialLazy(default = false) 16 | } -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_download_file.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_upload_file.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_switch_dispatcher.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /docs/error.md: -------------------------------------------------------------------------------- 1 | Net有完善的错误处理机制, 具备捕获异常/取消请求/错误提示/追踪链路 2 | 3 | !!! success "收集网络日志" 4 | 在Net作用域内发生的异常都会被全局错误处理捕获, 可以将其筛选上传日志 5 | 6 |
7 | 以下位置抛出异常会被捕获 8 | 9 | | 函数 | 描述 | 10 | |-|-| 11 | | 作用域 | `scopeXX`代码块中 | 12 | | 拦截器 | `Interceptor/RequestInterceptor` | 13 | | 转换器 | `NetConverter` | 14 | 15 | 如果捕获到错误默认会执行以下操作 16 | 17 | 1. `Logcat`输出异常堆栈信息, [自定义异常抛出](error-throws.md) 18 | 2. `Toast`显示错误文本, [自定义错误提示](error-tip.md) 19 | 20 |
21 | !!! failure "捕获不到异常" 22 | 如果请求未执行`await()`, 那么即使发生错误也不会被捕获到 23 | 24 |
25 | 自定义请阅读[全局错误处理](error-global.md) -------------------------------------------------------------------------------- /docs/coroutine-request.md: -------------------------------------------------------------------------------- 1 | Net的协程作用域会自动处理协程生命周期 2 | 3 | 在上章节已经介绍如何发起并发网络请求, 这里演示同时(并发)请求`一万次`, 然后取消全部 4 | 5 | ```kotlin 6 | val job = scopeNetLife { 7 | repeat(10000) { 8 | // 这里将返回的数据显示在TextView上 9 | launch { 10 | tv.text = Get(Api.PATH).await() 11 | } 12 | } 13 | } 14 | ``` 15 | 16 | 17 | 等待五秒后取消请求 18 | ```kotlin 19 | thread { 20 | Thread.sleep(5000) // 等待五秒 21 | job.cancel() 22 | } 23 | ``` 24 | 25 |
26 | 27 | Net主要使用协程请求, 但也支持其他方式发起请求 28 | 29 | - [同步请求](sync-request.md) 30 | - [回调请求](callback.md) 31 | - 协程请求 32 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/constants/Api.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.constants 2 | 3 | 4 | /* 5 | 建议请求路径都写在一个单例类中, 方便查找和替换 6 | */ 7 | object Api { 8 | const val HOST = "http://127.0.0.1:8091" 9 | 10 | const val TEXT = "/text" 11 | const val DELAY = "/delay" 12 | const val UPLOAD = "/upload" 13 | const val GAME = "/game" 14 | const val DATA = "/data" 15 | const val ARRAY = "/array" 16 | const val CONFIG = "/config" 17 | const val USER_INFO = "/userInfo" 18 | const val TIME = "/time" 19 | const val Token = "/token" 20 | } -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/interceptor/GlobalHeaderInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.interceptor 2 | 3 | import com.drake.net.interceptor.RequestInterceptor 4 | import com.drake.net.request.BaseRequest 5 | import com.drake.net.sample.constants.UserConfig 6 | 7 | 8 | /** 演示添加全局请求头/参数 */ 9 | class GlobalHeaderInterceptor : RequestInterceptor { 10 | 11 | /** 本方法每次请求发起都会调用, 这里添加的参数可以是动态参数 */ 12 | override fun interceptor(request: BaseRequest) { 13 | request.setHeader("client", "Android") 14 | request.setHeader("token", UserConfig.token) 15 | } 16 | } -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_read_cache.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_interval.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/menu/menu_converter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_simple_request.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/converter/FastJsonConverter.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.converter 2 | 3 | import com.alibaba.fastjson.JSON 4 | import com.drake.net.convert.JSONConvert 5 | import org.json.JSONObject 6 | import java.lang.reflect.Type 7 | 8 | class FastJsonConverter : JSONConvert(code = "errorCode", message = "errorMsg", success = "0") { 9 | 10 | override fun String.parseBody(succeed: Type): R? { 11 | val string = try { 12 | JSONObject(this).getString("data") 13 | } catch (e: Exception) { 14 | this 15 | } 16 | return JSON.parseObject(string, succeed) 17 | } 18 | } -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/model/GameModel.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.model 2 | 3 | @kotlinx.serialization.Serializable 4 | data class GameModel( 5 | var total: Int = 0, 6 | var list: List = listOf() 7 | ) { 8 | 9 | @kotlinx.serialization.Serializable 10 | data class Data( 11 | var id: Int = 0, 12 | var img: String = "", 13 | var name: String = "", 14 | var label: List = listOf(), 15 | var price: String = "", 16 | var initialPrice: String = "", 17 | var grade: Int = 0, 18 | var discount: Double = 0.0, 19 | var endTime: Int = 0 20 | ) 21 | } -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_state_layout.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_view_model.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /sample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #2FA8E6 5 | #2FA8E6 6 | #F44336 7 | 8 | 9 | #339e9e9e 10 | #fafafa 11 | #737373 12 | 13 | 14 | #333333 15 | #999999 16 | 17 | 18 | #FFFFFF 19 | #F44336 20 | #000000 21 | 22 | 23 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_pull_refresh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 12 | 13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/issues.md: -------------------------------------------------------------------------------- 1 | Net最大的特点在于完美支持OkHttp的所有功能组件, 而OkHttp是Android主流网络解决方案 2 | 3 | 所以如果存在Net没有实现的功能可以谷歌搜索`"OkHttp如何实现XX"`, 然后可以很容易在Net中使用 4 | 5 | ## 低版本兼容 6 | 7 | 如果开发要求低至 Android 4.4 (API level 19) 8 | 请使用兼容版本: [Net-okhttp3](https://github.com/liangjingkanji/Net-okhttp3) 9 | 10 | 如果需更低版本支持请拉取仓库修改`minSdkVersion`后编译成aar使用 11 | 12 | ## 开发者交流 13 | 14 | - [反馈问题](https://github.com/liangjingkanji/Net/issues) 15 | - [其他开发者提及问题](https://github.com/liangjingkanji/Net/issues) 16 | - [交流社区](https://github.com/liangjingkanji/Net/discussions) 17 | - 18 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/converter/GsonConverter.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.converter 2 | 3 | import com.drake.net.convert.JSONConvert 4 | import com.google.gson.GsonBuilder 5 | import org.json.JSONObject 6 | import java.lang.reflect.Type 7 | 8 | class GsonConverter : JSONConvert(code = "errorCode", message = "errorMsg") { 9 | companion object { 10 | private val gson = GsonBuilder().serializeNulls().create() 11 | } 12 | 13 | override fun String.parseBody(succeed: Type): R? { 14 | val string = try { 15 | JSONObject(this).getString("data") 16 | } catch (e: Exception) { 17 | this 18 | } 19 | return gson.fromJson(string, succeed) 20 | } 21 | } -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_fastest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_sync_request.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 10 | 11 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_async_task.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_push_refresh.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_callback_request.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 10 | 11 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_interceptor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_coroutine_scope.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_exception_trace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_error_handler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_parallel_network.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_simple_request.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_switch_dispatcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /sample/src/main/res/menu/menu_interval.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 13 | 16 | 19 | 22 | 25 | -------------------------------------------------------------------------------- /docs/api/images/anchor-copy-button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/cookie.md: -------------------------------------------------------------------------------- 1 | 可以实现OkHttp的`CookieJar`, 且提供持久化的[PersistentCookieJar](https://github.com/liangjingkanji/Net/blob/2abf07e1d003ef44574278fd2010f3375225d964/net/src/main/java/com/drake/net/cookie/PersistentCookieJar.kt) 2 | 3 | ```kotlin 4 | NetConfig.initialize(Api.HOST, this) { 5 | // 添加持久化Cookie 6 | cookieJar(PersistentCookieJar(this@App)) 7 | } 8 | ``` 9 | 10 | 可以手动增删Cookie 11 | 12 | | PersistentCookieJar | 描述 | 13 | |-|-| 14 | | addAll | 添加Cookie | 15 | | getAll | 获取某个域名的所有Cookie | 16 | | remove | 删除某个域名下所有或者指定名称的Cookie | 17 | | clear | 删除客户端全部Cookie | 18 | 19 | 20 | 可通过客户端获取到已配置cookieJar 21 | ```kotlin 22 | (NetConfig.okHttpClient.cookieJar as? PersistentCookieJar)?.clear() 23 | ``` 24 | 25 | !!! note "隔绝Cookies共享" 26 | 为`PersistentCookieJar`指定不同`dbName`阻止不同的客户端共享Cookies -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_super_interval.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_exception_trace.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_auto_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_read_cache.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_error_handler.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/ui/fragment/StateLayoutFragment.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.ui.fragment 2 | 3 | import com.drake.engine.base.EngineFragment 4 | import com.drake.net.Get 5 | import com.drake.net.sample.R 6 | import com.drake.net.sample.constants.Api 7 | import com.drake.net.sample.databinding.FragmentStateLayoutBinding 8 | import com.drake.net.utils.scope 9 | 10 | 11 | class StateLayoutFragment : 12 | EngineFragment(R.layout.fragment_state_layout) { 13 | 14 | override fun initData() { 15 | } 16 | 17 | override fun initView() { 18 | binding.state.onRefresh { 19 | scope { 20 | binding.tvFragment.text = Get(Api.TEXT).await() 21 | } 22 | }.showLoading() 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /sample/src/androidTest/java/com/drake/net/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 20 | assertEquals("com.drake.net", appContext.packageName) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_state_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 12 | 13 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_push_refresh.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /net/src/main/java/com/drake/net/utils/LegacyTLS.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.utils 2 | 3 | import android.os.Build 4 | import okhttp3.CipherSuite 5 | import okhttp3.ConnectionSpec 6 | import okhttp3.OkHttpClient 7 | 8 | /** 9 | * API<21 支持 TLSv1.1 和 TLSv1.2 10 | */ 11 | fun OkHttpClient.Builder.useLegacyTLS() { 12 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 13 | val legacyTls: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) 14 | .cipherSuites( 15 | *ConnectionSpec.MODERN_TLS.cipherSuites()?.toTypedArray() ?: emptyArray(), 16 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 17 | CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 18 | ).build() 19 | 20 | connectionSpecs(listOf(legacyTls, ConnectionSpec.CLEARTEXT)) 21 | } 22 | } -------------------------------------------------------------------------------- /sample/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 -------------------------------------------------------------------------------- /docs/sync-request.md: -------------------------------------------------------------------------------- 1 | Net支持在当前线程执行阻塞线程的同步请求 2 | 3 | !!! question "什么是同步请求" 4 | 即上个请求结束才会发起下个请求, 实际上协程也可以实现但是他不会阻塞线程 5 | 6 | 同步请求应用场景一般是在拦截器(执行在子线程)中使用 7 | 8 | 因为Android主线程不允许发起网络请求, 这里创建一个子线程来演示 9 | 10 | === "返回数据" 11 | 12 | ```kotlin 13 | thread { 14 | val result = Net.post(Api.PATH).execute() // 网络请求不允许在主线程 15 | tv?.post { 16 | tv?.text = result // view要求在主线程更新 17 | } 18 | } 19 | ``` 20 | 21 | === "返回Result" 22 | 23 | ```kotlin 24 | thread { 25 | val result = Net.post(Api.PATH).toResult().getOrDefault("请求发生错误, 我是默认值") 26 | tv?.post { 27 | tv?.text = result // view要求在主线程更新 28 | } 29 | } 30 | ``` 31 | 32 | 1. `execute`在请求错误时会直接抛出异常 33 | 2. `toResult`不会抛出异常, 可`getOrThrow/exceptionOrNull`等返回异常对象 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/error-global.md: -------------------------------------------------------------------------------- 1 | 可实现`NetErrorHandler`接口来监听全局错误处理 2 | 3 | === "创建" 4 | ```kotlin 5 | class NetworkingErrorHandler : NetErrorHandler { 6 | override fun onError(e: Throwable) { 7 | // .... 其他错误 8 | if (e is ResponseException && e.tag == 401) { // 判断异常为token失效 9 | // 打开登录界面或者弹登录失效对话框 10 | } 11 | } 12 | } 13 | ``` 14 | === "配置" 15 | ```kotlin 16 | NetConfig.initialize(Api.HOST, this) { 17 | setErrorHandler(NetworkingErrorHandler)) 18 | } 19 | ``` 20 | 21 | |NetErrorHandler|使用场景|触发位置| 22 | |-|-|-| 23 | |`onError`| 吐司错误信息 | `scopeNetLife/scopeDialog` | 24 | |`onStateError` | 要求错误显示在缺省页 |`PageRefreshLayout.scope/StateLayout.scope`| 25 | 26 | 27 | !!! warning "以下情况全局错误处理无效" 28 | 29 | 1. 异步任务作用域(`scope/scopeLife`)发生的错误 30 | 2. 使用[单例错误处理](error-single.md)处理的错误 -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/converter/MoshiConverter.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.converter 2 | 3 | import com.drake.net.convert.JSONConvert 4 | import com.squareup.moshi.Moshi 5 | import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory 6 | import org.json.JSONObject 7 | import java.lang.reflect.Type 8 | 9 | class MoshiConverter : JSONConvert(code = "errorCode", message = "errorMsg", success = "0") { 10 | 11 | companion object { 12 | private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() 13 | } 14 | 15 | override fun String.parseBody(succeed: Type): R? { 16 | val string = try { 17 | JSONObject(this).getString("data") 18 | } catch (e: Exception) { 19 | this 20 | } 21 | return moshi.adapter(succeed).fromJson(string) 22 | } 23 | } -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/ui/fragment/ExceptionTraceFragment.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.ui.fragment 2 | 3 | import com.drake.engine.base.EngineFragment 4 | import com.drake.net.Get 5 | import com.drake.net.sample.R 6 | import com.drake.net.sample.databinding.FragmentExceptionTraceBinding 7 | import com.drake.net.utils.scopeNetLife 8 | 9 | 10 | class ExceptionTraceFragment : 11 | EngineFragment(R.layout.fragment_exception_trace) { 12 | 13 | override fun initView() { 14 | scopeNetLife { 15 | // 这是一个错误的地址, 请查看LogCat的错误信息, 在[initNet]函数中的[onError]回调中你也可以进行自定义错误信息打印 16 | binding.tvFragment.text = 17 | Get("https://githuberror.com/liangjingkanji/Net/").await() 18 | } 19 | } 20 | 21 | override fun initData() { 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /sample/src/main/java/com/drake/net/sample/ui/fragment/InterceptorFragment.kt: -------------------------------------------------------------------------------- 1 | package com.drake.net.sample.ui.fragment 2 | 3 | import com.drake.engine.base.EngineFragment 4 | import com.drake.net.Get 5 | import com.drake.net.sample.R 6 | import com.drake.net.sample.constants.Api 7 | import com.drake.net.sample.databinding.FragmentInterceptorBinding 8 | import com.drake.net.utils.scopeNetLife 9 | 10 | 11 | class InterceptorFragment : 12 | EngineFragment(R.layout.fragment_interceptor) { 13 | 14 | override fun initView() { 15 | scopeNetLife { 16 | binding.tvFragment.text = Get(Api.TEXT) { 17 | // 拦截器只支持全局, 无法单例, 请查看[com.drake.net.sample.interceptor.NetInterceptor] 18 | }.await() 19 | } 20 | } 21 | 22 | override fun initData() { 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_limited_time.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 18 | 19 |