From 51fa25bc35498d0cba639b31e28304966b69a4cb Mon Sep 17 00:00:00 2001 From: <> Date: Wed, 16 Aug 2023 13:16:41 +0000 Subject: [PATCH] Deployed ec942f2 with MkDocs version: 1.5.2 --- .nojekyll | 0 404.html | 1104 +++ api/-net/androidx.lifecycle/index.html | 90 + api/-net/androidx.lifecycle/life.html | 38 + api/-net/androidx.lifecycle/scope-life.html | 38 + .../androidx.lifecycle/scope-net-life.html | 38 + .../-net-request-body/-net-request-body.html | 38 + .../-net-request-body/content-length.html | 38 + .../-net-request-body/content-type.html | 38 + .../-net-request-body/index.html | 91 + .../-net-request-body/write-to.html | 38 + .../-net-response-body.html | 38 + .../-net-response-body/content-length.html | 38 + .../-net-response-body/content-type.html | 38 + .../-net-response-body/index.html | 91 + .../-net-response-body/source.html | 38 + api/-net/com.drake.net.body/file-name.html | 38 + api/-net/com.drake.net.body/index.html | 183 + api/-net/com.drake.net.body/name.html | 38 + api/-net/com.drake.net.body/peek-bytes.html | 38 + .../to-net-request-body.html | 38 + .../to-net-response-body.html | 38 + api/-net/com.drake.net.body/value.html | 38 + .../-cache-mode/-r-e-a-d/index.html | 37 + .../index.html | 37 + .../index.html | 37 + .../-cache-mode/-w-r-i-t-e/index.html | 37 + .../-cache-mode/index.html | 92 + .../-force-cache/-companion/has-vary-all.html | 38 + .../-force-cache/-companion/index.html | 108 + .../-force-cache/-companion/key.html | 38 + .../-force-cache/-companion/vary-headers.html | 38 + .../-force-cache/-companion/vary-matches.html | 38 + .../-force-cache/cache.html | 38 + .../-force-cache/close.html | 38 + .../-force-cache/delete.html | 38 + .../-force-cache/directory.html | 38 + .../-force-cache/evict-all.html | 38 + .../-force-cache/flush.html | 38 + .../-force-cache/index.html | 270 + .../-force-cache/initialize.html | 38 + .../-force-cache/is-closed.html | 38 + .../-force-cache/max-size.html | 38 + .../-force-cache/size.html | 38 + .../-force-cache/urls.html | 38 + .../-force-cache/write-abort-count.html | 38 + .../-force-cache/write-success-count.html | 38 + api/-net/com.drake.net.cache/index.html | 73 + .../-progress/-progress.html | 38 + .../-progress/current-byte-count.html | 38 + .../-progress/current-size.html | 38 + .../-progress/finish.html | 38 + .../-progress/index.html | 318 + .../-progress/interval-byte-count.html | 38 + .../-progress/interval-time.html | 38 + .../-progress/progress.html | 38 + .../-progress/remain-size.html | 38 + .../-progress/remain-time-seconds.html | 38 + .../-progress/remain-time.html | 38 + .../-progress/speed-bytes.html | 38 + .../-progress/speed-size.html | 38 + .../-progress/start-elapsed-realtime.html | 38 + .../-progress/to-string.html | 38 + .../-progress/total-byte-count.html | 38 + .../-progress/total-size.html | 38 + .../-progress/use-time-seconds.html | 38 + .../-progress/use-time.html | 38 + api/-net/com.drake.net.component/index.html | 56 + .../-j-s-o-n-convert/-j-s-o-n-convert.html | 38 + .../-j-s-o-n-convert/code.html | 38 + .../-j-s-o-n-convert/index.html | 134 + .../-j-s-o-n-convert/message.html | 38 + .../-j-s-o-n-convert/on-convert.html | 38 + .../-j-s-o-n-convert/parse-body.html | 38 + .../-j-s-o-n-convert/success.html | 38 + .../-net-converter/-d-e-f-a-u-l-t/index.html | 57 + .../-d-e-f-a-u-l-t/on-convert.html | 38 + .../-net-converter/index.html | 96 + .../-net-converter/on-convert.html | 38 + api/-net/com.drake.net.convert/index.html | 73 + .../-persistent-cookie-jar.html | 38 + .../-persistent-cookie-jar/add-all.html | 38 + .../-persistent-cookie-jar/clear.html | 38 + .../-persistent-cookie-jar/context.html | 38 + .../-persistent-cookie-jar/db-name.html | 38 + .../-persistent-cookie-jar/get-all.html | 38 + .../-persistent-cookie-jar/index.html | 195 + .../load-for-request.html | 38 + .../-persistent-cookie-jar/remove.html | 44 + .../save-from-response.html | 38 + api/-net/com.drake.net.cookie/index.html | 56 + .../-convert-exception.html | 38 + .../-convert-exception/index.html | 72 + .../-convert-exception/tag.html | 38 + .../-download-file-exception.html | 38 + .../-download-file-exception/index.html | 72 + .../-download-file-exception/tag.html | 38 + .../-http-failure-exception.html | 38 + .../-http-failure-exception/index.html | 95 + .../-http-response-exception.html | 38 + .../-http-response-exception/index.html | 123 + .../-http-response-exception/response.html | 38 + .../-net-cancellation-exception.html | 38 + .../-net-cancellation-exception.html | 38 + .../-net-cancellation-exception/index.html | 53 + .../-net-connect-exception.html | 38 + .../-net-connect-exception/index.html | 57 + .../-net-exception/-net-exception.html | 38 + .../-net-exception/get-localized-message.html | 38 + .../-net-exception/index.html | 133 + .../-net-exception/occurred.html | 38 + .../-net-exception/request.html | 38 + .../-net-socket-timeout-exception.html | 38 + .../-net-socket-timeout-exception/index.html | 57 + .../-net-unknown-host-exception.html | 38 + .../-net-unknown-host-exception/index.html | 57 + .../-networking-exception.html | 38 + .../-networking-exception/index.html | 57 + .../-no-cache-exception.html | 38 + .../get-localized-message.html | 38 + .../-no-cache-exception/index.html | 76 + .../-request-params-exception.html | 38 + .../-request-params-exception/index.html | 72 + .../-request-params-exception/tag.html | 38 + .../-response-exception.html | 38 + .../-response-exception/index.html | 72 + .../-response-exception/tag.html | 38 + .../-server-response-exception.html | 38 + .../-server-response-exception/index.html | 72 + .../-server-response-exception/tag.html | 38 + .../-u-r-l-parse-exception.html | 38 + .../get-localized-message.html | 38 + .../-u-r-l-parse-exception/index.html | 91 + .../-u-r-l-parse-exception/occurred.html | 38 + api/-net/com.drake.net.exception/index.html | 313 + .../-log-record-interceptor.html | 38 + .../-log-record-interceptor/enabled.html | 38 + .../-log-record-interceptor/index.html | 113 + .../-log-record-interceptor/intercept.html | 38 + .../request-byte-count.html | 38 + .../response-byte-count.html | 38 + .../-net-ok-http-interceptor/index.html | 57 + .../-net-ok-http-interceptor/intercept.html | 38 + .../-request-interceptor/index.html | 57 + .../-request-interceptor/interceptor.html | 38 + .../-retry-interceptor.html | 38 + .../-retry-interceptor/index.html | 87 + .../-retry-interceptor/intercept.html | 38 + .../-retry-interceptor/retry-count.html | 38 + api/-net/com.drake.net.interceptor/index.html | 107 + .../-d-e-f-a-u-l-t/index.html | 57 + .../-d-e-f-a-u-l-t/on-create.html | 38 + .../-net-dialog-factory/index.html | 87 + .../-net-dialog-factory/on-create.html | 38 + .../-d-e-f-a-u-l-t/index.html | 37 + .../-net-error-handler/index.html | 104 + .../-net-error-handler/on-error.html | 38 + .../-net-error-handler/on-state-error.html | 38 + .../-progress-listener.html | 38 + .../-progress-listener/elapsed-time.html | 38 + .../-progress-listener/index.html | 117 + .../interval-byte-count.html | 38 + .../-progress-listener/interval.html | 38 + .../-progress-listener/on-progress.html | 38 + api/-net/com.drake.net.interfaces/index.html | 90 + .../-log-recorder/enabled.html | 38 + .../-log-recorder/generate-id.html | 38 + .../-log-recorder/index.html | 123 + .../-log-recorder/record-exception.html | 38 + .../-log-recorder/record-request.html | 38 + .../-log-recorder/record-response.html | 38 + .../-r-e-q-u-e-s-t_-b-o-d-y/index.html | 37 + .../-r-e-q-u-e-s-t_-e-n-d/index.html | 37 + .../-r-e-q-u-e-s-t_-h-e-a-d-e-r/index.html | 37 + .../-r-e-q-u-e-s-t_-m-e-t-h-o-d/index.html | 37 + .../-r-e-q-u-e-s-t_-t-i-m-e/index.html | 37 + .../-r-e-q-u-e-s-t_-u-r-l/index.html | 37 + .../-r-e-s-p-o-n-s-e_-b-o-d-y/index.html | 37 + .../-r-e-s-p-o-n-s-e_-e-n-d/index.html | 37 + .../-r-e-s-p-o-n-s-e_-e-r-r-o-r/index.html | 37 + .../-r-e-s-p-o-n-s-e_-h-e-a-d-e-r/index.html | 37 + .../-r-e-s-p-o-n-s-e_-s-t-a-t-u-s/index.html | 37 + .../-r-e-s-p-o-n-s-e_-t-i-m-e/index.html | 37 + .../-message-type/-u-n-k-n-o-w-n/index.html | 37 + .../-message-type/index.html | 224 + .../com.drake.net.log/-message-type/type.html | 38 + api/-net/com.drake.net.log/index.html | 73 + api/-net/com.drake.net.okhttp/index.html | 187 + .../com.drake.net.okhttp/set-converter.html | 38 + api/-net/com.drake.net.okhttp/set-debug.html | 38 + .../set-dialog-factory.html | 38 + .../set-error-handler.html | 38 + .../set-request-interceptor.html | 38 + .../set-s-s-l-certificate.html | 44 + .../com.drake.net.okhttp/to-net-okhttp.html | 38 + .../trust-s-s-l-certificate.html | 38 + .../$-gson$-preconditions/check-argument.html | 38 + .../$-gson$-preconditions/check-not-null.html | 38 + .../$-gson$-preconditions/index.html | 78 + .../$-gson$-types/array-of.html | 38 + .../$-gson$-types/canonicalize.html | 38 + .../$-gson$-types/equals.html | 38 + .../get-array-component-type.html | 38 + .../get-collection-element-type.html | 38 + .../get-map-key-and-value-types.html | 38 + .../$-gson$-types/get-raw-type.html | 38 + .../$-gson$-types/index.html | 244 + .../new-parameterized-type-with-owner.html | 38 + .../$-gson$-types/resolve.html | 38 + .../$-gson$-types/subtype-of.html | 38 + .../$-gson$-types/supertype-of.html | 38 + .../$-gson$-types/type-to-string.html | 38 + .../-type-token/equals.html | 38 + .../-type-token/get-array.html | 38 + .../-type-token/get-parameterized.html | 38 + .../-type-token/get.html | 44 + .../-type-token/hash-code.html | 38 + .../-type-token/index.html | 189 + .../-type-token/raw-type.html | 38 + .../-type-token/to-string.html | 38 + .../-type-token/type.html | 38 + api/-net/com.drake.net.reflect/index.html | 109 + .../com.drake.net.reflect/type-token-of.html | 38 + .../-base-request/-base-request.html | 38 + .../-base-request/add-download-listener.html | 38 + .../-base-request/add-header.html | 38 + .../-base-request/add-query.html | 38 + .../-base-request/build-request.html | 38 + .../-base-request/converter.html | 38 + .../-base-request/enqueue.html | 38 + .../-base-request/execute.html | 44 + .../-base-request/headers.html | 38 + .../-base-request/http-url.html | 38 + .../-base-request/index.html | 743 ++ .../-base-request/method.html | 38 + .../-base-request/ok-http-client.html | 38 + .../-base-request/ok-http-request.html | 38 + .../-base-request/param.html | 44 + .../-base-request/remove-header.html | 38 + .../-base-request/set-cache-control.html | 38 + .../-base-request/set-cache-key.html | 38 + .../-base-request/set-cache-mode.html | 38 + .../-base-request/set-cache-valid-time.html | 38 + .../-base-request/set-client.html | 38 + .../-base-request/set-download-dir.html | 38 + .../set-download-file-name-conflict.html | 38 + .../set-download-file-name-decode.html | 38 + .../-base-request/set-download-file-name.html | 38 + .../set-download-md5-verify.html | 38 + .../-base-request/set-download-temp-file.html | 38 + .../-base-request/set-extra.html | 38 + .../-base-request/set-group.html | 38 + .../-base-request/set-header.html | 38 + .../-base-request/set-headers.html | 38 + .../-base-request/set-id.html | 38 + .../-base-request/set-k-type.html | 38 + .../-base-request/set-path.html | 38 + .../-base-request/set-query.html | 38 + .../-base-request/set-url.html | 44 + .../-base-request/tag-of.html | 38 + .../-base-request/tag.html | 44 + .../-base-request/to-result.html | 38 + .../-body-request/-body-request.html | 38 + .../-body-request/add-upload-listener.html | 38 + .../-body-request/body.html | 38 + .../-body-request/build-request.html | 38 + .../-body-request/form-body.html | 38 + .../-body-request/index.html | 223 + .../-body-request/json.html | 44 + .../-body-request/media-type.html | 38 + .../-body-request/method.html | 38 + .../-body-request/param.html | 50 + .../-body-request/part-body.html | 38 + .../-media-const/-f-o-r-m.html | 38 + .../-media-const/-g-i-f.html | 38 + .../-media-const/-h-t-m-l.html | 38 + .../-media-const/-i-m-g.html | 38 + .../-media-const/-j-p-e-g.html | 38 + .../-media-const/-j-s-o-n.html | 38 + .../-media-const/-m-p4.html | 38 + .../-media-const/-o-c-t-e-t_-s-t-r-e-a-m.html | 38 + .../-media-const/-p-n-g.html | 38 + .../-media-const/-t-x-t.html | 38 + .../-media-const/-u-r-l-e-n-c-o-d-e-d.html | 38 + .../-media-const/-x-m-l.html | 38 + .../-media-const/index.html | 196 + .../-method/-d-e-l-e-t-e/index.html | 37 + .../-method/-g-e-t/index.html | 37 + .../-method/-h-e-a-d/index.html | 37 + .../-method/-o-p-t-i-o-n-s/index.html | 37 + .../-method/-p-a-t-c-h/index.html | 37 + .../-method/-p-o-s-t/index.html | 37 + .../-method/-p-u-t/index.html | 37 + .../-method/-t-r-a-c-e/index.html | 37 + .../com.drake.net.request/-method/index.html | 144 + .../-url-request/-url-request.html | 38 + .../-url-request/index.html | 75 + .../-url-request/param.html | 44 + api/-net/com.drake.net.request/converter.html | 38 + .../download-conflict-rename.html | 38 + .../download-file-dir.html | 38 + .../download-file-name-decode.html | 38 + .../download-file-name.html | 38 + .../download-listeners.html | 38 + .../download-md5-verify.html | 38 + .../download-temp-file.html | 38 + api/-net/com.drake.net.request/extra.html | 38 + api/-net/com.drake.net.request/extras.html | 38 + api/-net/com.drake.net.request/group.html | 38 + api/-net/com.drake.net.request/headers.html | 38 + api/-net/com.drake.net.request/id.html | 38 + api/-net/com.drake.net.request/index.html | 520 ++ api/-net/com.drake.net.request/k-type.html | 38 + .../com.drake.net.request/set-converter.html | 38 + api/-net/com.drake.net.request/set-extra.html | 38 + api/-net/com.drake.net.request/tag-of.html | 44 + api/-net/com.drake.net.request/tags.html | 38 + .../upload-listeners.html | 38 + api/-net/com.drake.net.response/convert.html | 44 + .../com.drake.net.response/file-name.html | 38 + api/-net/com.drake.net.response/file.html | 38 + api/-net/com.drake.net.response/index.html | 96 + .../-android-scope/-android-scope.html | 38 + .../-android-scope/cancel.html | 38 + .../-android-scope/catch.html | 38 + .../-android-scope/close.html | 38 + .../-android-scope/coroutine-context.html | 38 + .../-android-scope/dispatcher.html | 38 + .../-android-scope/finally.html | 38 + .../-android-scope/handle-error.html | 38 + .../-android-scope/index.html | 213 + .../-android-scope/launch.html | 38 + .../-android-scope/scope-group.html | 38 + .../-dialog-coroutine-scope.html | 38 + .../-dialog-coroutine-scope/activity.html | 38 + .../-dialog-coroutine-scope/cancelable.html | 38 + .../-dialog-coroutine-scope/dialog.html | 38 + .../-dialog-coroutine-scope/index.html | 98 + .../-net-coroutine-scope.html | 38 + .../-net-coroutine-scope/cancel.html | 38 + .../-net-coroutine-scope/handle-error.html | 38 + .../-net-coroutine-scope/index.html | 161 + .../-net-coroutine-scope/launch.html | 38 + .../-net-coroutine-scope/preview.html | 38 + .../-page-coroutine-scope/--index--.html | 38 + .../-page-coroutine-scope.html | 38 + .../-page-coroutine-scope/handle-error.html | 38 + .../-page-coroutine-scope/index.html | 85 + .../-page-coroutine-scope/page.html | 38 + .../-state-coroutine-scope.html | 38 + .../-state-coroutine-scope/handle-error.html | 38 + .../-state-coroutine-scope/index.html | 87 + .../-state-coroutine-scope/state.html | 38 + .../-view-coroutine-scope.html | 38 + .../-view-coroutine-scope/index.html | 68 + .../-view-coroutine-scope/view.html | 38 + api/-net/com.drake.net.scope/index.html | 141 + .../-net-tag/-cache-key/-cache-key.html | 38 + .../-net-tag/-cache-key/index.html | 53 + .../-net-tag/-cache-key/value.html | 38 + .../-cache-valid-time/-cache-valid-time.html | 38 + .../-net-tag/-cache-valid-time/index.html | 53 + .../-net-tag/-cache-valid-time/value.html | 38 + .../-download-file-conflict-rename.html | 38 + .../-download-file-conflict-rename/index.html | 53 + .../-download-file-conflict-rename/value.html | 38 + .../-download-file-dir.html | 38 + .../-net-tag/-download-file-dir/index.html | 68 + .../-net-tag/-download-file-dir/value.html | 38 + .../-download-file-m-d5-verify.html | 38 + .../-download-file-m-d5-verify/index.html | 53 + .../-download-file-m-d5-verify/value.html | 38 + .../-download-file-name-decode.html | 38 + .../-download-file-name-decode/index.html | 53 + .../-download-file-name-decode/value.html | 38 + .../-download-file-name.html | 38 + .../-net-tag/-download-file-name/index.html | 53 + .../-net-tag/-download-file-name/value.html | 38 + .../-download-listeners.html | 38 + .../-net-tag/-download-listeners/index.html | 37 + .../-download-temp-file.html | 38 + .../-net-tag/-download-temp-file/index.html | 53 + .../-net-tag/-download-temp-file/value.html | 38 + .../-net-tag/-extras/-extras.html | 38 + .../-net-tag/-extras/index.html | 37 + .../-request-group/-request-group.html | 38 + .../-net-tag/-request-group/index.html | 53 + .../-net-tag/-request-group/value.html | 38 + .../-net-tag/-request-id/-request-id.html | 38 + .../-net-tag/-request-id/index.html | 53 + .../-net-tag/-request-id/value.html | 38 + .../-request-k-type/-request-k-type.html | 38 + .../-net-tag/-request-k-type/index.html | 53 + .../-net-tag/-request-k-type/value.html | 38 + .../-upload-listeners/-upload-listeners.html | 38 + .../-net-tag/-upload-listeners/index.html | 37 + .../com.drake.net.tag/-net-tag/index.html | 278 + api/-net/com.drake.net.tag/index.html | 56 + .../-s-t-a-t-e_-a-c-t-i-v-e/index.html | 37 + .../-s-t-a-t-e_-i-d-l-e/index.html | 37 + .../-s-t-a-t-e_-p-a-u-s-e/index.html | 37 + .../-interval-status/index.html | 79 + .../-interval/-interval.html | 44 + .../com.drake.net.time/-interval/cancel.html | 38 + .../com.drake.net.time/-interval/close.html | 38 + .../com.drake.net.time/-interval/count.html | 38 + .../com.drake.net.time/-interval/end.html | 38 + .../com.drake.net.time/-interval/finish.html | 38 + .../com.drake.net.time/-interval/index.html | 342 + .../com.drake.net.time/-interval/life.html | 44 + .../-interval/only-resumed.html | 38 + .../com.drake.net.time/-interval/pause.html | 38 + .../com.drake.net.time/-interval/reset.html | 38 + .../com.drake.net.time/-interval/resume.html | 38 + .../com.drake.net.time/-interval/start.html | 38 + .../com.drake.net.time/-interval/state.html | 38 + .../com.drake.net.time/-interval/stop.html | 38 + .../-interval/subscribe.html | 38 + .../com.drake.net.time/-interval/switch.html | 38 + api/-net/com.drake.net.time/index.html | 73 + .../-deferred-transform.html | 38 + .../-deferred-transform/block.html | 38 + .../-deferred-transform/deferred.html | 38 + .../-deferred-transform/index.html | 66 + api/-net/com.drake.net.transform/index.html | 75 + .../com.drake.net.transform/transform.html | 38 + .../-https/-un-safe-hostname-verifier.html | 38 + .../-https/-un-safe-trust-manager.html | 38 + .../com.drake.net.utils/-https/index.html | 66 + .../com.drake.net.utils/-tip-utils/index.html | 57 + .../com.drake.net.utils/-tip-utils/toast.html | 38 + api/-net/com.drake.net.utils/debounce.html | 38 + api/-net/com.drake.net.utils/fastest.html | 44 + api/-net/com.drake.net.utils/file-name.html | 38 + api/-net/com.drake.net.utils/index.html | 435 ++ .../com.drake.net.utils/is-networking.html | 38 + api/-net/com.drake.net.utils/launch-in.html | 38 + api/-net/com.drake.net.utils/md5.html | 38 + api/-net/com.drake.net.utils/media-type.html | 44 + api/-net/com.drake.net.utils/run-main.html | 38 + .../com.drake.net.utils/scope-dialog.html | 38 + api/-net/com.drake.net.utils/scope-life.html | 44 + .../com.drake.net.utils/scope-net-life.html | 50 + api/-net/com.drake.net.utils/scope-net.html | 38 + api/-net/com.drake.net.utils/scope.html | 50 + .../com.drake.net.utils/to-request-body.html | 44 + .../com.drake.net.utils/with-default.html | 38 + api/-net/com.drake.net.utils/with-i-o.html | 38 + api/-net/com.drake.net.utils/with-main.html | 38 + .../com.drake.net.utils/with-unconfined.html | 38 + api/-net/com.drake.net/-delete.html | 38 + api/-net/com.drake.net/-get.html | 38 + api/-net/com.drake.net/-head.html | 38 + .../com.drake.net/-net-config/-t-a-g.html | 38 + api/-net/com.drake.net/-net-config/app.html | 38 + .../com.drake.net/-net-config/converter.html | 38 + api/-net/com.drake.net/-net-config/debug.html | 38 + .../-net-config/dialog-factory.html | 38 + .../-net-config/error-handler.html | 38 + api/-net/com.drake.net/-net-config/host.html | 38 + api/-net/com.drake.net/-net-config/index.html | 195 + .../com.drake.net/-net-config/initialize.html | 44 + .../-net-config/ok-http-client.html | 38 + .../-net-config/request-interceptor.html | 38 + .../-net-config/running-calls.html | 38 + .../-net/add-download-listener.html | 38 + .../-net/add-upload-listener.html | 38 + api/-net/com.drake.net/-net/cancel-all.html | 38 + api/-net/com.drake.net/-net/cancel-group.html | 38 + api/-net/com.drake.net/-net/cancel-id.html | 38 + api/-net/com.drake.net/-net/debug.html | 38 + api/-net/com.drake.net/-net/delete.html | 38 + .../-net/get-request-by-group.html | 38 + .../com.drake.net/-net/get-request-by-id.html | 38 + api/-net/com.drake.net/-net/get.html | 38 + api/-net/com.drake.net/-net/head.html | 38 + api/-net/com.drake.net/-net/index.html | 346 + api/-net/com.drake.net/-net/options.html | 38 + api/-net/com.drake.net/-net/patch.html | 38 + api/-net/com.drake.net/-net/post.html | 38 + api/-net/com.drake.net/-net/put.html | 38 + .../-net/remove-download-listener.html | 38 + .../-net/remove-upload-listener.html | 38 + api/-net/com.drake.net/-net/trace.html | 38 + api/-net/com.drake.net/-options.html | 38 + api/-net/com.drake.net/-patch.html | 38 + api/-net/com.drake.net/-post.html | 38 + api/-net/com.drake.net/-put.html | 38 + api/-net/com.drake.net/-trace.html | 38 + api/-net/com.drake.net/index.html | 211 + .../okhttp3/-ok-http-utils/add-lenient.html | 38 + .../-ok-http-utils/disk-lru-cache.html | 38 + api/-net/okhttp3/-ok-http-utils/headers.html | 38 + api/-net/okhttp3/-ok-http-utils/index.html | 114 + api/-net/okhttp3/-ok-http-utils/tags.html | 44 + api/-net/okhttp3/index.html | 56 + api/-net/package-list | 579 ++ api/images/anchor-copy-button.svg | 4 + api/images/arrow_down.svg | 3 + api/images/copy-icon.svg | 3 + api/images/copy-successful-icon.svg | 3 + api/images/docs_logo.svg | 7 + api/images/footer-go-to-link.svg | 3 + api/images/go-to-top-icon.svg | 4 + api/images/logo-icon.svg | 3 + api/index.html | 286 + api/navigation.html | 520 ++ api/scripts/clipboard.js | 52 + api/scripts/main.js | 67 + api/scripts/navigation-loader.js | 64 + api/scripts/navigation-pane.json | 1 + api/scripts/pages.json | 1 + api/scripts/platform-content-handler.js | 290 + api/scripts/sourceset_dependencies.js | 1 + api/styles/jetbrains-mono.css | 32 + api/styles/logo-styles.css | 3 + api/styles/main.css | 113 + api/styles/style.css | 1236 +++ assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.220ee61c.min.js | 29 + assets/javascripts/bundle.220ee61c.min.js.map | 8 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.74e28a9f.min.js | 42 + .../workers/search.74e28a9f.min.js.map | 8 + assets/stylesheets/main.eebd395e.min.css | 1 + assets/stylesheets/main.eebd395e.min.css.map | 1 + assets/stylesheets/palette.ecc896b0.min.css | 1 + .../stylesheets/palette.ecc896b0.min.css.map | 1 + auto-dialog.html | 1329 ++++ auto-pull.html | 1271 ++++ auto-refresh.html | 1320 ++++ auto-state.html | 1331 ++++ cache.html | 1438 ++++ callback.html | 1184 +++ cancel.html | 1282 ++++ config.html | 1380 ++++ converter-customize.html | 1373 ++++ converter-struct.html | 1386 ++++ converter.html | 1262 ++++ cookie.html | 1205 +++ coroutine-request.html | 1189 +++ css/extra.css | 53 + debounce.html | 1193 +++ download-file.html | 1306 ++++ error-global.html | 1217 +++ error-single.html | 1284 ++++ error-throws.html | 1355 ++++ error-tip.html | 1290 ++++ error.html | 1208 +++ fastest.html | 1313 ++++ https.html | 1295 ++++ img/book-open.svg | 1 + img/code-preview.png | Bin 0 -> 26782 bytes img/discussesions.svg | 25 + img/issues.svg | 29 + img/logo.gif | Bin 0 -> 57457 bytes img/preview.png | Bin 0 -> 189960 bytes index.html | 1321 ++++ interceptor.html | 1277 ++++ interval.html | 1257 +++ issues.html | 1243 +++ kotlin-serialization.html | 1414 ++++ log-notice.html | 1189 +++ log-recorder.html | 1446 ++++ material/partials/footer.html | 66 + model-generate.html | 1362 ++++ okhttp-client.html | 1265 ++++ progress.html | 1431 ++++ repeat-request.html | 1182 +++ request.html | 1377 ++++ scope.html | 1373 ++++ search/search_index.js | 1 + search/search_index.json | 1 + sitemap.xml | 3 + sitemap.xml.gz | Bin 0 -> 127 bytes sync-request.html | 1198 +++ tag.html | 1379 ++++ thread.html | 1304 ++++ timing.html | 1269 ++++ track.html | 1228 +++ updates.html | 2368 ++++++ upload-file.html | 1258 ++++ view-model.html | 1256 +++ 614 files changed, 95581 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 api/-net/androidx.lifecycle/index.html create mode 100644 api/-net/androidx.lifecycle/life.html create mode 100644 api/-net/androidx.lifecycle/scope-life.html create mode 100644 api/-net/androidx.lifecycle/scope-net-life.html create mode 100644 api/-net/com.drake.net.body/-net-request-body/-net-request-body.html create mode 100644 api/-net/com.drake.net.body/-net-request-body/content-length.html create mode 100644 api/-net/com.drake.net.body/-net-request-body/content-type.html create mode 100644 api/-net/com.drake.net.body/-net-request-body/index.html create mode 100644 api/-net/com.drake.net.body/-net-request-body/write-to.html create mode 100644 api/-net/com.drake.net.body/-net-response-body/-net-response-body.html create mode 100644 api/-net/com.drake.net.body/-net-response-body/content-length.html create mode 100644 api/-net/com.drake.net.body/-net-response-body/content-type.html create mode 100644 api/-net/com.drake.net.body/-net-response-body/index.html create mode 100644 api/-net/com.drake.net.body/-net-response-body/source.html create mode 100644 api/-net/com.drake.net.body/file-name.html create mode 100644 api/-net/com.drake.net.body/index.html create mode 100644 api/-net/com.drake.net.body/name.html create mode 100644 api/-net/com.drake.net.body/peek-bytes.html create mode 100644 api/-net/com.drake.net.body/to-net-request-body.html create mode 100644 api/-net/com.drake.net.body/to-net-response-body.html create mode 100644 api/-net/com.drake.net.body/value.html create mode 100644 api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d/index.html create mode 100644 api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d_-t-h-e-n_-r-e-q-u-e-s-t/index.html create mode 100644 api/-net/com.drake.net.cache/-cache-mode/-r-e-q-u-e-s-t_-t-h-e-n_-r-e-a-d/index.html create mode 100644 api/-net/com.drake.net.cache/-cache-mode/-w-r-i-t-e/index.html create mode 100644 api/-net/com.drake.net.cache/-cache-mode/index.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/-companion/has-vary-all.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/-companion/index.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/-companion/key.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/-companion/vary-headers.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/-companion/vary-matches.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/cache.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/close.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/delete.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/directory.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/evict-all.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/flush.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/index.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/initialize.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/is-closed.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/max-size.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/size.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/urls.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/write-abort-count.html create mode 100644 api/-net/com.drake.net.cache/-force-cache/write-success-count.html create mode 100644 api/-net/com.drake.net.cache/index.html create mode 100644 api/-net/com.drake.net.component/-progress/-progress.html create mode 100644 api/-net/com.drake.net.component/-progress/current-byte-count.html create mode 100644 api/-net/com.drake.net.component/-progress/current-size.html create mode 100644 api/-net/com.drake.net.component/-progress/finish.html create mode 100644 api/-net/com.drake.net.component/-progress/index.html create mode 100644 api/-net/com.drake.net.component/-progress/interval-byte-count.html create mode 100644 api/-net/com.drake.net.component/-progress/interval-time.html create mode 100644 api/-net/com.drake.net.component/-progress/progress.html create mode 100644 api/-net/com.drake.net.component/-progress/remain-size.html create mode 100644 api/-net/com.drake.net.component/-progress/remain-time-seconds.html create mode 100644 api/-net/com.drake.net.component/-progress/remain-time.html create mode 100644 api/-net/com.drake.net.component/-progress/speed-bytes.html create mode 100644 api/-net/com.drake.net.component/-progress/speed-size.html create mode 100644 api/-net/com.drake.net.component/-progress/start-elapsed-realtime.html create mode 100644 api/-net/com.drake.net.component/-progress/to-string.html create mode 100644 api/-net/com.drake.net.component/-progress/total-byte-count.html create mode 100644 api/-net/com.drake.net.component/-progress/total-size.html create mode 100644 api/-net/com.drake.net.component/-progress/use-time-seconds.html create mode 100644 api/-net/com.drake.net.component/-progress/use-time.html create mode 100644 api/-net/com.drake.net.component/index.html create mode 100644 api/-net/com.drake.net.convert/-j-s-o-n-convert/-j-s-o-n-convert.html create mode 100644 api/-net/com.drake.net.convert/-j-s-o-n-convert/code.html create mode 100644 api/-net/com.drake.net.convert/-j-s-o-n-convert/index.html create mode 100644 api/-net/com.drake.net.convert/-j-s-o-n-convert/message.html create mode 100644 api/-net/com.drake.net.convert/-j-s-o-n-convert/on-convert.html create mode 100644 api/-net/com.drake.net.convert/-j-s-o-n-convert/parse-body.html create mode 100644 api/-net/com.drake.net.convert/-j-s-o-n-convert/success.html create mode 100644 api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/index.html create mode 100644 api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/on-convert.html create mode 100644 api/-net/com.drake.net.convert/-net-converter/index.html create mode 100644 api/-net/com.drake.net.convert/-net-converter/on-convert.html create mode 100644 api/-net/com.drake.net.convert/index.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/-persistent-cookie-jar.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/add-all.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/clear.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/context.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/db-name.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/get-all.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/index.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/load-for-request.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/remove.html create mode 100644 api/-net/com.drake.net.cookie/-persistent-cookie-jar/save-from-response.html create mode 100644 api/-net/com.drake.net.cookie/index.html create mode 100644 api/-net/com.drake.net.exception/-convert-exception/-convert-exception.html create mode 100644 api/-net/com.drake.net.exception/-convert-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-convert-exception/tag.html create mode 100644 api/-net/com.drake.net.exception/-download-file-exception/-download-file-exception.html create mode 100644 api/-net/com.drake.net.exception/-download-file-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-download-file-exception/tag.html create mode 100644 api/-net/com.drake.net.exception/-http-failure-exception/-http-failure-exception.html create mode 100644 api/-net/com.drake.net.exception/-http-failure-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-http-response-exception/-http-response-exception.html create mode 100644 api/-net/com.drake.net.exception/-http-response-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-http-response-exception/response.html create mode 100644 api/-net/com.drake.net.exception/-net-cancellation-exception.html create mode 100644 api/-net/com.drake.net.exception/-net-cancellation-exception/-net-cancellation-exception.html create mode 100644 api/-net/com.drake.net.exception/-net-cancellation-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-net-connect-exception/-net-connect-exception.html create mode 100644 api/-net/com.drake.net.exception/-net-connect-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-net-exception/-net-exception.html create mode 100644 api/-net/com.drake.net.exception/-net-exception/get-localized-message.html create mode 100644 api/-net/com.drake.net.exception/-net-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-net-exception/occurred.html create mode 100644 api/-net/com.drake.net.exception/-net-exception/request.html create mode 100644 api/-net/com.drake.net.exception/-net-socket-timeout-exception/-net-socket-timeout-exception.html create mode 100644 api/-net/com.drake.net.exception/-net-socket-timeout-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-net-unknown-host-exception/-net-unknown-host-exception.html create mode 100644 api/-net/com.drake.net.exception/-net-unknown-host-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-networking-exception/-networking-exception.html create mode 100644 api/-net/com.drake.net.exception/-networking-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-no-cache-exception/-no-cache-exception.html create mode 100644 api/-net/com.drake.net.exception/-no-cache-exception/get-localized-message.html create mode 100644 api/-net/com.drake.net.exception/-no-cache-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-request-params-exception/-request-params-exception.html create mode 100644 api/-net/com.drake.net.exception/-request-params-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-request-params-exception/tag.html create mode 100644 api/-net/com.drake.net.exception/-response-exception/-response-exception.html create mode 100644 api/-net/com.drake.net.exception/-response-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-response-exception/tag.html create mode 100644 api/-net/com.drake.net.exception/-server-response-exception/-server-response-exception.html create mode 100644 api/-net/com.drake.net.exception/-server-response-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-server-response-exception/tag.html create mode 100644 api/-net/com.drake.net.exception/-u-r-l-parse-exception/-u-r-l-parse-exception.html create mode 100644 api/-net/com.drake.net.exception/-u-r-l-parse-exception/get-localized-message.html create mode 100644 api/-net/com.drake.net.exception/-u-r-l-parse-exception/index.html create mode 100644 api/-net/com.drake.net.exception/-u-r-l-parse-exception/occurred.html create mode 100644 api/-net/com.drake.net.exception/index.html create mode 100644 api/-net/com.drake.net.interceptor/-log-record-interceptor/-log-record-interceptor.html create mode 100644 api/-net/com.drake.net.interceptor/-log-record-interceptor/enabled.html create mode 100644 api/-net/com.drake.net.interceptor/-log-record-interceptor/index.html create mode 100644 api/-net/com.drake.net.interceptor/-log-record-interceptor/intercept.html create mode 100644 api/-net/com.drake.net.interceptor/-log-record-interceptor/request-byte-count.html create mode 100644 api/-net/com.drake.net.interceptor/-log-record-interceptor/response-byte-count.html create mode 100644 api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/index.html create mode 100644 api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/intercept.html create mode 100644 api/-net/com.drake.net.interceptor/-request-interceptor/index.html create mode 100644 api/-net/com.drake.net.interceptor/-request-interceptor/interceptor.html create mode 100644 api/-net/com.drake.net.interceptor/-retry-interceptor/-retry-interceptor.html create mode 100644 api/-net/com.drake.net.interceptor/-retry-interceptor/index.html create mode 100644 api/-net/com.drake.net.interceptor/-retry-interceptor/intercept.html create mode 100644 api/-net/com.drake.net.interceptor/-retry-interceptor/retry-count.html create mode 100644 api/-net/com.drake.net.interceptor/index.html create mode 100644 api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/index.html create mode 100644 api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/on-create.html create mode 100644 api/-net/com.drake.net.interfaces/-net-dialog-factory/index.html create mode 100644 api/-net/com.drake.net.interfaces/-net-dialog-factory/on-create.html create mode 100644 api/-net/com.drake.net.interfaces/-net-error-handler/-d-e-f-a-u-l-t/index.html create mode 100644 api/-net/com.drake.net.interfaces/-net-error-handler/index.html create mode 100644 api/-net/com.drake.net.interfaces/-net-error-handler/on-error.html create mode 100644 api/-net/com.drake.net.interfaces/-net-error-handler/on-state-error.html create mode 100644 api/-net/com.drake.net.interfaces/-progress-listener/-progress-listener.html create mode 100644 api/-net/com.drake.net.interfaces/-progress-listener/elapsed-time.html create mode 100644 api/-net/com.drake.net.interfaces/-progress-listener/index.html create mode 100644 api/-net/com.drake.net.interfaces/-progress-listener/interval-byte-count.html create mode 100644 api/-net/com.drake.net.interfaces/-progress-listener/interval.html create mode 100644 api/-net/com.drake.net.interfaces/-progress-listener/on-progress.html create mode 100644 api/-net/com.drake.net.interfaces/index.html create mode 100644 api/-net/com.drake.net.log/-log-recorder/enabled.html create mode 100644 api/-net/com.drake.net.log/-log-recorder/generate-id.html create mode 100644 api/-net/com.drake.net.log/-log-recorder/index.html create mode 100644 api/-net/com.drake.net.log/-log-recorder/record-exception.html create mode 100644 api/-net/com.drake.net.log/-log-recorder/record-request.html create mode 100644 api/-net/com.drake.net.log/-log-recorder/record-response.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-b-o-d-y/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-e-n-d/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-h-e-a-d-e-r/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-m-e-t-h-o-d/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-t-i-m-e/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-u-r-l/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-b-o-d-y/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-n-d/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-r-r-o-r/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-h-e-a-d-e-r/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-s-t-a-t-u-s/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-t-i-m-e/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/-u-n-k-n-o-w-n/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/index.html create mode 100644 api/-net/com.drake.net.log/-message-type/type.html create mode 100644 api/-net/com.drake.net.log/index.html create mode 100644 api/-net/com.drake.net.okhttp/index.html create mode 100644 api/-net/com.drake.net.okhttp/set-converter.html create mode 100644 api/-net/com.drake.net.okhttp/set-debug.html create mode 100644 api/-net/com.drake.net.okhttp/set-dialog-factory.html create mode 100644 api/-net/com.drake.net.okhttp/set-error-handler.html create mode 100644 api/-net/com.drake.net.okhttp/set-request-interceptor.html create mode 100644 api/-net/com.drake.net.okhttp/set-s-s-l-certificate.html create mode 100644 api/-net/com.drake.net.okhttp/to-net-okhttp.html create mode 100644 api/-net/com.drake.net.okhttp/trust-s-s-l-certificate.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-preconditions/check-argument.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-preconditions/check-not-null.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-preconditions/index.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/array-of.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/canonicalize.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/equals.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/get-array-component-type.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/get-collection-element-type.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/get-map-key-and-value-types.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/get-raw-type.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/index.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/new-parameterized-type-with-owner.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/resolve.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/subtype-of.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/supertype-of.html create mode 100644 api/-net/com.drake.net.reflect/$-gson$-types/type-to-string.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/equals.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/get-array.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/get-parameterized.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/get.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/hash-code.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/index.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/raw-type.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/to-string.html create mode 100644 api/-net/com.drake.net.reflect/-type-token/type.html create mode 100644 api/-net/com.drake.net.reflect/index.html create mode 100644 api/-net/com.drake.net.reflect/type-token-of.html create mode 100644 api/-net/com.drake.net.request/-base-request/-base-request.html create mode 100644 api/-net/com.drake.net.request/-base-request/add-download-listener.html create mode 100644 api/-net/com.drake.net.request/-base-request/add-header.html create mode 100644 api/-net/com.drake.net.request/-base-request/add-query.html create mode 100644 api/-net/com.drake.net.request/-base-request/build-request.html create mode 100644 api/-net/com.drake.net.request/-base-request/converter.html create mode 100644 api/-net/com.drake.net.request/-base-request/enqueue.html create mode 100644 api/-net/com.drake.net.request/-base-request/execute.html create mode 100644 api/-net/com.drake.net.request/-base-request/headers.html create mode 100644 api/-net/com.drake.net.request/-base-request/http-url.html create mode 100644 api/-net/com.drake.net.request/-base-request/index.html create mode 100644 api/-net/com.drake.net.request/-base-request/method.html create mode 100644 api/-net/com.drake.net.request/-base-request/ok-http-client.html create mode 100644 api/-net/com.drake.net.request/-base-request/ok-http-request.html create mode 100644 api/-net/com.drake.net.request/-base-request/param.html create mode 100644 api/-net/com.drake.net.request/-base-request/remove-header.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-cache-control.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-cache-key.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-cache-mode.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-cache-valid-time.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-client.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-download-dir.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-download-file-name-conflict.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-download-file-name-decode.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-download-file-name.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-download-md5-verify.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-download-temp-file.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-extra.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-group.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-header.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-headers.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-id.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-k-type.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-path.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-query.html create mode 100644 api/-net/com.drake.net.request/-base-request/set-url.html create mode 100644 api/-net/com.drake.net.request/-base-request/tag-of.html create mode 100644 api/-net/com.drake.net.request/-base-request/tag.html create mode 100644 api/-net/com.drake.net.request/-base-request/to-result.html create mode 100644 api/-net/com.drake.net.request/-body-request/-body-request.html create mode 100644 api/-net/com.drake.net.request/-body-request/add-upload-listener.html create mode 100644 api/-net/com.drake.net.request/-body-request/body.html create mode 100644 api/-net/com.drake.net.request/-body-request/build-request.html create mode 100644 api/-net/com.drake.net.request/-body-request/form-body.html create mode 100644 api/-net/com.drake.net.request/-body-request/index.html create mode 100644 api/-net/com.drake.net.request/-body-request/json.html create mode 100644 api/-net/com.drake.net.request/-body-request/media-type.html create mode 100644 api/-net/com.drake.net.request/-body-request/method.html create mode 100644 api/-net/com.drake.net.request/-body-request/param.html create mode 100644 api/-net/com.drake.net.request/-body-request/part-body.html create mode 100644 api/-net/com.drake.net.request/-media-const/-f-o-r-m.html create mode 100644 api/-net/com.drake.net.request/-media-const/-g-i-f.html create mode 100644 api/-net/com.drake.net.request/-media-const/-h-t-m-l.html create mode 100644 api/-net/com.drake.net.request/-media-const/-i-m-g.html create mode 100644 api/-net/com.drake.net.request/-media-const/-j-p-e-g.html create mode 100644 api/-net/com.drake.net.request/-media-const/-j-s-o-n.html create mode 100644 api/-net/com.drake.net.request/-media-const/-m-p4.html create mode 100644 api/-net/com.drake.net.request/-media-const/-o-c-t-e-t_-s-t-r-e-a-m.html create mode 100644 api/-net/com.drake.net.request/-media-const/-p-n-g.html create mode 100644 api/-net/com.drake.net.request/-media-const/-t-x-t.html create mode 100644 api/-net/com.drake.net.request/-media-const/-u-r-l-e-n-c-o-d-e-d.html create mode 100644 api/-net/com.drake.net.request/-media-const/-x-m-l.html create mode 100644 api/-net/com.drake.net.request/-media-const/index.html create mode 100644 api/-net/com.drake.net.request/-method/-d-e-l-e-t-e/index.html create mode 100644 api/-net/com.drake.net.request/-method/-g-e-t/index.html create mode 100644 api/-net/com.drake.net.request/-method/-h-e-a-d/index.html create mode 100644 api/-net/com.drake.net.request/-method/-o-p-t-i-o-n-s/index.html create mode 100644 api/-net/com.drake.net.request/-method/-p-a-t-c-h/index.html create mode 100644 api/-net/com.drake.net.request/-method/-p-o-s-t/index.html create mode 100644 api/-net/com.drake.net.request/-method/-p-u-t/index.html create mode 100644 api/-net/com.drake.net.request/-method/-t-r-a-c-e/index.html create mode 100644 api/-net/com.drake.net.request/-method/index.html create mode 100644 api/-net/com.drake.net.request/-url-request/-url-request.html create mode 100644 api/-net/com.drake.net.request/-url-request/index.html create mode 100644 api/-net/com.drake.net.request/-url-request/param.html create mode 100644 api/-net/com.drake.net.request/converter.html create mode 100644 api/-net/com.drake.net.request/download-conflict-rename.html create mode 100644 api/-net/com.drake.net.request/download-file-dir.html create mode 100644 api/-net/com.drake.net.request/download-file-name-decode.html create mode 100644 api/-net/com.drake.net.request/download-file-name.html create mode 100644 api/-net/com.drake.net.request/download-listeners.html create mode 100644 api/-net/com.drake.net.request/download-md5-verify.html create mode 100644 api/-net/com.drake.net.request/download-temp-file.html create mode 100644 api/-net/com.drake.net.request/extra.html create mode 100644 api/-net/com.drake.net.request/extras.html create mode 100644 api/-net/com.drake.net.request/group.html create mode 100644 api/-net/com.drake.net.request/headers.html create mode 100644 api/-net/com.drake.net.request/id.html create mode 100644 api/-net/com.drake.net.request/index.html create mode 100644 api/-net/com.drake.net.request/k-type.html create mode 100644 api/-net/com.drake.net.request/set-converter.html create mode 100644 api/-net/com.drake.net.request/set-extra.html create mode 100644 api/-net/com.drake.net.request/tag-of.html create mode 100644 api/-net/com.drake.net.request/tags.html create mode 100644 api/-net/com.drake.net.request/upload-listeners.html create mode 100644 api/-net/com.drake.net.response/convert.html create mode 100644 api/-net/com.drake.net.response/file-name.html create mode 100644 api/-net/com.drake.net.response/file.html create mode 100644 api/-net/com.drake.net.response/index.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/-android-scope.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/cancel.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/catch.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/close.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/coroutine-context.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/dispatcher.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/finally.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/handle-error.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/index.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/launch.html create mode 100644 api/-net/com.drake.net.scope/-android-scope/scope-group.html create mode 100644 api/-net/com.drake.net.scope/-dialog-coroutine-scope/-dialog-coroutine-scope.html create mode 100644 api/-net/com.drake.net.scope/-dialog-coroutine-scope/activity.html create mode 100644 api/-net/com.drake.net.scope/-dialog-coroutine-scope/cancelable.html create mode 100644 api/-net/com.drake.net.scope/-dialog-coroutine-scope/dialog.html create mode 100644 api/-net/com.drake.net.scope/-dialog-coroutine-scope/index.html create mode 100644 api/-net/com.drake.net.scope/-net-coroutine-scope/-net-coroutine-scope.html create mode 100644 api/-net/com.drake.net.scope/-net-coroutine-scope/cancel.html create mode 100644 api/-net/com.drake.net.scope/-net-coroutine-scope/handle-error.html create mode 100644 api/-net/com.drake.net.scope/-net-coroutine-scope/index.html create mode 100644 api/-net/com.drake.net.scope/-net-coroutine-scope/launch.html create mode 100644 api/-net/com.drake.net.scope/-net-coroutine-scope/preview.html create mode 100644 api/-net/com.drake.net.scope/-page-coroutine-scope/--index--.html create mode 100644 api/-net/com.drake.net.scope/-page-coroutine-scope/-page-coroutine-scope.html create mode 100644 api/-net/com.drake.net.scope/-page-coroutine-scope/handle-error.html create mode 100644 api/-net/com.drake.net.scope/-page-coroutine-scope/index.html create mode 100644 api/-net/com.drake.net.scope/-page-coroutine-scope/page.html create mode 100644 api/-net/com.drake.net.scope/-state-coroutine-scope/-state-coroutine-scope.html create mode 100644 api/-net/com.drake.net.scope/-state-coroutine-scope/handle-error.html create mode 100644 api/-net/com.drake.net.scope/-state-coroutine-scope/index.html create mode 100644 api/-net/com.drake.net.scope/-state-coroutine-scope/state.html create mode 100644 api/-net/com.drake.net.scope/-view-coroutine-scope/-view-coroutine-scope.html create mode 100644 api/-net/com.drake.net.scope/-view-coroutine-scope/index.html create mode 100644 api/-net/com.drake.net.scope/-view-coroutine-scope/view.html create mode 100644 api/-net/com.drake.net.scope/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-cache-key/-cache-key.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-cache-key/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-cache-key/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/-cache-valid-time.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/-download-file-conflict-rename.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-dir/-download-file-dir.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-dir/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-dir/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/-download-file-m-d5-verify.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/-download-file-name-decode.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-name/-download-file-name.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-name/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-file-name/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-listeners/-download-listeners.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-listeners/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-temp-file/-download-temp-file.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-temp-file/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-download-temp-file/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-extras/-extras.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-extras/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-group/-request-group.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-group/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-group/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-id/-request-id.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-id/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-id/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-k-type/-request-k-type.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-k-type/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-request-k-type/value.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-upload-listeners/-upload-listeners.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/-upload-listeners/index.html create mode 100644 api/-net/com.drake.net.tag/-net-tag/index.html create mode 100644 api/-net/com.drake.net.tag/index.html create mode 100644 api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-a-c-t-i-v-e/index.html create mode 100644 api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-i-d-l-e/index.html create mode 100644 api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-p-a-u-s-e/index.html create mode 100644 api/-net/com.drake.net.time/-interval-status/index.html create mode 100644 api/-net/com.drake.net.time/-interval/-interval.html create mode 100644 api/-net/com.drake.net.time/-interval/cancel.html create mode 100644 api/-net/com.drake.net.time/-interval/close.html create mode 100644 api/-net/com.drake.net.time/-interval/count.html create mode 100644 api/-net/com.drake.net.time/-interval/end.html create mode 100644 api/-net/com.drake.net.time/-interval/finish.html create mode 100644 api/-net/com.drake.net.time/-interval/index.html create mode 100644 api/-net/com.drake.net.time/-interval/life.html create mode 100644 api/-net/com.drake.net.time/-interval/only-resumed.html create mode 100644 api/-net/com.drake.net.time/-interval/pause.html create mode 100644 api/-net/com.drake.net.time/-interval/reset.html create mode 100644 api/-net/com.drake.net.time/-interval/resume.html create mode 100644 api/-net/com.drake.net.time/-interval/start.html create mode 100644 api/-net/com.drake.net.time/-interval/state.html create mode 100644 api/-net/com.drake.net.time/-interval/stop.html create mode 100644 api/-net/com.drake.net.time/-interval/subscribe.html create mode 100644 api/-net/com.drake.net.time/-interval/switch.html create mode 100644 api/-net/com.drake.net.time/index.html create mode 100644 api/-net/com.drake.net.transform/-deferred-transform/-deferred-transform.html create mode 100644 api/-net/com.drake.net.transform/-deferred-transform/block.html create mode 100644 api/-net/com.drake.net.transform/-deferred-transform/deferred.html create mode 100644 api/-net/com.drake.net.transform/-deferred-transform/index.html create mode 100644 api/-net/com.drake.net.transform/index.html create mode 100644 api/-net/com.drake.net.transform/transform.html create mode 100644 api/-net/com.drake.net.utils/-https/-un-safe-hostname-verifier.html create mode 100644 api/-net/com.drake.net.utils/-https/-un-safe-trust-manager.html create mode 100644 api/-net/com.drake.net.utils/-https/index.html create mode 100644 api/-net/com.drake.net.utils/-tip-utils/index.html create mode 100644 api/-net/com.drake.net.utils/-tip-utils/toast.html create mode 100644 api/-net/com.drake.net.utils/debounce.html create mode 100644 api/-net/com.drake.net.utils/fastest.html create mode 100644 api/-net/com.drake.net.utils/file-name.html create mode 100644 api/-net/com.drake.net.utils/index.html create mode 100644 api/-net/com.drake.net.utils/is-networking.html create mode 100644 api/-net/com.drake.net.utils/launch-in.html create mode 100644 api/-net/com.drake.net.utils/md5.html create mode 100644 api/-net/com.drake.net.utils/media-type.html create mode 100644 api/-net/com.drake.net.utils/run-main.html create mode 100644 api/-net/com.drake.net.utils/scope-dialog.html create mode 100644 api/-net/com.drake.net.utils/scope-life.html create mode 100644 api/-net/com.drake.net.utils/scope-net-life.html create mode 100644 api/-net/com.drake.net.utils/scope-net.html create mode 100644 api/-net/com.drake.net.utils/scope.html create mode 100644 api/-net/com.drake.net.utils/to-request-body.html create mode 100644 api/-net/com.drake.net.utils/with-default.html create mode 100644 api/-net/com.drake.net.utils/with-i-o.html create mode 100644 api/-net/com.drake.net.utils/with-main.html create mode 100644 api/-net/com.drake.net.utils/with-unconfined.html create mode 100644 api/-net/com.drake.net/-delete.html create mode 100644 api/-net/com.drake.net/-get.html create mode 100644 api/-net/com.drake.net/-head.html create mode 100644 api/-net/com.drake.net/-net-config/-t-a-g.html create mode 100644 api/-net/com.drake.net/-net-config/app.html create mode 100644 api/-net/com.drake.net/-net-config/converter.html create mode 100644 api/-net/com.drake.net/-net-config/debug.html create mode 100644 api/-net/com.drake.net/-net-config/dialog-factory.html create mode 100644 api/-net/com.drake.net/-net-config/error-handler.html create mode 100644 api/-net/com.drake.net/-net-config/host.html create mode 100644 api/-net/com.drake.net/-net-config/index.html create mode 100644 api/-net/com.drake.net/-net-config/initialize.html create mode 100644 api/-net/com.drake.net/-net-config/ok-http-client.html create mode 100644 api/-net/com.drake.net/-net-config/request-interceptor.html create mode 100644 api/-net/com.drake.net/-net-config/running-calls.html create mode 100644 api/-net/com.drake.net/-net/add-download-listener.html create mode 100644 api/-net/com.drake.net/-net/add-upload-listener.html create mode 100644 api/-net/com.drake.net/-net/cancel-all.html create mode 100644 api/-net/com.drake.net/-net/cancel-group.html create mode 100644 api/-net/com.drake.net/-net/cancel-id.html create mode 100644 api/-net/com.drake.net/-net/debug.html create mode 100644 api/-net/com.drake.net/-net/delete.html create mode 100644 api/-net/com.drake.net/-net/get-request-by-group.html create mode 100644 api/-net/com.drake.net/-net/get-request-by-id.html create mode 100644 api/-net/com.drake.net/-net/get.html create mode 100644 api/-net/com.drake.net/-net/head.html create mode 100644 api/-net/com.drake.net/-net/index.html create mode 100644 api/-net/com.drake.net/-net/options.html create mode 100644 api/-net/com.drake.net/-net/patch.html create mode 100644 api/-net/com.drake.net/-net/post.html create mode 100644 api/-net/com.drake.net/-net/put.html create mode 100644 api/-net/com.drake.net/-net/remove-download-listener.html create mode 100644 api/-net/com.drake.net/-net/remove-upload-listener.html create mode 100644 api/-net/com.drake.net/-net/trace.html create mode 100644 api/-net/com.drake.net/-options.html create mode 100644 api/-net/com.drake.net/-patch.html create mode 100644 api/-net/com.drake.net/-post.html create mode 100644 api/-net/com.drake.net/-put.html create mode 100644 api/-net/com.drake.net/-trace.html create mode 100644 api/-net/com.drake.net/index.html create mode 100644 api/-net/okhttp3/-ok-http-utils/add-lenient.html create mode 100644 api/-net/okhttp3/-ok-http-utils/disk-lru-cache.html create mode 100644 api/-net/okhttp3/-ok-http-utils/headers.html create mode 100644 api/-net/okhttp3/-ok-http-utils/index.html create mode 100644 api/-net/okhttp3/-ok-http-utils/tags.html create mode 100644 api/-net/okhttp3/index.html create mode 100644 api/-net/package-list create mode 100644 api/images/anchor-copy-button.svg create mode 100644 api/images/arrow_down.svg create mode 100644 api/images/copy-icon.svg create mode 100644 api/images/copy-successful-icon.svg create mode 100644 api/images/docs_logo.svg create mode 100644 api/images/footer-go-to-link.svg create mode 100644 api/images/go-to-top-icon.svg create mode 100644 api/images/logo-icon.svg create mode 100644 api/index.html create mode 100644 api/navigation.html create mode 100644 api/scripts/clipboard.js create mode 100644 api/scripts/main.js create mode 100644 api/scripts/navigation-loader.js create mode 100644 api/scripts/navigation-pane.json create mode 100644 api/scripts/pages.json create mode 100644 api/scripts/platform-content-handler.js create mode 100644 api/scripts/sourceset_dependencies.js create mode 100644 api/styles/jetbrains-mono.css create mode 100644 api/styles/logo-styles.css create mode 100644 api/styles/main.css create mode 100644 api/styles/style.css create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.220ee61c.min.js create mode 100644 assets/javascripts/bundle.220ee61c.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.74e28a9f.min.js create mode 100644 assets/javascripts/workers/search.74e28a9f.min.js.map create mode 100644 assets/stylesheets/main.eebd395e.min.css create mode 100644 assets/stylesheets/main.eebd395e.min.css.map create mode 100644 assets/stylesheets/palette.ecc896b0.min.css create mode 100644 assets/stylesheets/palette.ecc896b0.min.css.map create mode 100644 auto-dialog.html create mode 100644 auto-pull.html create mode 100644 auto-refresh.html create mode 100644 auto-state.html create mode 100644 cache.html create mode 100644 callback.html create mode 100644 cancel.html create mode 100644 config.html create mode 100644 converter-customize.html create mode 100644 converter-struct.html create mode 100644 converter.html create mode 100644 cookie.html create mode 100644 coroutine-request.html create mode 100644 css/extra.css create mode 100644 debounce.html create mode 100644 download-file.html create mode 100644 error-global.html create mode 100644 error-single.html create mode 100644 error-throws.html create mode 100644 error-tip.html create mode 100644 error.html create mode 100644 fastest.html create mode 100644 https.html create mode 100644 img/book-open.svg create mode 100644 img/code-preview.png create mode 100644 img/discussesions.svg create mode 100644 img/issues.svg create mode 100644 img/logo.gif create mode 100644 img/preview.png create mode 100644 index.html create mode 100644 interceptor.html create mode 100644 interval.html create mode 100644 issues.html create mode 100644 kotlin-serialization.html create mode 100644 log-notice.html create mode 100644 log-recorder.html create mode 100644 material/partials/footer.html create mode 100644 model-generate.html create mode 100644 okhttp-client.html create mode 100644 progress.html create mode 100644 repeat-request.html create mode 100644 request.html create mode 100644 scope.html create mode 100644 search/search_index.js create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 sync-request.html create mode 100644 tag.html create mode 100644 thread.html create mode 100644 timing.html create mode 100644 track.html create mode 100644 updates.html create mode 100644 upload-file.html create mode 100644 view-model.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..eac087d7b --- /dev/null +++ b/404.html @@ -0,0 +1,1104 @@ + + + + + + + + + + + + + + + + + + + + + + Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/-net/androidx.lifecycle/index.html b/api/-net/androidx.lifecycle/index.html new file mode 100644 index 000000000..dd21e7808 --- /dev/null +++ b/api/-net/androidx.lifecycle/index.html @@ -0,0 +1,90 @@ + + + + androidx.lifecycle + + +
+
+ + +
+
+
+
+
+
+ +
+

Package androidx.lifecycle

+
+
+
+
+

Functions

+
+
+
+
life +
Link copied to clipboard
+
+
+
+ +
+
fun Interval.life(viewModel: ViewModel): <ERROR CLASS>
+
+
轮询器根据ViewModel生命周期自动取消
+
+
+
+
+ +
+
+
scopeLife +
Link copied to clipboard
+
+
+
+ +
+
fun ViewModel.scopeLife(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+
ViewModel被销毁时取消协程作用域
+
+
+
+
+ +
+
+
scopeNetLife +
Link copied to clipboard
+
+
+
+ +
+
fun ViewModel.scopeNetLife(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
ViewModel被销毁时取消协程作用域以及其中的网络请求 具备网络错误全局处理功能, 其内部的网络请求会跟随其作用域的生命周期
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/androidx.lifecycle/life.html b/api/-net/androidx.lifecycle/life.html new file mode 100644 index 000000000..0d9f1d51f --- /dev/null +++ b/api/-net/androidx.lifecycle/life.html @@ -0,0 +1,38 @@ + + + + life + + +
+
+ + +
+
+
+
+
+
+ +
+

life

+
+
+ +
+
fun Interval.life(viewModel: ViewModel): <ERROR CLASS>
+
+

轮询器根据ViewModel生命周期自动取消

+
+ +
+
+ + + diff --git a/api/-net/androidx.lifecycle/scope-life.html b/api/-net/androidx.lifecycle/scope-life.html new file mode 100644 index 000000000..fde71e6a7 --- /dev/null +++ b/api/-net/androidx.lifecycle/scope-life.html @@ -0,0 +1,38 @@ + + + + scopeLife + + +
+
+ + +
+
+
+
+
+
+ +
+

scopeLife

+
+
+ +
+
fun ViewModel.scopeLife(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+

ViewModel被销毁时取消协程作用域

+
+ +
+
+ + + diff --git a/api/-net/androidx.lifecycle/scope-net-life.html b/api/-net/androidx.lifecycle/scope-net-life.html new file mode 100644 index 000000000..3596a8d21 --- /dev/null +++ b/api/-net/androidx.lifecycle/scope-net-life.html @@ -0,0 +1,38 @@ + + + + scopeNetLife + + +
+
+ + +
+
+
+
+
+
+ +
+

scopeNetLife

+
+
+ +
+
fun ViewModel.scopeNetLife(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+

ViewModel被销毁时取消协程作用域以及其中的网络请求 具备网络错误全局处理功能, 其内部的网络请求会跟随其作用域的生命周期

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-request-body/-net-request-body.html b/api/-net/com.drake.net.body/-net-request-body/-net-request-body.html new file mode 100644 index 000000000..d6fedf77c --- /dev/null +++ b/api/-net/com.drake.net.body/-net-request-body/-net-request-body.html @@ -0,0 +1,38 @@ + + + + NetRequestBody + + +
+
+ + +
+
+
+
+
+
+ +
+

NetRequestBody

+
+
+ +
+
fun NetRequestBody(body: RequestBody, progressListeners: ConcurrentLinkedQueue<ProgressListener>? = null)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-request-body/content-length.html b/api/-net/com.drake.net.body/-net-request-body/content-length.html new file mode 100644 index 000000000..fe15b9d3b --- /dev/null +++ b/api/-net/com.drake.net.body/-net-request-body/content-length.html @@ -0,0 +1,38 @@ + + + + contentLength + + +
+
+ + +
+
+
+
+
+
+ +
+

contentLength

+
+
+ +
+
open override fun contentLength(): Long
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-request-body/content-type.html b/api/-net/com.drake.net.body/-net-request-body/content-type.html new file mode 100644 index 000000000..13c40fd5a --- /dev/null +++ b/api/-net/com.drake.net.body/-net-request-body/content-type.html @@ -0,0 +1,38 @@ + + + + contentType + + +
+
+ + +
+
+
+
+
+
+ +
+

contentType

+
+
+ +
+
open override fun contentType(): MediaType?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-request-body/index.html b/api/-net/com.drake.net.body/-net-request-body/index.html new file mode 100644 index 000000000..af1c4197f --- /dev/null +++ b/api/-net/com.drake.net.body/-net-request-body/index.html @@ -0,0 +1,91 @@ + + + + NetRequestBody + + +
+
+ + +
+
+
+
+
+
+ +
+

NetRequestBody

+
class NetRequestBody(body: RequestBody, progressListeners: ConcurrentLinkedQueue<ProgressListener>?) : RequestBody
+
+
+
+
+

Functions

+
+
+
+
contentLength +
Link copied to clipboard
+
+
+
+ +
+
open override fun contentLength(): Long
+
+
+
+
+
+
+ +
+
+
contentType +
Link copied to clipboard
+
+
+
+ +
+
open override fun contentType(): MediaType?
+
+
+
+
+
+
+ +
+
+
writeTo +
Link copied to clipboard
+
+
+
+ +
+
open override fun writeTo(sink: BufferedSink)
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-request-body/write-to.html b/api/-net/com.drake.net.body/-net-request-body/write-to.html new file mode 100644 index 000000000..a0a717e07 --- /dev/null +++ b/api/-net/com.drake.net.body/-net-request-body/write-to.html @@ -0,0 +1,38 @@ + + + + writeTo + + +
+
+ + +
+
+
+
+
+
+ +
+

writeTo

+
+
+ +
+
open override fun writeTo(sink: BufferedSink)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-response-body/-net-response-body.html b/api/-net/com.drake.net.body/-net-response-body/-net-response-body.html new file mode 100644 index 000000000..aebb2cf34 --- /dev/null +++ b/api/-net/com.drake.net.body/-net-response-body/-net-response-body.html @@ -0,0 +1,38 @@ + + + + NetResponseBody + + +
+
+ + +
+
+
+
+
+
+ +
+

NetResponseBody

+
+
+ +
+
fun NetResponseBody(body: ResponseBody, progressListeners: ConcurrentLinkedQueue<ProgressListener>? = null, complete: () -> Unit? = null)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-response-body/content-length.html b/api/-net/com.drake.net.body/-net-response-body/content-length.html new file mode 100644 index 000000000..73cfd2d77 --- /dev/null +++ b/api/-net/com.drake.net.body/-net-response-body/content-length.html @@ -0,0 +1,38 @@ + + + + contentLength + + +
+
+ + +
+
+
+
+
+
+ +
+

contentLength

+
+
+ +
+
open override fun contentLength(): Long
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-response-body/content-type.html b/api/-net/com.drake.net.body/-net-response-body/content-type.html new file mode 100644 index 000000000..309ff05f5 --- /dev/null +++ b/api/-net/com.drake.net.body/-net-response-body/content-type.html @@ -0,0 +1,38 @@ + + + + contentType + + +
+
+ + +
+
+
+
+
+
+ +
+

contentType

+
+
+ +
+
open override fun contentType(): MediaType?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-response-body/index.html b/api/-net/com.drake.net.body/-net-response-body/index.html new file mode 100644 index 000000000..3fb8e94e0 --- /dev/null +++ b/api/-net/com.drake.net.body/-net-response-body/index.html @@ -0,0 +1,91 @@ + + + + NetResponseBody + + +
+
+ + +
+
+
+
+
+
+ +
+

NetResponseBody

+
class NetResponseBody(body: ResponseBody, progressListeners: ConcurrentLinkedQueue<ProgressListener>?, complete: () -> Unit?) : ResponseBody
+
+
+
+
+

Functions

+
+
+
+
contentLength +
Link copied to clipboard
+
+
+
+ +
+
open override fun contentLength(): Long
+
+
+
+
+
+
+ +
+
+
contentType +
Link copied to clipboard
+
+
+
+ +
+
open override fun contentType(): MediaType?
+
+
+
+
+
+
+ +
+
+
source +
Link copied to clipboard
+
+
+
+ +
+
open override fun source(): BufferedSource
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/-net-response-body/source.html b/api/-net/com.drake.net.body/-net-response-body/source.html new file mode 100644 index 000000000..6dad57d54 --- /dev/null +++ b/api/-net/com.drake.net.body/-net-response-body/source.html @@ -0,0 +1,38 @@ + + + + source + + +
+
+ + +
+
+
+
+
+
+ +
+

source

+
+
+ +
+
open override fun source(): BufferedSource
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/file-name.html b/api/-net/com.drake.net.body/file-name.html new file mode 100644 index 000000000..1ae8c1cfc --- /dev/null +++ b/api/-net/com.drake.net.body/file-name.html @@ -0,0 +1,38 @@ + + + + fileName + + +
+
+ + +
+
+
+
+
+
+ +
+

fileName

+
+
+ +
+
fun MultipartBody.Part.fileName(): String?
+
+

获取Content-Disposition里面的filename属性值 可以此来判断是否为文件类型

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/index.html b/api/-net/com.drake.net.body/index.html new file mode 100644 index 000000000..8d58898b4 --- /dev/null +++ b/api/-net/com.drake.net.body/index.html @@ -0,0 +1,183 @@ + + + + com.drake.net.body + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.body

+
+
+
+
+

Types

+
+
+
+
NetRequestBody +
Link copied to clipboard
+
+
+
+ +
+
class NetRequestBody(body: RequestBody, progressListeners: ConcurrentLinkedQueue<ProgressListener>?) : RequestBody
+
+
+
+
+
+
+ +
+
+
NetResponseBody +
Link copied to clipboard
+
+
+
+ +
+
class NetResponseBody(body: ResponseBody, progressListeners: ConcurrentLinkedQueue<ProgressListener>?, complete: () -> Unit?) : ResponseBody
+
+
+
+
+
+
+
+

Functions

+
+
+
+
fileName +
Link copied to clipboard
+
+
+
+ +
+
fun MultipartBody.Part.fileName(): String?
+
+
获取Content-Disposition里面的filename属性值 可以此来判断是否为文件类型
+
+
+
+
+ +
+
+
name +
Link copied to clipboard
+
+
+
+ +
+
fun MultipartBody.Part.name(): String?
+
+
获取Content-Disposition里面的字段名称
+
+
+
+
+ +
+
+
peekBytes +
Link copied to clipboard
+
+
+
+ +
+
fun RequestBody.peekBytes(byteCount: Long = 1024 * 1024): ByteString
+
+
复制一段指定长度的字符串内容
+
+ +
+
fun ResponseBody.peekBytes(byteCount: Long = 1024 * 1024): ByteString
+
+
复制一段指定长度的字符串内容
+
+
+
+
+ +
+
+
toNetRequestBody +
Link copied to clipboard
+
+
+
+ +
+
fun RequestBody.toNetRequestBody(listeners: ConcurrentLinkedQueue<ProgressListener>? = null): NetRequestBody
+
+
+
+
+
+
+ +
+
+
toNetResponseBody +
Link copied to clipboard
+
+
+
+ +
+
fun ResponseBody.toNetResponseBody(listeners: ConcurrentLinkedQueue<ProgressListener>? = null, complete: () -> Unit? = null): NetResponseBody
+
+
+
+
+
+
+ +
+
+
value +
Link copied to clipboard
+
+
+
+ +
+
fun MultipartBody.Part.value(): String?
+
+
MultipartBody.Part.body作为字符串返回 如果MultipartBody.Part有指定fileName那么视为文件类型将返回fileName值而不是文件内容
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/name.html b/api/-net/com.drake.net.body/name.html new file mode 100644 index 000000000..42b72a8a7 --- /dev/null +++ b/api/-net/com.drake.net.body/name.html @@ -0,0 +1,38 @@ + + + + name + + +
+
+ + +
+
+
+
+
+
+ +
+

name

+
+
+ +
+
fun MultipartBody.Part.name(): String?
+
+

获取Content-Disposition里面的字段名称

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/peek-bytes.html b/api/-net/com.drake.net.body/peek-bytes.html new file mode 100644 index 000000000..c364da045 --- /dev/null +++ b/api/-net/com.drake.net.body/peek-bytes.html @@ -0,0 +1,38 @@ + + + + peekBytes + + +
+
+ + +
+
+
+
+
+
+ +
+

peekBytes

+
+
+ +
+
fun RequestBody.peekBytes(byteCount: Long = 1024 * 1024): ByteString
fun ResponseBody.peekBytes(byteCount: Long = 1024 * 1024): ByteString
+
+

复制一段指定长度的字符串内容

Parameters

byteCount

复制的字节长度, 允许超过实际长度, 如果-1则返回完整的字符串内容

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/to-net-request-body.html b/api/-net/com.drake.net.body/to-net-request-body.html new file mode 100644 index 000000000..cd4a10aee --- /dev/null +++ b/api/-net/com.drake.net.body/to-net-request-body.html @@ -0,0 +1,38 @@ + + + + toNetRequestBody + + +
+
+ + +
+
+
+
+
+
+ +
+

toNetRequestBody

+
+
+ +
+
fun RequestBody.toNetRequestBody(listeners: ConcurrentLinkedQueue<ProgressListener>? = null): NetRequestBody
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/to-net-response-body.html b/api/-net/com.drake.net.body/to-net-response-body.html new file mode 100644 index 000000000..cd27dfb26 --- /dev/null +++ b/api/-net/com.drake.net.body/to-net-response-body.html @@ -0,0 +1,38 @@ + + + + toNetResponseBody + + +
+
+ + +
+
+
+
+
+
+ +
+

toNetResponseBody

+
+
+ +
+
fun ResponseBody.toNetResponseBody(listeners: ConcurrentLinkedQueue<ProgressListener>? = null, complete: () -> Unit? = null): NetResponseBody
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.body/value.html b/api/-net/com.drake.net.body/value.html new file mode 100644 index 000000000..924931438 --- /dev/null +++ b/api/-net/com.drake.net.body/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
fun MultipartBody.Part.value(): String?
+
+

MultipartBody.Part.body作为字符串返回 如果MultipartBody.Part有指定fileName那么视为文件类型将返回fileName值而不是文件内容

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d/index.html b/api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d/index.html new file mode 100644 index 000000000..381898db3 --- /dev/null +++ b/api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d/index.html @@ -0,0 +1,37 @@ + + + + READ + + +
+
+ + +
+
+
+
+
+
+ +
+

READ

+

只读取缓存, 本操作并不会请求网络故不存在写入缓存

+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d_-t-h-e-n_-r-e-q-u-e-s-t/index.html b/api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d_-t-h-e-n_-r-e-q-u-e-s-t/index.html new file mode 100644 index 000000000..73fd65259 --- /dev/null +++ b/api/-net/com.drake.net.cache/-cache-mode/-r-e-a-d_-t-h-e-n_-r-e-q-u-e-s-t/index.html @@ -0,0 +1,37 @@ + + + + READ_THEN_REQUEST + + +
+
+ + +
+
+
+
+
+
+ +
+

READ_THEN_REQUEST

+

先从缓存读取,如果失败再从网络读取, 强制写入缓存

+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-cache-mode/-r-e-q-u-e-s-t_-t-h-e-n_-r-e-a-d/index.html b/api/-net/com.drake.net.cache/-cache-mode/-r-e-q-u-e-s-t_-t-h-e-n_-r-e-a-d/index.html new file mode 100644 index 000000000..6807bf0ff --- /dev/null +++ b/api/-net/com.drake.net.cache/-cache-mode/-r-e-q-u-e-s-t_-t-h-e-n_-r-e-a-d/index.html @@ -0,0 +1,37 @@ + + + + REQUEST_THEN_READ + + +
+
+ + +
+
+
+
+
+
+ +
+

REQUEST_THEN_READ

+

先从网络读取,如果失败再从缓存读取, 强制写入缓存

+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-cache-mode/-w-r-i-t-e/index.html b/api/-net/com.drake.net.cache/-cache-mode/-w-r-i-t-e/index.html new file mode 100644 index 000000000..3039f69a1 --- /dev/null +++ b/api/-net/com.drake.net.cache/-cache-mode/-w-r-i-t-e/index.html @@ -0,0 +1,37 @@ + + + + WRITE + + +
+
+ + +
+
+
+
+
+
+ +
+

WRITE

+

只请求网络, 强制写入缓存

+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-cache-mode/index.html b/api/-net/com.drake.net.cache/-cache-mode/index.html new file mode 100644 index 000000000..e62aabd7a --- /dev/null +++ b/api/-net/com.drake.net.cache/-cache-mode/index.html @@ -0,0 +1,92 @@ + + + + CacheMode + + +
+
+ + +
+
+
+
+
+
+ +
+

CacheMode

+
enum CacheMode : Enum<CacheMode>
+
+
+
+
+

Entries

+
+
+
+
REQUEST_THEN_READ +
Link copied to clipboard
+
+
+
+
先从网络读取,如果失败再从缓存读取, 强制写入缓存
+
+
+
+
+ +
+
+
READ_THEN_REQUEST +
Link copied to clipboard
+
+
+
+
先从缓存读取,如果失败再从网络读取, 强制写入缓存
+
+
+
+
+ +
+
+
WRITE +
Link copied to clipboard
+
+
+
+
只请求网络, 强制写入缓存
+
+
+
+
+ +
+
+
READ +
Link copied to clipboard
+
+
+
+
只读取缓存, 本操作并不会请求网络故不存在写入缓存
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/-companion/has-vary-all.html b/api/-net/com.drake.net.cache/-force-cache/-companion/has-vary-all.html new file mode 100644 index 000000000..f6c824b4a --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/-companion/has-vary-all.html @@ -0,0 +1,38 @@ + + + + hasVaryAll + + +
+
+ + +
+
+
+
+
+
+ +
+

hasVaryAll

+
+
+ +
+
fun Response.hasVaryAll(): Boolean
+
+

Returns true if a Vary header contains an asterisk. Such responses cannot be cached.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/-companion/index.html b/api/-net/com.drake.net.cache/-force-cache/-companion/index.html new file mode 100644 index 000000000..e59fade5c --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/-companion/index.html @@ -0,0 +1,108 @@ + + + + Companion + + +
+
+ + +
+
+
+
+
+
+ +
+

Companion

+
object Companion
+
+
+
+
+

Functions

+
+
+
+
hasVaryAll +
Link copied to clipboard
+
+
+
+ +
+
fun Response.hasVaryAll(): Boolean
+
+
Returns true if a Vary header contains an asterisk.
+
+
+
+
+ +
+
+
key +
Link copied to clipboard
+
+
+
+ +
+
fun key(request: Request): String
+
+
+
+
+
+
+ +
+
+
varyHeaders +
Link copied to clipboard
+
+
+
+ +
+
fun Response.varyHeaders(): Headers
+
+
Returns the subset of the headers in this's request that impact the content of this's body.
+
+
+
+
+ +
+
+
varyMatches +
Link copied to clipboard
+
+
+
+ +
+
fun varyMatches(cachedResponse: Response, cachedRequest: Headers, newRequest: Request): Boolean
+
+
Returns true if none of the Vary headers have changed between cachedRequest and newRequest.
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/-companion/key.html b/api/-net/com.drake.net.cache/-force-cache/-companion/key.html new file mode 100644 index 000000000..6328b699b --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/-companion/key.html @@ -0,0 +1,38 @@ + + + + key + + +
+
+ + +
+
+
+
+
+
+ +
+

key

+
+
+ +
+
fun key(request: Request): String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/-companion/vary-headers.html b/api/-net/com.drake.net.cache/-force-cache/-companion/vary-headers.html new file mode 100644 index 000000000..ef429ed6f --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/-companion/vary-headers.html @@ -0,0 +1,38 @@ + + + + varyHeaders + + +
+
+ + +
+
+
+
+
+
+ +
+

varyHeaders

+
+
+ +
+
fun Response.varyHeaders(): Headers
+
+

Returns the subset of the headers in this's request that impact the content of this's body.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/-companion/vary-matches.html b/api/-net/com.drake.net.cache/-force-cache/-companion/vary-matches.html new file mode 100644 index 000000000..5b3acddf6 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/-companion/vary-matches.html @@ -0,0 +1,38 @@ + + + + varyMatches + + +
+
+ + +
+
+
+
+
+
+ +
+

varyMatches

+
+
+ +
+
fun varyMatches(cachedResponse: Response, cachedRequest: Headers, newRequest: Request): Boolean
+
+

Returns true if none of the Vary headers have changed between cachedRequest and newRequest.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/cache.html b/api/-net/com.drake.net.cache/-force-cache/cache.html new file mode 100644 index 000000000..75c80718c --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/cache.html @@ -0,0 +1,38 @@ + + + + cache + + +
+
+ + +
+
+
+
+
+
+ +
+

cache

+
+
+ +
+
val cache: DiskLruCache
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/close.html b/api/-net/com.drake.net.cache/-force-cache/close.html new file mode 100644 index 000000000..7de57ead5 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/close.html @@ -0,0 +1,38 @@ + + + + close + + +
+
+ + +
+
+
+
+
+
+ +
+

close

+
+
+ +
+
open override fun close()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/delete.html b/api/-net/com.drake.net.cache/-force-cache/delete.html new file mode 100644 index 000000000..03c342090 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/delete.html @@ -0,0 +1,38 @@ + + + + delete + + +
+
+ + +
+
+
+
+
+
+ +
+

delete

+
+
+ +
+
fun delete()
+
+

Closes the cache and deletes all of its stored values. This will delete all files in the cache directory including files that weren't created by the cache.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/directory.html b/api/-net/com.drake.net.cache/-force-cache/directory.html new file mode 100644 index 000000000..8f75c01e7 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/directory.html @@ -0,0 +1,38 @@ + + + + directory + + +
+
+ + +
+
+
+
+
+
+ +
+

directory

+
+
+ +
+
val directory: File
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/evict-all.html b/api/-net/com.drake.net.cache/-force-cache/evict-all.html new file mode 100644 index 000000000..64b11f421 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/evict-all.html @@ -0,0 +1,38 @@ + + + + evictAll + + +
+
+ + +
+
+
+
+
+
+ +
+

evictAll

+
+
+ +
+
fun evictAll()
+
+

Deletes all values stored in the cache. In-flight writes to the cache will complete normally, but the corresponding responses will not be stored.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/flush.html b/api/-net/com.drake.net.cache/-force-cache/flush.html new file mode 100644 index 000000000..76be5c4d4 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/flush.html @@ -0,0 +1,38 @@ + + + + flush + + +
+
+ + +
+
+
+
+
+
+ +
+

flush

+
+
+ +
+
open override fun flush()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/index.html b/api/-net/com.drake.net.cache/-force-cache/index.html new file mode 100644 index 000000000..ab3f16fe1 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/index.html @@ -0,0 +1,270 @@ + + + + ForceCache + + +
+
+ + +
+
+
+
+
+
+ +
+

ForceCache

+
class ForceCache : Closeable, Flushable

Caches HTTP and HTTPS responses to the filesystem so they may be reused, saving time and bandwidth.

Cache Optimization

To measure cache effectiveness, this class tracks three statistics:

  • requestCount the number of HTTP requests issued since this cache was created.

  • networkCount the number of those requests that required network use.

  • hitCount the number of those requests whose responses were served by the cache.

Sometimes a request will result in a conditional cache hit. If the cache contains a stale copy of the response, the client will issue a conditional GET. The server will then send either the updated response if it has changed, or a short 'not modified' response if the client's copy is still valid. Such responses increment both the network count and hit count.

The best way to improve the cache hit rate is by configuring the web server to return cacheable responses. Although this client honors all HTTP/1.1 (RFC 7234) cache headers, it doesn't cache partial responses.

Force a Network Response

In some situations, such as after a user clicks a 'refresh' button, it may be necessary to skip the cache, and fetch data directly from the server. To force a full refresh, add the no-cache directive:

Request request = new Request.Builder()
.cacheControl(new CacheControl.Builder().noCache().build())
.url("http://publicobject.com/helloworld.txt")
.build();

If it is only necessary to force a cached response to be validated by the server, use the more efficient max-age=0 directive instead:

Request request = new Request.Builder()
.cacheControl(new CacheControl.Builder()
.maxAge(0, TimeUnit.SECONDS)
.build())
.url("http://publicobject.com/helloworld.txt")
.build();

Force a Cache Response

Sometimes you'll want to show resources if they are available immediately, but not otherwise. This can be used so your application can show something while waiting for the latest data to be downloaded. To restrict a request to locally-cached resources, add the only-if-cached directive:

Request request = new Request.Builder()
.cacheControl(new CacheControl.Builder()
.onlyIfCached()
.build())
.url("http://publicobject.com/helloworld.txt")
.build();
Response forceCacheResponse = client.newCall(request).execute();
if (forceCacheResponse.code() != 504) {
// The resource was cached! Show it.
} else {
// The resource was not cached.
}

This technique works even better in situations where a stale response is better than no response. To permit stale cached responses, use the max-stale directive with the maximum staleness in seconds:

Request request = new Request.Builder()
.cacheControl(new CacheControl.Builder()
.maxStale(365, TimeUnit.DAYS)
.build())
.url("http://publicobject.com/helloworld.txt")
.build();

The CacheControl class can configure request caching directives and parse response caching directives. It even offers convenient constants CacheControl.FORCE_NETWORK and CacheControl.FORCE_CACHE that address the use cases above.

+
+
+
+
+

Types

+
+
+
+
Companion +
Link copied to clipboard
+
+
+
+ +
+
object Companion
+
+
+
+
+
+
+
+

Functions

+
+
+
+
close +
Link copied to clipboard
+
+
+
+ +
+
open override fun close()
+
+
+
+
+
+
+ +
+
+
delete +
Link copied to clipboard
+
+
+
+ +
+
fun delete()
+
+
Closes the cache and deletes all of its stored values.
+
+
+
+
+ +
+
+
evictAll +
Link copied to clipboard
+
+
+
+ +
+
fun evictAll()
+
+
Deletes all values stored in the cache.
+
+
+
+
+ +
+
+
flush +
Link copied to clipboard
+
+
+
+ +
+
open override fun flush()
+
+
+
+
+
+
+ +
+
+
initialize +
Link copied to clipboard
+
+
+
+ +
+
fun initialize()
+
+
Initialize the cache.
+
+
+
+
+ +
+
+
maxSize +
Link copied to clipboard
+
+
+
+ +
+
fun maxSize(): Long
+
+
Max size of the cache (in bytes).
+
+
+
+
+ +
+
+
size +
Link copied to clipboard
+
+
+
+ +
+
fun size(): Long
+
+
+
+
+
+
+ +
+
+
urls +
Link copied to clipboard
+
+
+
+ +
+
fun urls(): MutableIterator<String>
+
+
Returns an iterator over the URLs in this cache.
+
+
+
+
+ +
+
+
writeAbortCount +
Link copied to clipboard
+
+
+
+ +
+
fun writeAbortCount(): Int
+
+
+
+
+
+
+ +
+
+
writeSuccessCount +
Link copied to clipboard
+
+
+
+ +
+
fun writeSuccessCount(): Int
+
+
+
+
+
+
+
+

Properties

+
+
+
+
cache +
Link copied to clipboard
+
+
+
+
val cache: DiskLruCache
+
+
+
+
+ +
+
+
directory +
Link copied to clipboard
+
+
+
+
val directory: File
+
+
+
+
+ +
+
+
isClosed +
Link copied to clipboard
+
+
+
+
val isClosed: Boolean
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/initialize.html b/api/-net/com.drake.net.cache/-force-cache/initialize.html new file mode 100644 index 000000000..fd073b7d7 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/initialize.html @@ -0,0 +1,38 @@ + + + + initialize + + +
+
+ + +
+
+
+
+
+
+ +
+

initialize

+
+
+ +
+
fun initialize()
+
+

Initialize the cache. This will include reading the journal files from the storage and building up the necessary in-memory cache information.

The initialization time may vary depending on the journal file size and the current actual cache size. The application needs to be aware of calling this function during the initialization phase and preferably in a background worker thread.

Note that if the application chooses to not call this method to initialize the cache. By default, OkHttp will perform lazy initialization upon the first usage of the cache.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/is-closed.html b/api/-net/com.drake.net.cache/-force-cache/is-closed.html new file mode 100644 index 000000000..f794ee742 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/is-closed.html @@ -0,0 +1,38 @@ + + + + isClosed + + +
+
+ + +
+
+
+
+
+
+ +
+

isClosed

+
+
+ +
+
val isClosed: Boolean
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/max-size.html b/api/-net/com.drake.net.cache/-force-cache/max-size.html new file mode 100644 index 000000000..329ee1c90 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/max-size.html @@ -0,0 +1,38 @@ + + + + maxSize + + +
+
+ + +
+
+
+
+
+
+ +
+

maxSize

+
+
+ +
+
fun maxSize(): Long
+
+

Max size of the cache (in bytes).

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/size.html b/api/-net/com.drake.net.cache/-force-cache/size.html new file mode 100644 index 000000000..a75de6881 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/size.html @@ -0,0 +1,38 @@ + + + + size + + +
+
+ + +
+
+
+
+
+
+ +
+

size

+
+
+ +
+
fun size(): Long
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/urls.html b/api/-net/com.drake.net.cache/-force-cache/urls.html new file mode 100644 index 000000000..1ee185edd --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/urls.html @@ -0,0 +1,38 @@ + + + + urls + + +
+
+ + +
+
+
+
+
+
+ +
+

urls

+
+
+ +
+
fun urls(): MutableIterator<String>
+
+

Returns an iterator over the URLs in this cache. This iterator doesn't throw ConcurrentModificationException, but if new responses are added while iterating, their URLs will not be returned. If existing responses are evicted during iteration, they will be absent (unless they were already returned).

The iterator supports MutableIterator.remove. Removing a URL from the iterator evicts the corresponding response from the cache. Use this to evict selected responses.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/write-abort-count.html b/api/-net/com.drake.net.cache/-force-cache/write-abort-count.html new file mode 100644 index 000000000..dc2f37981 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/write-abort-count.html @@ -0,0 +1,38 @@ + + + + writeAbortCount + + +
+
+ + +
+
+
+
+
+
+ +
+

writeAbortCount

+
+
+ +
+
fun writeAbortCount(): Int
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/-force-cache/write-success-count.html b/api/-net/com.drake.net.cache/-force-cache/write-success-count.html new file mode 100644 index 000000000..f304ebc89 --- /dev/null +++ b/api/-net/com.drake.net.cache/-force-cache/write-success-count.html @@ -0,0 +1,38 @@ + + + + writeSuccessCount + + +
+
+ + +
+
+
+
+
+
+ +
+

writeSuccessCount

+
+
+ +
+
fun writeSuccessCount(): Int
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cache/index.html b/api/-net/com.drake.net.cache/index.html new file mode 100644 index 000000000..2d012c1aa --- /dev/null +++ b/api/-net/com.drake.net.cache/index.html @@ -0,0 +1,73 @@ + + + + com.drake.net.cache + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.cache

+
+
+
+
+

Types

+
+
+
+
CacheMode +
Link copied to clipboard
+
+
+
+ +
+
enum CacheMode : Enum<CacheMode>
+
+
+
+
+
+
+ +
+
+
ForceCache +
Link copied to clipboard
+
+
+
+ +
+
class ForceCache : Closeable, Flushable
+
+
Caches HTTP and HTTPS responses to the filesystem so they may be reused, saving time and bandwidth.
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/-progress.html b/api/-net/com.drake.net.component/-progress/-progress.html new file mode 100644 index 000000000..a37e7df36 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/-progress.html @@ -0,0 +1,38 @@ + + + + Progress + + +
+
+ + +
+
+
+
+
+
+ +
+

Progress

+
+
+ +
+
fun Progress()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/current-byte-count.html b/api/-net/com.drake.net.component/-progress/current-byte-count.html new file mode 100644 index 000000000..2cfe6a5ff --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/current-byte-count.html @@ -0,0 +1,38 @@ + + + + currentByteCount + + +
+
+ + +
+
+
+
+
+
+ +
+

currentByteCount

+
+
+ +
+
var currentByteCount: Long = 0
+
+

当前已经完成的字节数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/current-size.html b/api/-net/com.drake.net.component/-progress/current-size.html new file mode 100644 index 000000000..b94b66cf1 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/current-size.html @@ -0,0 +1,38 @@ + + + + currentSize + + +
+
+ + +
+
+
+
+
+
+ +
+

currentSize

+
+
+ +
+
fun currentSize(): String
+
+

已完成文件大小 根据字节数自动显示内存单位, 例如 19MB 或者 27KB

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/finish.html b/api/-net/com.drake.net.component/-progress/finish.html new file mode 100644 index 000000000..41e75a739 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/finish.html @@ -0,0 +1,38 @@ + + + + finish + + +
+
+ + +
+
+
+
+
+
+ +
+

finish

+
+
+ +
+
var finish: Boolean = false
+
+

是否完成

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/index.html b/api/-net/com.drake.net.component/-progress/index.html new file mode 100644 index 000000000..094a77cdc --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/index.html @@ -0,0 +1,318 @@ + + + + Progress + + +
+
+ + +
+
+
+
+
+
+ +
+

Progress

+
class Progress

下载/上传进度信息

+
+
+
+
+

Constructors

+
+
+
+
Progress +
Link copied to clipboard
+
+
+
+
fun Progress()
+
+
+
+
+
+

Functions

+
+
+
+
currentSize +
Link copied to clipboard
+
+
+
+ +
+
fun currentSize(): String
+
+
已完成文件大小 根据字节数自动显示内存单位, 例如 19MB 或者 27KB
+
+
+
+
+ +
+
+
progress +
Link copied to clipboard
+
+
+
+ +
+
fun progress(): Int
+
+
请求或者响应的进度, 值范围在0-100 如果服务器返回的响应体没有包含Content-Length(比如启用gzip压缩后Content-Length会被删除), 则无法计算进度, 始终返回0
+
+
+
+
+ +
+
+
remainSize +
Link copied to clipboard
+
+
+
+ +
+
fun remainSize(): String
+
+
剩余大小 根据字节数自动显示内存单位, 例如 19MB 或者 27KB
+
+
+
+
+ +
+
+
remainTime +
Link copied to clipboard
+
+
+
+ +
+
fun remainTime(): String
+
+
剩余时间
+
+
+
+
+ +
+
+
remainTimeSeconds +
Link copied to clipboard
+
+
+
+ +
+
fun remainTimeSeconds(): Long
+
+
剩余时间
+
+
+
+
+ +
+
+
speedSize +
Link copied to clipboard
+
+
+
+ +
+
fun speedSize(): String
+
+
每秒下载速度 根据字节数自动显示内存单位, 例如 19MB 或者 27KB
+
+
+
+
+ +
+
+
toString +
Link copied to clipboard
+
+
+
+ +
+
open override fun toString(): String
+
+
+
+
+
+
+ +
+
+
totalSize +
Link copied to clipboard
+
+
+
+ +
+
fun totalSize(): String
+
+
文件全部大小 根据字节数自动显示内存单位, 例如 19MB 或者 27KB
+
+
+
+
+ +
+
+
useTime +
Link copied to clipboard
+
+
+
+ +
+
fun useTime(): String
+
+
已使用时间
+
+
+
+
+ +
+
+
useTimeSeconds +
Link copied to clipboard
+
+
+
+ +
+
fun useTimeSeconds(): Long
+
+
已使用时间
+
+
+
+
+
+

Properties

+
+
+
+
currentByteCount +
Link copied to clipboard
+
+
+
+
var currentByteCount: Long = 0
当前已经完成的字节数
+
+
+
+
+ +
+
+
finish +
Link copied to clipboard
+
+
+
+
var finish: Boolean = false
是否完成
+
+
+
+
+ +
+
+
intervalByteCount +
Link copied to clipboard
+
+
+
+
var intervalByteCount: Long = 0
距离上次进度变化的新增字节数
+
+
+
+
+ +
+
+
intervalTime +
Link copied to clipboard
+
+
+
+
var intervalTime: Long = 0
距离上次进度变化的时间
+
+
+
+
+ +
+
+
speedBytes +
Link copied to clipboard
+
+
+
+
var speedBytes: Long = 0L
每秒下载速度, 字节单位
+
+
+
+
+ +
+
+
startElapsedRealtime +
Link copied to clipboard
+
+
+
+
val startElapsedRealtime: Long
开始下载的时间
+
+
+
+
+ +
+
+
totalByteCount +
Link copied to clipboard
+
+
+
+
var totalByteCount: Long = 0
全部字节数
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/interval-byte-count.html b/api/-net/com.drake.net.component/-progress/interval-byte-count.html new file mode 100644 index 000000000..a5dbe7924 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/interval-byte-count.html @@ -0,0 +1,38 @@ + + + + intervalByteCount + + +
+
+ + +
+
+
+
+
+
+ +
+

intervalByteCount

+
+
+ +
+
var intervalByteCount: Long = 0
+
+

距离上次进度变化的新增字节数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/interval-time.html b/api/-net/com.drake.net.component/-progress/interval-time.html new file mode 100644 index 000000000..1dbb765ac --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/interval-time.html @@ -0,0 +1,38 @@ + + + + intervalTime + + +
+
+ + +
+
+
+
+
+
+ +
+

intervalTime

+
+
+ +
+
var intervalTime: Long = 0
+
+

距离上次进度变化的时间

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/progress.html b/api/-net/com.drake.net.component/-progress/progress.html new file mode 100644 index 000000000..98520fd19 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/progress.html @@ -0,0 +1,38 @@ + + + + progress + + +
+
+ + +
+
+
+
+
+
+ +
+

progress

+
+
+ +
+
fun progress(): Int
+
+

请求或者响应的进度, 值范围在0-100 如果服务器返回的响应体没有包含Content-Length(比如启用gzip压缩后Content-Length会被删除), 则无法计算进度, 始终返回0

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/remain-size.html b/api/-net/com.drake.net.component/-progress/remain-size.html new file mode 100644 index 000000000..602e47d2e --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/remain-size.html @@ -0,0 +1,38 @@ + + + + remainSize + + +
+
+ + +
+
+
+
+
+
+ +
+

remainSize

+
+
+ +
+
fun remainSize(): String
+
+

剩余大小 根据字节数自动显示内存单位, 例如 19MB 或者 27KB

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/remain-time-seconds.html b/api/-net/com.drake.net.component/-progress/remain-time-seconds.html new file mode 100644 index 000000000..8fb3f869a --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/remain-time-seconds.html @@ -0,0 +1,38 @@ + + + + remainTimeSeconds + + +
+
+ + +
+
+
+
+
+
+ +
+

remainTimeSeconds

+
+
+ +
+
fun remainTimeSeconds(): Long
+
+

剩余时间

Return

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/remain-time.html b/api/-net/com.drake.net.component/-progress/remain-time.html new file mode 100644 index 000000000..fe857836c --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/remain-time.html @@ -0,0 +1,38 @@ + + + + remainTime + + +
+
+ + +
+
+
+
+
+
+ +
+

remainTime

+
+
+ +
+
fun remainTime(): String
+
+

剩余时间

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/speed-bytes.html b/api/-net/com.drake.net.component/-progress/speed-bytes.html new file mode 100644 index 000000000..f89337e2c --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/speed-bytes.html @@ -0,0 +1,38 @@ + + + + speedBytes + + +
+
+ + +
+
+
+
+
+
+ +
+

speedBytes

+
+
+ +
+
var speedBytes: Long = 0L
+
+

每秒下载速度, 字节单位

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/speed-size.html b/api/-net/com.drake.net.component/-progress/speed-size.html new file mode 100644 index 000000000..180d3cb9a --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/speed-size.html @@ -0,0 +1,38 @@ + + + + speedSize + + +
+
+ + +
+
+
+
+
+
+ +
+

speedSize

+
+
+ +
+
fun speedSize(): String
+
+

每秒下载速度 根据字节数自动显示内存单位, 例如 19MB 或者 27KB

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/start-elapsed-realtime.html b/api/-net/com.drake.net.component/-progress/start-elapsed-realtime.html new file mode 100644 index 000000000..03932ca32 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/start-elapsed-realtime.html @@ -0,0 +1,38 @@ + + + + startElapsedRealtime + + +
+
+ + +
+
+
+
+
+
+ +
+

startElapsedRealtime

+
+
+ +
+
val startElapsedRealtime: Long
+
+

开始下载的时间

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/to-string.html b/api/-net/com.drake.net.component/-progress/to-string.html new file mode 100644 index 000000000..7c08b9a84 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/to-string.html @@ -0,0 +1,38 @@ + + + + toString + + +
+
+ + +
+
+
+
+
+
+ +
+

toString

+
+
+ +
+
open override fun toString(): String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/total-byte-count.html b/api/-net/com.drake.net.component/-progress/total-byte-count.html new file mode 100644 index 000000000..907694d8c --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/total-byte-count.html @@ -0,0 +1,38 @@ + + + + totalByteCount + + +
+
+ + +
+
+
+
+
+
+ +
+

totalByteCount

+
+
+ +
+
var totalByteCount: Long = 0
+
+

全部字节数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/total-size.html b/api/-net/com.drake.net.component/-progress/total-size.html new file mode 100644 index 000000000..50f7a93a5 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/total-size.html @@ -0,0 +1,38 @@ + + + + totalSize + + +
+
+ + +
+
+
+
+
+
+ +
+

totalSize

+
+
+ +
+
fun totalSize(): String
+
+

文件全部大小 根据字节数自动显示内存单位, 例如 19MB 或者 27KB

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/use-time-seconds.html b/api/-net/com.drake.net.component/-progress/use-time-seconds.html new file mode 100644 index 000000000..d615a1ee0 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/use-time-seconds.html @@ -0,0 +1,38 @@ + + + + useTimeSeconds + + +
+
+ + +
+
+
+
+
+
+ +
+

useTimeSeconds

+
+
+ +
+
fun useTimeSeconds(): Long
+
+

已使用时间

Return

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/-progress/use-time.html b/api/-net/com.drake.net.component/-progress/use-time.html new file mode 100644 index 000000000..e360f0448 --- /dev/null +++ b/api/-net/com.drake.net.component/-progress/use-time.html @@ -0,0 +1,38 @@ + + + + useTime + + +
+
+ + +
+
+
+
+
+
+ +
+

useTime

+
+
+ +
+
fun useTime(): String
+
+

已使用时间

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.component/index.html b/api/-net/com.drake.net.component/index.html new file mode 100644 index 000000000..5c8e6df5a --- /dev/null +++ b/api/-net/com.drake.net.component/index.html @@ -0,0 +1,56 @@ + + + + com.drake.net.component + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.component

+
+
+
+
+

Types

+
+
+
+
Progress +
Link copied to clipboard
+
+
+
+ +
+
class Progress
+
+
下载/上传进度信息
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-j-s-o-n-convert/-j-s-o-n-convert.html b/api/-net/com.drake.net.convert/-j-s-o-n-convert/-j-s-o-n-convert.html new file mode 100644 index 000000000..b5564cf2f --- /dev/null +++ b/api/-net/com.drake.net.convert/-j-s-o-n-convert/-j-s-o-n-convert.html @@ -0,0 +1,38 @@ + + + + JSONConvert + + +
+
+ + +
+
+
+
+
+
+ +
+

JSONConvert

+
+
+ +
+
fun JSONConvert(success: String = "0", code: String = "code", message: String = "msg")
+
+

Parameters

success

后端定义为成功状态的错误码值

code

错误码在JSON中的字段名

message

错误信息在JSON中的字段名

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-j-s-o-n-convert/code.html b/api/-net/com.drake.net.convert/-j-s-o-n-convert/code.html new file mode 100644 index 000000000..f3a2ad39e --- /dev/null +++ b/api/-net/com.drake.net.convert/-j-s-o-n-convert/code.html @@ -0,0 +1,38 @@ + + + + code + + +
+
+ + +
+
+
+
+
+
+ +
+

code

+
+
+ +
+
val code: String
+
+

Parameters

code

错误码在JSON中的字段名

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-j-s-o-n-convert/index.html b/api/-net/com.drake.net.convert/-j-s-o-n-convert/index.html new file mode 100644 index 000000000..a75aca480 --- /dev/null +++ b/api/-net/com.drake.net.convert/-j-s-o-n-convert/index.html @@ -0,0 +1,134 @@ + + + + JSONConvert + + +
+
+ + +
+
+
+
+
+
+ +
+

JSONConvert

+
abstract class JSONConvert(success: String, code: String, message: String) : NetConverter

常见的JSON转换器实现, 如果不满意继承实现自定义的业务逻辑

+
+
+
+
+

Parameters

+
+
success

后端定义为成功状态的错误码值

code

错误码在JSON中的字段名

message

错误信息在JSON中的字段名

+
+

Constructors

+
+
+
+
JSONConvert +
Link copied to clipboard
+
+
+
+
fun JSONConvert(success: String = "0", code: String = "code", message: String = "msg")
后端定义为成功状态的错误码值
+
+
+
+
+
+

Functions

+
+
+
+
onConvert +
Link copied to clipboard
+
+
+
+ +
+
open override fun <R> onConvert(succeed: Type, response: Response): R?
+
+
+
+
+
+
+ +
+
+
parseBody +
Link copied to clipboard
+
+
+
+ +
+
abstract fun <R> String.parseBody(succeed: Type): R?
+
+
反序列化JSON
+
+
+
+
+
+

Properties

+
+
+
+
code +
Link copied to clipboard
+
+
+
+
val code: String
错误码在JSON中的字段名
+
+
+
+
+ +
+
+
message +
Link copied to clipboard
+
+
+
+
val message: String
错误信息在JSON中的字段名
+
+
+
+
+ +
+
+
success +
Link copied to clipboard
+
+
+
+
val success: String
后端定义为成功状态的错误码值
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-j-s-o-n-convert/message.html b/api/-net/com.drake.net.convert/-j-s-o-n-convert/message.html new file mode 100644 index 000000000..5b6847a89 --- /dev/null +++ b/api/-net/com.drake.net.convert/-j-s-o-n-convert/message.html @@ -0,0 +1,38 @@ + + + + message + + +
+
+ + +
+
+
+
+
+
+ +
+

message

+
+
+ +
+
val message: String
+
+

Parameters

message

错误信息在JSON中的字段名

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-j-s-o-n-convert/on-convert.html b/api/-net/com.drake.net.convert/-j-s-o-n-convert/on-convert.html new file mode 100644 index 000000000..ba941ab90 --- /dev/null +++ b/api/-net/com.drake.net.convert/-j-s-o-n-convert/on-convert.html @@ -0,0 +1,38 @@ + + + + onConvert + + +
+
+ + +
+
+
+
+
+
+ +
+

onConvert

+
+
+ +
+
open override fun <R> onConvert(succeed: Type, response: Response): R?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-j-s-o-n-convert/parse-body.html b/api/-net/com.drake.net.convert/-j-s-o-n-convert/parse-body.html new file mode 100644 index 000000000..8a08f86fe --- /dev/null +++ b/api/-net/com.drake.net.convert/-j-s-o-n-convert/parse-body.html @@ -0,0 +1,38 @@ + + + + parseBody + + +
+
+ + +
+
+
+
+
+
+ +
+

parseBody

+
+
+ +
+
abstract fun <R> String.parseBody(succeed: Type): R?
+
+

反序列化JSON

Parameters

<receiver>

原始字符串

succeed

JSON对象的类型

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-j-s-o-n-convert/success.html b/api/-net/com.drake.net.convert/-j-s-o-n-convert/success.html new file mode 100644 index 000000000..e03815b06 --- /dev/null +++ b/api/-net/com.drake.net.convert/-j-s-o-n-convert/success.html @@ -0,0 +1,38 @@ + + + + success + + +
+
+ + +
+
+
+
+
+
+ +
+

success

+
+
+ +
+
val success: String
+
+

Parameters

success

后端定义为成功状态的错误码值

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/index.html b/api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/index.html new file mode 100644 index 000000000..674b73c14 --- /dev/null +++ b/api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/index.html @@ -0,0 +1,57 @@ + + + + DEFAULT + + +
+
+ + +
+
+
+
+
+
+ +
+

DEFAULT

+
object DEFAULT : NetConverter
+
+
+
+
+

Functions

+
+
+
+
onConvert +
Link copied to clipboard
+
+
+
+ +
+
open override fun <R> onConvert(succeed: Type, response: Response): R?
+
+
返回结果应当等于泛型对象, 可空
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/on-convert.html b/api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/on-convert.html new file mode 100644 index 000000000..7323d54db --- /dev/null +++ b/api/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/on-convert.html @@ -0,0 +1,38 @@ + + + + onConvert + + +
+
+ + +
+
+
+
+
+
+ +
+

onConvert

+
+
+ +
+
open override fun <R> onConvert(succeed: Type, response: Response): R?
+
+

返回结果应当等于泛型对象, 可空

Parameters

succeed

请求要求返回的泛型类型

response

请求响应对象

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-net-converter/index.html b/api/-net/com.drake.net.convert/-net-converter/index.html new file mode 100644 index 000000000..4c7a60c0a --- /dev/null +++ b/api/-net/com.drake.net.convert/-net-converter/index.html @@ -0,0 +1,96 @@ + + + + NetConverter + + +
+
+ + +
+
+
+
+
+
+ +
+

NetConverter

+
interface NetConverter
+
+
+
+
+

Types

+
+
+
+
DEFAULT +
Link copied to clipboard
+
+
+
+ +
+
object DEFAULT : NetConverter
+
+
+
+
+
+
+
+

Functions

+
+
+
+
onConvert +
Link copied to clipboard
+
+
+
+ +
+
abstract fun <R> onConvert(succeed: Type, response: Response): R?
+
+
+
+
+
+
+
+

Inheritors

+
+
+
+
JSONConvert +
Link copied to clipboard
+
+
+
+
+ +
+
+
NetConverter +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/-net-converter/on-convert.html b/api/-net/com.drake.net.convert/-net-converter/on-convert.html new file mode 100644 index 000000000..75aa80377 --- /dev/null +++ b/api/-net/com.drake.net.convert/-net-converter/on-convert.html @@ -0,0 +1,38 @@ + + + + onConvert + + +
+
+ + +
+
+
+
+
+
+ +
+

onConvert

+
+
+ +
+
abstract fun <R> onConvert(succeed: Type, response: Response): R?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.convert/index.html b/api/-net/com.drake.net.convert/index.html new file mode 100644 index 000000000..0744794bb --- /dev/null +++ b/api/-net/com.drake.net.convert/index.html @@ -0,0 +1,73 @@ + + + + com.drake.net.convert + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.convert

+
+
+
+
+

Types

+
+
+
+
JSONConvert +
Link copied to clipboard
+
+
+
+ +
+
abstract class JSONConvert(success: String, code: String, message: String) : NetConverter
+
+
常见的JSON转换器实现, 如果不满意继承实现自定义的业务逻辑
+
+
+
+
+ +
+
+
NetConverter +
Link copied to clipboard
+
+
+
+ +
+
interface NetConverter
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/-persistent-cookie-jar.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/-persistent-cookie-jar.html new file mode 100644 index 000000000..1bad23dd7 --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/-persistent-cookie-jar.html @@ -0,0 +1,38 @@ + + + + PersistentCookieJar + + +
+
+ + +
+
+
+
+
+
+ +
+

PersistentCookieJar

+
+
+ +
+
fun PersistentCookieJar(context: Context, dbName: String = "net_cookies")
+
+

Parameters

dbName

数据库名称, 设置多个名称可以让不同的客户端共享不同的cookies

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/add-all.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/add-all.html new file mode 100644 index 000000000..1a4273d0e --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/add-all.html @@ -0,0 +1,38 @@ + + + + addAll + + +
+
+ + +
+
+
+
+
+
+ +
+

addAll

+
+
+ +
+
fun addAll(url: HttpUrl, cookies: List<Cookie>)
+
+

添加Cookie到指定域名下

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/clear.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/clear.html new file mode 100644 index 000000000..c896e8b7c --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/clear.html @@ -0,0 +1,38 @@ + + + + clear + + +
+
+ + +
+
+
+
+
+
+ +
+

clear

+
+
+ +
+
fun clear()
+
+

清除应用所有Cookie

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/context.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/context.html new file mode 100644 index 000000000..c6c4b16ac --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/context.html @@ -0,0 +1,38 @@ + + + + context + + +
+
+ + +
+
+
+
+
+
+ +
+

context

+
+
+ +
+
val context: Context
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/db-name.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/db-name.html new file mode 100644 index 000000000..e4b6a48ee --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/db-name.html @@ -0,0 +1,38 @@ + + + + dbName + + +
+
+ + +
+
+
+
+
+
+ +
+

dbName

+
+
+ +
+
val dbName: String
+
+

Parameters

dbName

数据库名称, 设置多个名称可以让不同的客户端共享不同的cookies

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/get-all.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/get-all.html new file mode 100644 index 000000000..c1c56b135 --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/get-all.html @@ -0,0 +1,38 @@ + + + + getAll + + +
+
+ + +
+
+
+
+
+
+ +
+

getAll

+
+
+ +
+
fun getAll(url: HttpUrl): List<Cookie>
+
+

获取指定域名下的所有Cookie

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/index.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/index.html new file mode 100644 index 000000000..5748e98c6 --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/index.html @@ -0,0 +1,195 @@ + + + + PersistentCookieJar + + +
+
+ + +
+
+
+
+
+
+ +
+

PersistentCookieJar

+
class PersistentCookieJar(context: Context, dbName: String) : CookieJar

持久化存储Cookie

+
+
+
+
+

Parameters

+
+
dbName

数据库名称, 设置多个名称可以让不同的客户端共享不同的cookies

+
+

Constructors

+
+
+
+
PersistentCookieJar +
Link copied to clipboard
+
+
+
+
fun PersistentCookieJar(context: Context, dbName: String = "net_cookies")
数据库名称, 设置多个名称可以让不同的客户端共享不同的cookies
+
+
+
+
+
+

Functions

+
+
+
+
addAll +
Link copied to clipboard
+
+
+
+ +
+
fun addAll(url: HttpUrl, cookies: List<Cookie>)
+
+
添加Cookie到指定域名下
+
+
+
+
+ +
+
+
clear +
Link copied to clipboard
+
+
+
+ +
+
fun clear()
+
+
清除应用所有Cookie
+
+
+
+
+ +
+
+
getAll +
Link copied to clipboard
+
+
+
+ +
+
fun getAll(url: HttpUrl): List<Cookie>
+
+
获取指定域名下的所有Cookie
+
+
+
+
+ +
+
+
loadForRequest +
Link copied to clipboard
+
+
+
+ +
+
open override fun loadForRequest(url: HttpUrl): List<Cookie>
+
+
+
+
+
+
+ +
+
+
remove +
Link copied to clipboard
+
+
+
+ +
+
fun remove(url: HttpUrl)
+
+
删除指定域名的所有Cookie
+
+ +
+
fun remove(url: HttpUrl, cookieName: String)
+
+
删除指定域名下的指定cookie
+
+
+
+
+ +
+
+
saveFromResponse +
Link copied to clipboard
+
+
+
+ +
+
open override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
context +
Link copied to clipboard
+
+
+
+
val context: Context
+
+
+
+
+ +
+
+
dbName +
Link copied to clipboard
+
+
+
+
val dbName: String
数据库名称, 设置多个名称可以让不同的客户端共享不同的cookies
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/load-for-request.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/load-for-request.html new file mode 100644 index 000000000..dae65095c --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/load-for-request.html @@ -0,0 +1,38 @@ + + + + loadForRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

loadForRequest

+
+
+ +
+
open override fun loadForRequest(url: HttpUrl): List<Cookie>
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/remove.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/remove.html new file mode 100644 index 000000000..bebcc7d15 --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/remove.html @@ -0,0 +1,44 @@ + + + + remove + + +
+
+ + +
+
+
+
+
+
+ +
+

remove

+
+
+ +
+
fun remove(url: HttpUrl)
+
+

删除指定域名的所有Cookie

+
+ +
+
fun remove(url: HttpUrl, cookieName: String)
+
+

删除指定域名下的指定cookie

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/-persistent-cookie-jar/save-from-response.html b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/save-from-response.html new file mode 100644 index 000000000..085d3d81d --- /dev/null +++ b/api/-net/com.drake.net.cookie/-persistent-cookie-jar/save-from-response.html @@ -0,0 +1,38 @@ + + + + saveFromResponse + + +
+
+ + +
+
+
+
+
+
+ +
+

saveFromResponse

+
+
+ +
+
open override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.cookie/index.html b/api/-net/com.drake.net.cookie/index.html new file mode 100644 index 000000000..04d372f58 --- /dev/null +++ b/api/-net/com.drake.net.cookie/index.html @@ -0,0 +1,56 @@ + + + + com.drake.net.cookie + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.cookie

+
+
+
+
+

Types

+
+
+
+
PersistentCookieJar +
Link copied to clipboard
+
+
+
+ +
+
class PersistentCookieJar(context: Context, dbName: String) : CookieJar
+
+
持久化存储Cookie
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-convert-exception/-convert-exception.html b/api/-net/com.drake.net.exception/-convert-exception/-convert-exception.html new file mode 100644 index 000000000..2995902c9 --- /dev/null +++ b/api/-net/com.drake.net.exception/-convert-exception/-convert-exception.html @@ -0,0 +1,38 @@ + + + + ConvertException + + +
+
+ + +
+
+
+
+
+
+ +
+

ConvertException

+
+
+ +
+
fun ConvertException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
+
+

Parameters

response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-convert-exception/index.html b/api/-net/com.drake.net.exception/-convert-exception/index.html new file mode 100644 index 000000000..9ca58d853 --- /dev/null +++ b/api/-net/com.drake.net.exception/-convert-exception/index.html @@ -0,0 +1,72 @@ + + + + ConvertException + + +
+
+ + +
+
+
+
+
+
+ +
+

ConvertException

+
class ConvertException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException

转换数据异常

+
+
+
+
+

Parameters

+
+
response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+

Constructors

+
+
+
+
ConvertException +
Link copied to clipboard
+
+
+
+
fun ConvertException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
响应信息
+
+
+
+
+
+

Properties

+
+
+
+
tag +
Link copied to clipboard
+
+
+
+
var tag: Any? = null
可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-convert-exception/tag.html b/api/-net/com.drake.net.exception/-convert-exception/tag.html new file mode 100644 index 000000000..435cb7b5b --- /dev/null +++ b/api/-net/com.drake.net.exception/-convert-exception/tag.html @@ -0,0 +1,38 @@ + + + + tag + + +
+
+ + +
+
+
+
+
+
+ +
+

tag

+
+
+ +
+
var tag: Any? = null
+
+

Parameters

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-download-file-exception/-download-file-exception.html b/api/-net/com.drake.net.exception/-download-file-exception/-download-file-exception.html new file mode 100644 index 000000000..f6e62900c --- /dev/null +++ b/api/-net/com.drake.net.exception/-download-file-exception/-download-file-exception.html @@ -0,0 +1,38 @@ + + + + DownloadFileException + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileException

+
+
+ +
+
fun DownloadFileException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
+
+

Parameters

response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-download-file-exception/index.html b/api/-net/com.drake.net.exception/-download-file-exception/index.html new file mode 100644 index 000000000..8070d3238 --- /dev/null +++ b/api/-net/com.drake.net.exception/-download-file-exception/index.html @@ -0,0 +1,72 @@ + + + + DownloadFileException + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileException

+
class DownloadFileException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException

下载文件异常

+
+
+
+
+

Parameters

+
+
response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+

Constructors

+
+
+
+
DownloadFileException +
Link copied to clipboard
+
+
+
+
fun DownloadFileException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
响应信息
+
+
+
+
+
+

Properties

+
+
+
+
tag +
Link copied to clipboard
+
+
+
+
var tag: Any? = null
可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-download-file-exception/tag.html b/api/-net/com.drake.net.exception/-download-file-exception/tag.html new file mode 100644 index 000000000..006fdc258 --- /dev/null +++ b/api/-net/com.drake.net.exception/-download-file-exception/tag.html @@ -0,0 +1,38 @@ + + + + tag + + +
+
+ + +
+
+
+
+
+
+ +
+

tag

+
+
+ +
+
var tag: Any? = null
+
+

Parameters

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-http-failure-exception/-http-failure-exception.html b/api/-net/com.drake.net.exception/-http-failure-exception/-http-failure-exception.html new file mode 100644 index 000000000..96801a0b9 --- /dev/null +++ b/api/-net/com.drake.net.exception/-http-failure-exception/-http-failure-exception.html @@ -0,0 +1,38 @@ + + + + HttpFailureException + + +
+
+ + +
+
+
+
+
+
+ +
+

HttpFailureException

+
+
+ +
+
fun HttpFailureException(request: Request, message: String? = null, cause: Throwable? = null)
+
+

Parameters

request

请求信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-http-failure-exception/index.html b/api/-net/com.drake.net.exception/-http-failure-exception/index.html new file mode 100644 index 000000000..c1b0a89a4 --- /dev/null +++ b/api/-net/com.drake.net.exception/-http-failure-exception/index.html @@ -0,0 +1,95 @@ + + + + HttpFailureException + + +
+
+ + +
+
+
+
+
+
+ +
+

HttpFailureException

+
open class HttpFailureException(request: Request, message: String?, cause: Throwable?) : NetException

该类表示Http请求在服务器响应之前失败

+
+
+
+
+

Parameters

+
+
request

请求信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
HttpFailureException +
Link copied to clipboard
+
+
+
+
fun HttpFailureException(request: Request, message: String? = null, cause: Throwable? = null)
请求信息
+
+
+
+
+
+

Inheritors

+
+
+
+
NetConnectException +
Link copied to clipboard
+
+
+
+
+ +
+
+
NetSocketTimeoutException +
Link copied to clipboard
+
+
+
+
+ +
+
+
NetUnknownHostException +
Link copied to clipboard
+
+
+
+
+ +
+
+
NetworkingException +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-http-response-exception/-http-response-exception.html b/api/-net/com.drake.net.exception/-http-response-exception/-http-response-exception.html new file mode 100644 index 000000000..835936cc5 --- /dev/null +++ b/api/-net/com.drake.net.exception/-http-response-exception/-http-response-exception.html @@ -0,0 +1,38 @@ + + + + HttpResponseException + + +
+
+ + +
+
+
+
+
+
+ +
+

HttpResponseException

+
+
+ +
+
fun HttpResponseException(response: Response, message: String? = null, cause: Throwable? = null)
+
+

Parameters

response

响应信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-http-response-exception/index.html b/api/-net/com.drake.net.exception/-http-response-exception/index.html new file mode 100644 index 000000000..6ee732754 --- /dev/null +++ b/api/-net/com.drake.net.exception/-http-response-exception/index.html @@ -0,0 +1,123 @@ + + + + HttpResponseException + + +
+
+ + +
+
+
+
+
+
+ +
+

HttpResponseException

+
open class HttpResponseException(response: Response, message: String?, cause: Throwable?) : NetException

该类表示Http请求在服务器响应成功后失败

+
+
+
+
+

See also

+ +

Parameters

+
+
response

响应信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
HttpResponseException +
Link copied to clipboard
+
+
+
+
fun HttpResponseException(response: Response, message: String? = null, cause: Throwable? = null)
响应信息
+
+
+
+
+
+

Properties

+
+
+
+
response +
Link copied to clipboard
+
+
+
+
open val response: Response
响应信息
+
+
+
+
+
+

Inheritors

+
+
+
+
ConvertException +
Link copied to clipboard
+
+
+
+
+ +
+
+
DownloadFileException +
Link copied to clipboard
+
+
+
+
+ +
+
+
RequestParamsException +
Link copied to clipboard
+
+
+
+
+ +
+
+
ResponseException +
Link copied to clipboard
+
+
+
+
+ +
+
+
ServerResponseException +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-http-response-exception/response.html b/api/-net/com.drake.net.exception/-http-response-exception/response.html new file mode 100644 index 000000000..35507972a --- /dev/null +++ b/api/-net/com.drake.net.exception/-http-response-exception/response.html @@ -0,0 +1,38 @@ + + + + response + + +
+
+ + +
+
+
+
+
+
+ +
+

response

+
+
+ +
+
open val response: Response
+
+

Parameters

response

响应信息

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-cancellation-exception.html b/api/-net/com.drake.net.exception/-net-cancellation-exception.html new file mode 100644 index 000000000..7ad9fe1c1 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-cancellation-exception.html @@ -0,0 +1,38 @@ + + + + NetCancellationException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetCancellationException

+
+
+ +
+
fun CoroutineScope.NetCancellationException(message: String? = null): NetCancellationException
+
+

在作用域中抛出该异常将取消其作用域内所有的网络请求(如果存在的话)

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-cancellation-exception/-net-cancellation-exception.html b/api/-net/com.drake.net.exception/-net-cancellation-exception/-net-cancellation-exception.html new file mode 100644 index 000000000..41f0f3bf4 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-cancellation-exception/-net-cancellation-exception.html @@ -0,0 +1,38 @@ + + + + NetCancellationException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetCancellationException

+
+
+ +
+
fun NetCancellationException(coroutineScope: CoroutineScope, message: String? = null)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-cancellation-exception/index.html b/api/-net/com.drake.net.exception/-net-cancellation-exception/index.html new file mode 100644 index 000000000..11c7df330 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-cancellation-exception/index.html @@ -0,0 +1,53 @@ + + + + NetCancellationException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetCancellationException

+
class NetCancellationException(coroutineScope: CoroutineScope, message: String?) : CancellationException

取消网络任务的异常

+
+
+
+
+

Constructors

+
+
+
+
NetCancellationException +
Link copied to clipboard
+
+
+
+
fun NetCancellationException(coroutineScope: CoroutineScope, message: String? = null)
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-connect-exception/-net-connect-exception.html b/api/-net/com.drake.net.exception/-net-connect-exception/-net-connect-exception.html new file mode 100644 index 000000000..9d1de9092 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-connect-exception/-net-connect-exception.html @@ -0,0 +1,38 @@ + + + + NetConnectException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetConnectException

+
+
+ +
+
fun NetConnectException(request: Request, message: String? = null, cause: Throwable? = null)
+
+

Parameters

request

请求信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-connect-exception/index.html b/api/-net/com.drake.net.exception/-net-connect-exception/index.html new file mode 100644 index 000000000..f3d261d94 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-connect-exception/index.html @@ -0,0 +1,57 @@ + + + + NetConnectException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetConnectException

+
class NetConnectException(request: Request, message: String?, cause: Throwable?) : HttpFailureException

连接错误

+
+
+
+
+

Parameters

+
+
request

请求信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
NetConnectException +
Link copied to clipboard
+
+
+
+
fun NetConnectException(request: Request, message: String? = null, cause: Throwable? = null)
请求信息
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-exception/-net-exception.html b/api/-net/com.drake.net.exception/-net-exception/-net-exception.html new file mode 100644 index 000000000..57adbcdfa --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-exception/-net-exception.html @@ -0,0 +1,38 @@ + + + + NetException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetException

+
+
+ +
+
fun NetException(request: Request, message: String? = null, cause: Throwable? = null)
+
+

Parameters

request

请求信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-exception/get-localized-message.html b/api/-net/com.drake.net.exception/-net-exception/get-localized-message.html new file mode 100644 index 000000000..444556719 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-exception/get-localized-message.html @@ -0,0 +1,38 @@ + + + + getLocalizedMessage + + +
+
+ + +
+
+
+
+
+
+ +
+

getLocalizedMessage

+
+
+ +
+
open override fun getLocalizedMessage(): String?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-exception/index.html b/api/-net/com.drake.net.exception/-net-exception/index.html new file mode 100644 index 000000000..b4d28cd84 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-exception/index.html @@ -0,0 +1,133 @@ + + + + NetException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetException

+
open class NetException(request: Request, message: String?, cause: Throwable?) : IOException

表示为Net发生的网络异常 在转换器com.drake.net.convert.NetConverter中抛出的异常如果没有继承该类都会被视为数据转换异常ConvertException, 该类一般用于自定义异常

+
+
+
+
+

Parameters

+
+
request

请求信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
NetException +
Link copied to clipboard
+
+
+
+
fun NetException(request: Request, message: String? = null, cause: Throwable? = null)
请求信息
+
+
+
+
+
+

Functions

+
+
+
+
getLocalizedMessage +
Link copied to clipboard
+
+
+
+ +
+
open override fun getLocalizedMessage(): String?
+
+
+
+
+
+
+
+

Properties

+
+
+
+
occurred +
Link copied to clipboard
+
+
+
+
var occurred: String
+
+
+
+
+ +
+
+
request +
Link copied to clipboard
+
+
+
+
open val request: Request
请求信息
+
+
+
+
+
+

Inheritors

+
+
+
+
HttpFailureException +
Link copied to clipboard
+
+
+
+
+ +
+
+
HttpResponseException +
Link copied to clipboard
+
+
+
+
+ +
+
+
NoCacheException +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-exception/occurred.html b/api/-net/com.drake.net.exception/-net-exception/occurred.html new file mode 100644 index 000000000..1b3523db5 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-exception/occurred.html @@ -0,0 +1,38 @@ + + + + occurred + + +
+
+ + +
+
+
+
+
+
+ +
+

occurred

+
+
+ +
+
var occurred: String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-exception/request.html b/api/-net/com.drake.net.exception/-net-exception/request.html new file mode 100644 index 000000000..660116a95 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-exception/request.html @@ -0,0 +1,38 @@ + + + + request + + +
+
+ + +
+
+
+
+
+
+ +
+

request

+
+
+ +
+
open val request: Request
+
+

Parameters

request

请求信息

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-socket-timeout-exception/-net-socket-timeout-exception.html b/api/-net/com.drake.net.exception/-net-socket-timeout-exception/-net-socket-timeout-exception.html new file mode 100644 index 000000000..c1753e858 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-socket-timeout-exception/-net-socket-timeout-exception.html @@ -0,0 +1,38 @@ + + + + NetSocketTimeoutException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetSocketTimeoutException

+
+
+ +
+
fun NetSocketTimeoutException(request: Request, message: String? = null, cause: Throwable? = null)
+
+

Parameters

request

请求信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-socket-timeout-exception/index.html b/api/-net/com.drake.net.exception/-net-socket-timeout-exception/index.html new file mode 100644 index 000000000..36e838054 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-socket-timeout-exception/index.html @@ -0,0 +1,57 @@ + + + + NetSocketTimeoutException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetSocketTimeoutException

+
class NetSocketTimeoutException(request: Request, message: String?, cause: Throwable?) : HttpFailureException

请求过程中读取或者写入超时

+
+
+
+
+

Parameters

+
+
request

请求信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
NetSocketTimeoutException +
Link copied to clipboard
+
+
+
+
fun NetSocketTimeoutException(request: Request, message: String? = null, cause: Throwable? = null)
请求信息
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-unknown-host-exception/-net-unknown-host-exception.html b/api/-net/com.drake.net.exception/-net-unknown-host-exception/-net-unknown-host-exception.html new file mode 100644 index 000000000..0e5c95b24 --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-unknown-host-exception/-net-unknown-host-exception.html @@ -0,0 +1,38 @@ + + + + NetUnknownHostException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetUnknownHostException

+
+
+ +
+
fun NetUnknownHostException(request: Request, message: String? = null, cause: Throwable? = null)
+
+

Parameters

request

请求信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-net-unknown-host-exception/index.html b/api/-net/com.drake.net.exception/-net-unknown-host-exception/index.html new file mode 100644 index 000000000..b1a85dd3a --- /dev/null +++ b/api/-net/com.drake.net.exception/-net-unknown-host-exception/index.html @@ -0,0 +1,57 @@ + + + + NetUnknownHostException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetUnknownHostException

+
class NetUnknownHostException(request: Request, message: String?, cause: Throwable?) : HttpFailureException

主机域名无法访问

+
+
+
+
+

Parameters

+
+
request

请求信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
NetUnknownHostException +
Link copied to clipboard
+
+
+
+
fun NetUnknownHostException(request: Request, message: String? = null, cause: Throwable? = null)
请求信息
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-networking-exception/-networking-exception.html b/api/-net/com.drake.net.exception/-networking-exception/-networking-exception.html new file mode 100644 index 000000000..01f7f551b --- /dev/null +++ b/api/-net/com.drake.net.exception/-networking-exception/-networking-exception.html @@ -0,0 +1,38 @@ + + + + NetworkingException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetworkingException

+
+
+ +
+
fun NetworkingException(request: Request, message: String? = null, cause: Throwable? = null)
+
+

Parameters

request

请求信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-networking-exception/index.html b/api/-net/com.drake.net.exception/-networking-exception/index.html new file mode 100644 index 000000000..eceaa7a9b --- /dev/null +++ b/api/-net/com.drake.net.exception/-networking-exception/index.html @@ -0,0 +1,57 @@ + + + + NetworkingException + + +
+
+ + +
+
+
+
+
+
+ +
+

NetworkingException

+
class NetworkingException(request: Request, message: String?, cause: Throwable?) : HttpFailureException

无网络情况

+
+
+
+
+

Parameters

+
+
request

请求信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
NetworkingException +
Link copied to clipboard
+
+
+
+
fun NetworkingException(request: Request, message: String? = null, cause: Throwable? = null)
请求信息
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-no-cache-exception/-no-cache-exception.html b/api/-net/com.drake.net.exception/-no-cache-exception/-no-cache-exception.html new file mode 100644 index 000000000..687bb1ee6 --- /dev/null +++ b/api/-net/com.drake.net.exception/-no-cache-exception/-no-cache-exception.html @@ -0,0 +1,38 @@ + + + + NoCacheException + + +
+
+ + +
+
+
+
+
+
+ +
+

NoCacheException

+
+
+ +
+
fun NoCacheException(request: Request, message: String? = null, cause: Throwable? = null)
+
+

Parameters

request

请求信息

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-no-cache-exception/get-localized-message.html b/api/-net/com.drake.net.exception/-no-cache-exception/get-localized-message.html new file mode 100644 index 000000000..abb94ef5d --- /dev/null +++ b/api/-net/com.drake.net.exception/-no-cache-exception/get-localized-message.html @@ -0,0 +1,38 @@ + + + + getLocalizedMessage + + +
+
+ + +
+
+
+
+
+
+ +
+

getLocalizedMessage

+
+
+ +
+
open override fun getLocalizedMessage(): String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-no-cache-exception/index.html b/api/-net/com.drake.net.exception/-no-cache-exception/index.html new file mode 100644 index 000000000..f522cddd5 --- /dev/null +++ b/api/-net/com.drake.net.exception/-no-cache-exception/index.html @@ -0,0 +1,76 @@ + + + + NoCacheException + + +
+
+ + +
+
+
+
+
+
+ +
+

NoCacheException

+
class NoCacheException(request: Request, message: String?, cause: Throwable?) : NetException

读取缓存失败 仅当设置强制缓存模式com.drake.net.cache.CacheMode.READcom.drake.net.cache.CacheMode.REQUEST_THEN_READ才会发生此异常

+
+
+
+
+

Parameters

+
+
request

请求信息

message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
NoCacheException +
Link copied to clipboard
+
+
+
+
fun NoCacheException(request: Request, message: String? = null, cause: Throwable? = null)
请求信息
+
+
+
+
+
+

Functions

+
+
+
+
getLocalizedMessage +
Link copied to clipboard
+
+
+
+ +
+
open override fun getLocalizedMessage(): String
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-request-params-exception/-request-params-exception.html b/api/-net/com.drake.net.exception/-request-params-exception/-request-params-exception.html new file mode 100644 index 000000000..493ec139e --- /dev/null +++ b/api/-net/com.drake.net.exception/-request-params-exception/-request-params-exception.html @@ -0,0 +1,38 @@ + + + + RequestParamsException + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestParamsException

+
+
+ +
+
fun RequestParamsException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
+
+

Parameters

response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-request-params-exception/index.html b/api/-net/com.drake.net.exception/-request-params-exception/index.html new file mode 100644 index 000000000..88be7458e --- /dev/null +++ b/api/-net/com.drake.net.exception/-request-params-exception/index.html @@ -0,0 +1,72 @@ + + + + RequestParamsException + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestParamsException

+
class RequestParamsException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException

400 - 499 客户端请求异常

+
+
+
+
+

Parameters

+
+
response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+

Constructors

+
+
+
+
RequestParamsException +
Link copied to clipboard
+
+
+
+
fun RequestParamsException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
响应信息
+
+
+
+
+
+

Properties

+
+
+
+
tag +
Link copied to clipboard
+
+
+
+
var tag: Any? = null
可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-request-params-exception/tag.html b/api/-net/com.drake.net.exception/-request-params-exception/tag.html new file mode 100644 index 000000000..98a862362 --- /dev/null +++ b/api/-net/com.drake.net.exception/-request-params-exception/tag.html @@ -0,0 +1,38 @@ + + + + tag + + +
+
+ + +
+
+
+
+
+
+ +
+

tag

+
+
+ +
+
var tag: Any? = null
+
+

Parameters

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-response-exception/-response-exception.html b/api/-net/com.drake.net.exception/-response-exception/-response-exception.html new file mode 100644 index 000000000..74a72d918 --- /dev/null +++ b/api/-net/com.drake.net.exception/-response-exception/-response-exception.html @@ -0,0 +1,38 @@ + + + + ResponseException + + +
+
+ + +
+
+
+
+
+
+ +
+

ResponseException

+
+
+ +
+
fun ResponseException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
+
+

Parameters

response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-response-exception/index.html b/api/-net/com.drake.net.exception/-response-exception/index.html new file mode 100644 index 000000000..be8a8cc55 --- /dev/null +++ b/api/-net/com.drake.net.exception/-response-exception/index.html @@ -0,0 +1,72 @@ + + + + ResponseException + + +
+
+ + +
+
+
+
+
+
+ +
+

ResponseException

+
class ResponseException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException

状态码在200..299, 但是返回数据不符合业务要求可以抛出该异常

+
+
+
+
+

Parameters

+
+
response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+

Constructors

+
+
+
+
ResponseException +
Link copied to clipboard
+
+
+
+
fun ResponseException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
响应信息
+
+
+
+
+
+

Properties

+
+
+
+
tag +
Link copied to clipboard
+
+
+
+
var tag: Any? = null
可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-response-exception/tag.html b/api/-net/com.drake.net.exception/-response-exception/tag.html new file mode 100644 index 000000000..900438d4d --- /dev/null +++ b/api/-net/com.drake.net.exception/-response-exception/tag.html @@ -0,0 +1,38 @@ + + + + tag + + +
+
+ + +
+
+
+
+
+
+ +
+

tag

+
+
+ +
+
var tag: Any? = null
+
+

Parameters

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-server-response-exception/-server-response-exception.html b/api/-net/com.drake.net.exception/-server-response-exception/-server-response-exception.html new file mode 100644 index 000000000..1362e3637 --- /dev/null +++ b/api/-net/com.drake.net.exception/-server-response-exception/-server-response-exception.html @@ -0,0 +1,38 @@ + + + + ServerResponseException + + +
+
+ + +
+
+
+
+
+
+ +
+

ServerResponseException

+
+
+ +
+
fun ServerResponseException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
+
+

Parameters

response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-server-response-exception/index.html b/api/-net/com.drake.net.exception/-server-response-exception/index.html new file mode 100644 index 000000000..f818383cc --- /dev/null +++ b/api/-net/com.drake.net.exception/-server-response-exception/index.html @@ -0,0 +1,72 @@ + + + + ServerResponseException + + +
+
+ + +
+
+
+
+
+
+ +
+

ServerResponseException

+
class ServerResponseException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException

= 500 服务器异常

+
+
+
+
+

Parameters

+
+
response

响应信息

message

错误描述信息

cause

错误原因

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+

Constructors

+
+
+
+
ServerResponseException +
Link copied to clipboard
+
+
+
+
fun ServerResponseException(response: Response, message: String? = null, cause: Throwable? = null, tag: Any? = null)
响应信息
+
+
+
+
+
+

Properties

+
+
+
+
tag +
Link copied to clipboard
+
+
+
+
var tag: Any? = null
可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-server-response-exception/tag.html b/api/-net/com.drake.net.exception/-server-response-exception/tag.html new file mode 100644 index 000000000..285665aa7 --- /dev/null +++ b/api/-net/com.drake.net.exception/-server-response-exception/tag.html @@ -0,0 +1,38 @@ + + + + tag + + +
+
+ + +
+
+
+
+
+
+ +
+

tag

+
+
+ +
+
var tag: Any? = null
+
+

Parameters

tag

可携带任意对象, 一般用于在转换器/拦截器中添加然后传递给错误处理器去使用判断

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-u-r-l-parse-exception/-u-r-l-parse-exception.html b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/-u-r-l-parse-exception.html new file mode 100644 index 000000000..1e54a9fec --- /dev/null +++ b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/-u-r-l-parse-exception.html @@ -0,0 +1,38 @@ + + + + URLParseException + + +
+
+ + +
+
+
+
+
+
+ +
+

URLParseException

+
+
+ +
+
fun URLParseException(message: String? = null, cause: Throwable? = null)
+
+

Parameters

message

错误描述信息

cause

错误原因

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-u-r-l-parse-exception/get-localized-message.html b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/get-localized-message.html new file mode 100644 index 000000000..1b1885d4d --- /dev/null +++ b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/get-localized-message.html @@ -0,0 +1,38 @@ + + + + getLocalizedMessage + + +
+
+ + +
+
+
+
+
+
+ +
+

getLocalizedMessage

+
+
+ +
+
open override fun getLocalizedMessage(): String?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-u-r-l-parse-exception/index.html b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/index.html new file mode 100644 index 000000000..4fec54afd --- /dev/null +++ b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/index.html @@ -0,0 +1,91 @@ + + + + URLParseException + + +
+
+ + +
+
+
+
+
+
+ +
+

URLParseException

+
open class URLParseException(message: String?, cause: Throwable?) : Exception

URL地址错误

+
+
+
+
+

Parameters

+
+
message

错误描述信息

cause

错误原因

+
+

Constructors

+
+
+
+
URLParseException +
Link copied to clipboard
+
+
+
+
fun URLParseException(message: String? = null, cause: Throwable? = null)
错误描述信息
+
+
+
+
+
+

Functions

+
+
+
+
getLocalizedMessage +
Link copied to clipboard
+
+
+
+ +
+
open override fun getLocalizedMessage(): String?
+
+
+
+
+
+
+
+

Properties

+
+
+
+
occurred +
Link copied to clipboard
+
+
+
+
var occurred: String
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/-u-r-l-parse-exception/occurred.html b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/occurred.html new file mode 100644 index 000000000..0741e3d00 --- /dev/null +++ b/api/-net/com.drake.net.exception/-u-r-l-parse-exception/occurred.html @@ -0,0 +1,38 @@ + + + + occurred + + +
+
+ + +
+
+
+
+
+
+ +
+

occurred

+
+
+ +
+
var occurred: String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.exception/index.html b/api/-net/com.drake.net.exception/index.html new file mode 100644 index 000000000..c2e9faaaa --- /dev/null +++ b/api/-net/com.drake.net.exception/index.html @@ -0,0 +1,313 @@ + + + + com.drake.net.exception + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.exception

+
+
+
+
+

Types

+
+
+
+
ConvertException +
Link copied to clipboard
+
+
+
+ +
+
class ConvertException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException
+
+
转换数据异常
+
+
+
+
+ +
+
+
DownloadFileException +
Link copied to clipboard
+
+
+
+ +
+
class DownloadFileException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException
+
+
下载文件异常
+
+
+
+
+ +
+
+
HttpFailureException +
Link copied to clipboard
+
+
+
+ +
+
open class HttpFailureException(request: Request, message: String?, cause: Throwable?) : NetException
+
+
该类表示Http请求在服务器响应之前失败
+
+
+
+
+ +
+
+
HttpResponseException +
Link copied to clipboard
+
+
+
+ +
+
open class HttpResponseException(response: Response, message: String?, cause: Throwable?) : NetException
+
+
该类表示Http请求在服务器响应成功后失败
+
+
+
+
+ +
+
+
NetCancellationException +
Link copied to clipboard
+
+
+
+ +
+
class NetCancellationException(coroutineScope: CoroutineScope, message: String?) : CancellationException
+
+
取消网络任务的异常
+
+
+
+
+ +
+
+
NetConnectException +
Link copied to clipboard
+
+
+
+ +
+
class NetConnectException(request: Request, message: String?, cause: Throwable?) : HttpFailureException
+
+
连接错误
+
+
+
+
+ +
+
+
NetException +
Link copied to clipboard
+
+
+
+ +
+
open class NetException(request: Request, message: String?, cause: Throwable?) : IOException
+
+
表示为Net发生的网络异常 在转换器com.drake.net.convert.NetConverter中抛出的异常如果没有继承该类都会被视为数据转换异常ConvertException, 该类一般用于自定义异常
+
+
+
+
+ +
+
+
NetSocketTimeoutException +
Link copied to clipboard
+
+
+
+ +
+
class NetSocketTimeoutException(request: Request, message: String?, cause: Throwable?) : HttpFailureException
+
+
请求过程中读取或者写入超时
+
+
+
+
+ +
+
+
NetUnknownHostException +
Link copied to clipboard
+
+
+
+ +
+
class NetUnknownHostException(request: Request, message: String?, cause: Throwable?) : HttpFailureException
+
+
主机域名无法访问
+
+
+
+
+ +
+
+
NetworkingException +
Link copied to clipboard
+
+
+
+ +
+
class NetworkingException(request: Request, message: String?, cause: Throwable?) : HttpFailureException
+
+
无网络情况
+
+
+
+
+ +
+
+
NoCacheException +
Link copied to clipboard
+
+
+
+ +
+
class NoCacheException(request: Request, message: String?, cause: Throwable?) : NetException
+
+
读取缓存失败 仅当设置强制缓存模式com.drake.net.cache.CacheMode.READcom.drake.net.cache.CacheMode.REQUEST_THEN_READ才会发生此异常
+
+
+
+
+ +
+
+
RequestParamsException +
Link copied to clipboard
+
+
+
+ +
+
class RequestParamsException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException
+
+
400 - 499 客户端请求异常
+
+
+
+
+ +
+
+
ResponseException +
Link copied to clipboard
+
+
+
+ +
+
class ResponseException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException
+
+
状态码在200..
+
+
+
+
+ +
+
+
ServerResponseException +
Link copied to clipboard
+
+
+
+ +
+
class ServerResponseException(response: Response, message: String?, cause: Throwable?, tag: Any?) : HttpResponseException
+
+

= 500 服务器异常

+
+
+
+
+ +
+
+
URLParseException +
Link copied to clipboard
+
+
+
+ +
+
open class URLParseException(message: String?, cause: Throwable?) : Exception
+
+
URL地址错误
+
+
+
+
+
+

Functions

+
+
+
+
NetCancellationException +
Link copied to clipboard
+
+
+
+ +
+
fun CoroutineScope.NetCancellationException(message: String? = null): NetCancellationException
+
+
在作用域中抛出该异常将取消其作用域内所有的网络请求(如果存在的话)
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-log-record-interceptor/-log-record-interceptor.html b/api/-net/com.drake.net.interceptor/-log-record-interceptor/-log-record-interceptor.html new file mode 100644 index 000000000..ec9ce2f8d --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-log-record-interceptor/-log-record-interceptor.html @@ -0,0 +1,38 @@ + + + + LogRecordInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

LogRecordInterceptor

+
+
+ +
+
fun LogRecordInterceptor(enabled: Boolean, requestByteCount: Long = 1024 * 1024, responseByteCount: Long = 1024 * 1024 * 4)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-log-record-interceptor/enabled.html b/api/-net/com.drake.net.interceptor/-log-record-interceptor/enabled.html new file mode 100644 index 000000000..c181bec0c --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-log-record-interceptor/enabled.html @@ -0,0 +1,38 @@ + + + + enabled + + +
+
+ + +
+
+
+
+
+
+ +
+

enabled

+
+
+ +
+
var enabled: Boolean
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-log-record-interceptor/index.html b/api/-net/com.drake.net.interceptor/-log-record-interceptor/index.html new file mode 100644 index 000000000..6708aa93a --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-log-record-interceptor/index.html @@ -0,0 +1,113 @@ + + + + LogRecordInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

LogRecordInterceptor

+
open class LogRecordInterceptor @JvmOverloads() constructor(enabled: Boolean, requestByteCount: Long, responseByteCount: Long) : Interceptor

网络日志记录器 可以参考此拦截器为项目中其他网络请求库配置. 本拦截器属于标准的OkHttp拦截器适用于所有OkHttp拦截器内核的网络请求库

在正式环境下请禁用此日志记录器. 因为他会消耗少量网络速度

+
+
+
+
+

Constructors

+
+
+
+
LogRecordInterceptor +
Link copied to clipboard
+
+
+
+
fun LogRecordInterceptor(enabled: Boolean, requestByteCount: Long = 1024 * 1024, responseByteCount: Long = 1024 * 1024 * 4)
+
+
+
+
+
+

Functions

+
+
+
+
intercept +
Link copied to clipboard
+
+
+
+ +
+
open override fun intercept(chain: Interceptor.Chain): Response
+
+
+
+
+
+
+
+

Properties

+
+
+
+
enabled +
Link copied to clipboard
+
+
+
+
var enabled: Boolean
是否启用日志输出
+
+
+
+
+ +
+
+
requestByteCount +
Link copied to clipboard
+
+
+
+
var requestByteCount: Long
请求日志输出字节数, -1 则为全部
+
+
+
+
+ +
+
+
responseByteCount +
Link copied to clipboard
+
+
+
+
var responseByteCount: Long
响应日志输出字节数, -1 则为全部
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-log-record-interceptor/intercept.html b/api/-net/com.drake.net.interceptor/-log-record-interceptor/intercept.html new file mode 100644 index 000000000..acc970181 --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-log-record-interceptor/intercept.html @@ -0,0 +1,38 @@ + + + + intercept + + +
+
+ + +
+
+
+
+
+
+ +
+

intercept

+
+
+ +
+
open override fun intercept(chain: Interceptor.Chain): Response
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-log-record-interceptor/request-byte-count.html b/api/-net/com.drake.net.interceptor/-log-record-interceptor/request-byte-count.html new file mode 100644 index 000000000..48ea80694 --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-log-record-interceptor/request-byte-count.html @@ -0,0 +1,38 @@ + + + + requestByteCount + + +
+
+ + +
+
+
+
+
+
+ +
+

requestByteCount

+
+
+ +
+
var requestByteCount: Long
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-log-record-interceptor/response-byte-count.html b/api/-net/com.drake.net.interceptor/-log-record-interceptor/response-byte-count.html new file mode 100644 index 000000000..027d8a517 --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-log-record-interceptor/response-byte-count.html @@ -0,0 +1,38 @@ + + + + responseByteCount + + +
+
+ + +
+
+
+
+
+
+ +
+

responseByteCount

+
+
+ +
+
var responseByteCount: Long
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/index.html b/api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/index.html new file mode 100644 index 000000000..bbe59d2df --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/index.html @@ -0,0 +1,57 @@ + + + + NetOkHttpInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

NetOkHttpInterceptor

+
object NetOkHttpInterceptor : Interceptor

Net代理OkHttp的拦截器

+
+
+
+
+

Functions

+
+
+
+
intercept +
Link copied to clipboard
+
+
+
+ +
+
open override fun intercept(chain: Interceptor.Chain): Response
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/intercept.html b/api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/intercept.html new file mode 100644 index 000000000..627aca99d --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-net-ok-http-interceptor/intercept.html @@ -0,0 +1,38 @@ + + + + intercept + + +
+
+ + +
+
+
+
+
+
+ +
+

intercept

+
+
+ +
+
open override fun intercept(chain: Interceptor.Chain): Response
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-request-interceptor/index.html b/api/-net/com.drake.net.interceptor/-request-interceptor/index.html new file mode 100644 index 000000000..c5537a711 --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-request-interceptor/index.html @@ -0,0 +1,57 @@ + + + + RequestInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestInterceptor

+
interface RequestInterceptor
+
+
+
+
+

Functions

+
+
+
+
interceptor +
Link copied to clipboard
+
+
+
+ +
+
abstract fun interceptor(request: BaseRequest)
+
+
当你使用Net发起请求的时候就会触发该拦截器 该拦截器属于轻量级不具备重发的功能, 一般用于请求参数的修改 请勿在这里进行请求重发可能会导致死循环
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-request-interceptor/interceptor.html b/api/-net/com.drake.net.interceptor/-request-interceptor/interceptor.html new file mode 100644 index 000000000..96f9a0ff8 --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-request-interceptor/interceptor.html @@ -0,0 +1,38 @@ + + + + interceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

interceptor

+
+
+ +
+
abstract fun interceptor(request: BaseRequest)
+
+

当你使用Net发起请求的时候就会触发该拦截器 该拦截器属于轻量级不具备重发的功能, 一般用于请求参数的修改 请勿在这里进行请求重发可能会导致死循环

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-retry-interceptor/-retry-interceptor.html b/api/-net/com.drake.net.interceptor/-retry-interceptor/-retry-interceptor.html new file mode 100644 index 000000000..d1700a8df --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-retry-interceptor/-retry-interceptor.html @@ -0,0 +1,38 @@ + + + + RetryInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

RetryInterceptor

+
+
+ +
+
fun RetryInterceptor(@IntRange(from = 1.toLong()retryCount: Int = 3)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-retry-interceptor/index.html b/api/-net/com.drake.net.interceptor/-retry-interceptor/index.html new file mode 100644 index 000000000..eb6d0fe15 --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-retry-interceptor/index.html @@ -0,0 +1,87 @@ + + + + RetryInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

RetryInterceptor

+
class RetryInterceptor(@IntRange(from = 1.toLong()retryCount: Int) : Interceptor

重试次数拦截器 OkHttp自带重试请求规则, 本拦截器并不推荐使用 因为长时间阻塞用户请求是不合理的, 发生错误请让用户主动重试, 例如显示缺省页或者提示

+
+
+
+
+

Constructors

+
+
+
+
RetryInterceptor +
Link copied to clipboard
+
+
+
+
fun RetryInterceptor(@IntRange(from = 1.toLong()retryCount: Int = 3)
+
+
+
+
+
+

Functions

+
+
+
+
intercept +
Link copied to clipboard
+
+
+
+ +
+
open override fun intercept(chain: Interceptor.Chain): Response
+
+
+
+
+
+
+
+

Properties

+
+
+
+
retryCount +
Link copied to clipboard
+
+
+
+
var retryCount: Int = 3
重试次数
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-retry-interceptor/intercept.html b/api/-net/com.drake.net.interceptor/-retry-interceptor/intercept.html new file mode 100644 index 000000000..ad3a1c26a --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-retry-interceptor/intercept.html @@ -0,0 +1,38 @@ + + + + intercept + + +
+
+ + +
+
+
+
+
+
+ +
+

intercept

+
+
+ +
+
open override fun intercept(chain: Interceptor.Chain): Response
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/-retry-interceptor/retry-count.html b/api/-net/com.drake.net.interceptor/-retry-interceptor/retry-count.html new file mode 100644 index 000000000..cfcb3140b --- /dev/null +++ b/api/-net/com.drake.net.interceptor/-retry-interceptor/retry-count.html @@ -0,0 +1,38 @@ + + + + retryCount + + +
+
+ + +
+
+
+
+
+
+ +
+

retryCount

+
+
+ +
+
var retryCount: Int = 3
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interceptor/index.html b/api/-net/com.drake.net.interceptor/index.html new file mode 100644 index 000000000..729eacd4d --- /dev/null +++ b/api/-net/com.drake.net.interceptor/index.html @@ -0,0 +1,107 @@ + + + + com.drake.net.interceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.interceptor

+
+
+
+
+

Types

+
+
+
+
LogRecordInterceptor +
Link copied to clipboard
+
+
+
+ +
+
open class LogRecordInterceptor @JvmOverloads() constructor(enabled: Boolean, requestByteCount: Long, responseByteCount: Long) : Interceptor
+
+
网络日志记录器 可以参考此拦截器为项目中其他网络请求库配置.
+
+
+
+
+ +
+
+
NetOkHttpInterceptor +
Link copied to clipboard
+
+
+
+ +
+
object NetOkHttpInterceptor : Interceptor
+
+
Net代理OkHttp的拦截器
+
+
+
+
+ +
+
+
RequestInterceptor +
Link copied to clipboard
+
+
+
+ +
+
interface RequestInterceptor
+
+
+
+
+
+
+ +
+
+
RetryInterceptor +
Link copied to clipboard
+
+
+
+ +
+
class RetryInterceptor(@IntRange(from = 1.toLong()retryCount: Int) : Interceptor
+
+
重试次数拦截器 OkHttp自带重试请求规则, 本拦截器并不推荐使用 因为长时间阻塞用户请求是不合理的, 发生错误请让用户主动重试, 例如显示缺省页或者提示
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/index.html b/api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/index.html new file mode 100644 index 000000000..a93d88b53 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/index.html @@ -0,0 +1,57 @@ + + + + DEFAULT + + +
+
+ + +
+
+
+
+
+
+ +
+

DEFAULT

+
object DEFAULT : NetDialogFactory
+
+
+
+
+

Functions

+
+
+
+
onCreate +
Link copied to clipboard
+
+
+
+ +
+
open override fun onCreate(activity: FragmentActivity): Dialog
+
+
构建并返回Dialog.
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/on-create.html b/api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/on-create.html new file mode 100644 index 000000000..0222dfa0c --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/on-create.html @@ -0,0 +1,38 @@ + + + + onCreate + + +
+
+ + +
+
+
+
+
+
+ +
+

onCreate

+
+
+ +
+
open override fun onCreate(activity: FragmentActivity): Dialog
+
+

构建并返回Dialog. 当使用 scopeDialog 作用域时将会自动显示该对话框且作用域完成后关闭对话框

Parameters

activity

请求发生所在的FragmentActivity

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-dialog-factory/index.html b/api/-net/com.drake.net.interfaces/-net-dialog-factory/index.html new file mode 100644 index 000000000..ba65176bc --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-dialog-factory/index.html @@ -0,0 +1,87 @@ + + + + NetDialogFactory + + +
+
+ + +
+
+
+
+
+
+ +
+

NetDialogFactory

+
fun fun interface NetDialogFactory
+
+
+
+
+

Types

+
+
+
+
DEFAULT +
Link copied to clipboard
+
+
+
+ +
+
object DEFAULT : NetDialogFactory
+
+
+
+
+
+
+
+

Functions

+
+
+
+
onCreate +
Link copied to clipboard
+
+
+
+ +
+
abstract fun onCreate(activity: FragmentActivity): Dialog
+
+
构建并返回Dialog.
+
+
+
+
+
+

Inheritors

+
+
+
+
NetDialogFactory +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-dialog-factory/on-create.html b/api/-net/com.drake.net.interfaces/-net-dialog-factory/on-create.html new file mode 100644 index 000000000..25452c95c --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-dialog-factory/on-create.html @@ -0,0 +1,38 @@ + + + + onCreate + + +
+
+ + +
+
+
+
+
+
+ +
+

onCreate

+
+
+ +
+
abstract fun onCreate(activity: FragmentActivity): Dialog
+
+

构建并返回Dialog. 当使用 scopeDialog 作用域时将会自动显示该对话框且作用域完成后关闭对话框

Parameters

activity

请求发生所在的FragmentActivity

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-error-handler/-d-e-f-a-u-l-t/index.html b/api/-net/com.drake.net.interfaces/-net-error-handler/-d-e-f-a-u-l-t/index.html new file mode 100644 index 000000000..341462ded --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-error-handler/-d-e-f-a-u-l-t/index.html @@ -0,0 +1,37 @@ + + + + DEFAULT + + +
+
+ + +
+
+
+
+
+
+ +
+

DEFAULT

+
object DEFAULT : NetErrorHandler
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-error-handler/index.html b/api/-net/com.drake.net.interfaces/-net-error-handler/index.html new file mode 100644 index 000000000..b05281e61 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-error-handler/index.html @@ -0,0 +1,104 @@ + + + + NetErrorHandler + + +
+
+ + +
+
+
+
+
+
+ +
+

NetErrorHandler

+
interface NetErrorHandler
+
+
+
+
+

Types

+
+
+
+
DEFAULT +
Link copied to clipboard
+
+
+
+ +
+
object DEFAULT : NetErrorHandler
+
+
+
+
+
+
+
+

Functions

+
+
+
+
onError +
Link copied to clipboard
+
+
+
+ +
+
open fun onError(e: Throwable)
+
+
全局的网络错误处理
+
+
+
+
+ +
+
+
onStateError +
Link copied to clipboard
+
+
+
+ +
+
open fun onStateError(e: Throwable, view: View)
+
+
当你使用包含缺省页功能的作用域中发生错误将回调本函数处理错误
+
+
+
+
+
+

Inheritors

+
+
+
+
NetErrorHandler +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-error-handler/on-error.html b/api/-net/com.drake.net.interfaces/-net-error-handler/on-error.html new file mode 100644 index 000000000..b8f7fee4e --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-error-handler/on-error.html @@ -0,0 +1,38 @@ + + + + onError + + +
+
+ + +
+
+
+
+
+
+ +
+

onError

+
+
+ +
+
open fun onError(e: Throwable)
+
+

全局的网络错误处理

Parameters

e

发生的错误

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-net-error-handler/on-state-error.html b/api/-net/com.drake.net.interfaces/-net-error-handler/on-state-error.html new file mode 100644 index 000000000..f46843bd3 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-net-error-handler/on-state-error.html @@ -0,0 +1,38 @@ + + + + onStateError + + +
+
+ + +
+
+
+
+
+
+ +
+

onStateError

+
+
+ +
+
open fun onStateError(e: Throwable, view: View)
+
+

当你使用包含缺省页功能的作用域中发生错误将回调本函数处理错误

Parameters

e

发生的错误

view

缺省页, StateLayout或者PageRefreshLayout

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-progress-listener/-progress-listener.html b/api/-net/com.drake.net.interfaces/-progress-listener/-progress-listener.html new file mode 100644 index 000000000..15a4f9fd3 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-progress-listener/-progress-listener.html @@ -0,0 +1,38 @@ + + + + ProgressListener + + +
+
+ + +
+
+
+
+
+
+ +
+

ProgressListener

+
+
+ +
+
fun ProgressListener(interval: Long = 500)
+
+

Parameters

interval

进度监听器刷新的间隔时间, 单位为毫秒, 默认值为500ms

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-progress-listener/elapsed-time.html b/api/-net/com.drake.net.interfaces/-progress-listener/elapsed-time.html new file mode 100644 index 000000000..5d08d1ff9 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-progress-listener/elapsed-time.html @@ -0,0 +1,38 @@ + + + + elapsedTime + + +
+
+ + +
+
+
+
+
+
+ +
+

elapsedTime

+
+
+ +
+
var elapsedTime: Long = 0L
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-progress-listener/index.html b/api/-net/com.drake.net.interfaces/-progress-listener/index.html new file mode 100644 index 000000000..eb747c3bd --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-progress-listener/index.html @@ -0,0 +1,117 @@ + + + + ProgressListener + + +
+
+ + +
+
+
+
+
+
+ +
+

ProgressListener

+
abstract class ProgressListener(interval: Long)

进度监听器, 可能为下载或上传

+
+
+
+
+

Parameters

+
+
interval

进度监听器刷新的间隔时间, 单位为毫秒, 默认值为500ms

+
+

Constructors

+
+
+
+
ProgressListener +
Link copied to clipboard
+
+
+
+
fun ProgressListener(interval: Long = 500)
进度监听器刷新的间隔时间, 单位为毫秒, 默认值为500ms
+
+
+
+
+
+

Functions

+
+
+
+
onProgress +
Link copied to clipboard
+
+
+
+ +
+
abstract fun onProgress(p: Progress)
+
+
监听上传/下载进度回调函数
+
+
+
+
+
+

Properties

+
+
+
+
elapsedTime +
Link copied to clipboard
+
+
+
+
var elapsedTime: Long = 0L
+
+
+
+
+ +
+
+
interval +
Link copied to clipboard
+
+
+
+
var interval: Long = 500
进度监听器刷新的间隔时间, 单位为毫秒, 默认值为500ms
+
+
+
+
+ +
+
+
intervalByteCount +
Link copied to clipboard
+
+
+
+
var intervalByteCount: Long = 0L
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-progress-listener/interval-byte-count.html b/api/-net/com.drake.net.interfaces/-progress-listener/interval-byte-count.html new file mode 100644 index 000000000..810489911 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-progress-listener/interval-byte-count.html @@ -0,0 +1,38 @@ + + + + intervalByteCount + + +
+
+ + +
+
+
+
+
+
+ +
+

intervalByteCount

+
+
+ +
+
var intervalByteCount: Long = 0L
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-progress-listener/interval.html b/api/-net/com.drake.net.interfaces/-progress-listener/interval.html new file mode 100644 index 000000000..d6d571469 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-progress-listener/interval.html @@ -0,0 +1,38 @@ + + + + interval + + +
+
+ + +
+
+
+
+
+
+ +
+

interval

+
+
+ +
+
var interval: Long = 500
+
+

Parameters

interval

进度监听器刷新的间隔时间, 单位为毫秒, 默认值为500ms

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/-progress-listener/on-progress.html b/api/-net/com.drake.net.interfaces/-progress-listener/on-progress.html new file mode 100644 index 000000000..89c6d267d --- /dev/null +++ b/api/-net/com.drake.net.interfaces/-progress-listener/on-progress.html @@ -0,0 +1,38 @@ + + + + onProgress + + +
+
+ + +
+
+
+
+
+
+ +
+

onProgress

+
+
+ +
+
abstract fun onProgress(p: Progress)
+
+

监听上传/下载进度回调函数

Parameters

p

上传或者下载进度

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.interfaces/index.html b/api/-net/com.drake.net.interfaces/index.html new file mode 100644 index 000000000..195a0ec55 --- /dev/null +++ b/api/-net/com.drake.net.interfaces/index.html @@ -0,0 +1,90 @@ + + + + com.drake.net.interfaces + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.interfaces

+
+
+
+
+

Types

+
+
+
+
NetDialogFactory +
Link copied to clipboard
+
+
+
+ +
+
fun fun interface NetDialogFactory
+
+
+
+
+
+
+ +
+
+
NetErrorHandler +
Link copied to clipboard
+
+
+
+ +
+
interface NetErrorHandler
+
+
+
+
+
+
+ +
+
+
ProgressListener +
Link copied to clipboard
+
+
+
+ +
+
abstract class ProgressListener(interval: Long)
+
+
进度监听器, 可能为下载或上传
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-log-recorder/enabled.html b/api/-net/com.drake.net.log/-log-recorder/enabled.html new file mode 100644 index 000000000..cb135d2d5 --- /dev/null +++ b/api/-net/com.drake.net.log/-log-recorder/enabled.html @@ -0,0 +1,38 @@ + + + + enabled + + +
+
+ + +
+
+
+
+
+
+ +
+

enabled

+
+
+ +
+
var enabled: Boolean = true
+
+

是否启用日志记录器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-log-recorder/generate-id.html b/api/-net/com.drake.net.log/-log-recorder/generate-id.html new file mode 100644 index 000000000..d946a4dff --- /dev/null +++ b/api/-net/com.drake.net.log/-log-recorder/generate-id.html @@ -0,0 +1,38 @@ + + + + generateId + + +
+
+ + +
+
+
+
+
+
+ +
+

generateId

+
+
+ +
+
fun generateId(): String
+
+

产生一个唯一的基于时间戳Id

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-log-recorder/index.html b/api/-net/com.drake.net.log/-log-recorder/index.html new file mode 100644 index 000000000..b6354ff33 --- /dev/null +++ b/api/-net/com.drake.net.log/-log-recorder/index.html @@ -0,0 +1,123 @@ + + + + LogRecorder + + +
+
+ + +
+
+
+
+
+
+ +
+

LogRecorder

+
object LogRecorder

日志记录器

+
+
+
+
+

Functions

+
+
+
+
generateId +
Link copied to clipboard
+
+
+
+ +
+
fun generateId(): String
+
+
产生一个唯一的基于时间戳Id
+
+
+
+
+ +
+
+
recordException +
Link copied to clipboard
+
+
+
+ +
+
fun recordException(id: String, requestMillis: Long, code: Int?, response: String?, error: String?)
+
+
发送请求异常到记录器
+
+
+
+
+ +
+
+
recordRequest +
Link copied to clipboard
+
+
+
+ +
+
fun recordRequest(id: String, url: String, method: String, headers: Map<String, List<String>>, body: String?)
+
+
发送请求信息到记录器中
+
+
+
+
+ +
+
+
recordResponse +
Link copied to clipboard
+
+
+
+ +
+
fun recordResponse(id: String, requestMillis: Long, code: Int, headers: Map<String, List<String>>, body: String?)
+
+
发送响应信息到记录器中
+
+
+
+
+
+

Properties

+
+
+
+
enabled +
Link copied to clipboard
+
+
+
+
var enabled: Boolean = true
是否启用日志记录器
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-log-recorder/record-exception.html b/api/-net/com.drake.net.log/-log-recorder/record-exception.html new file mode 100644 index 000000000..66d209c8f --- /dev/null +++ b/api/-net/com.drake.net.log/-log-recorder/record-exception.html @@ -0,0 +1,38 @@ + + + + recordException + + +
+
+ + +
+
+
+
+
+
+ +
+

recordException

+
+
+ +
+
fun recordException(id: String, requestMillis: Long, code: Int?, response: String?, error: String?)
+
+

发送请求异常到记录器

Parameters

id

请求的唯一标识符

requestMillis

请求时间毫秒值

error

错误信息, 如果存在\n换行符, 仅接受最后一行

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-log-recorder/record-request.html b/api/-net/com.drake.net.log/-log-recorder/record-request.html new file mode 100644 index 000000000..f602c009e --- /dev/null +++ b/api/-net/com.drake.net.log/-log-recorder/record-request.html @@ -0,0 +1,38 @@ + + + + recordRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

recordRequest

+
+
+ +
+
fun recordRequest(id: String, url: String, method: String, headers: Map<String, List<String>>, body: String?)
+
+

发送请求信息到记录器中

Parameters

id

请求的唯一标识符

url

请求URL地址

method

请求方法

headers

请求头

body

请求体

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-log-recorder/record-response.html b/api/-net/com.drake.net.log/-log-recorder/record-response.html new file mode 100644 index 000000000..dbe9ced04 --- /dev/null +++ b/api/-net/com.drake.net.log/-log-recorder/record-response.html @@ -0,0 +1,38 @@ + + + + recordResponse + + +
+
+ + +
+
+
+
+
+
+ +
+

recordResponse

+
+
+ +
+
fun recordResponse(id: String, requestMillis: Long, code: Int, headers: Map<String, List<String>>, body: String?)
+
+

发送响应信息到记录器中

Parameters

id

请求的唯一标识符

code

响应码

headers

响应头

body

响应体

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-b-o-d-y/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-b-o-d-y/index.html new file mode 100644 index 000000000..53c5d3bdd --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-b-o-d-y/index.html @@ -0,0 +1,37 @@ + + + + REQUEST_BODY + + +
+
+ + +
+
+
+
+
+
+ +
+

REQUEST_BODY

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-e-n-d/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-e-n-d/index.html new file mode 100644 index 000000000..0bae624fb --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-e-n-d/index.html @@ -0,0 +1,37 @@ + + + + REQUEST_END + + +
+
+ + +
+
+
+
+
+
+ +
+

REQUEST_END

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-h-e-a-d-e-r/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-h-e-a-d-e-r/index.html new file mode 100644 index 000000000..c43dc6fbe --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-h-e-a-d-e-r/index.html @@ -0,0 +1,37 @@ + + + + REQUEST_HEADER + + +
+
+ + +
+
+
+
+
+
+ +
+

REQUEST_HEADER

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-m-e-t-h-o-d/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-m-e-t-h-o-d/index.html new file mode 100644 index 000000000..07fd5b6a3 --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-m-e-t-h-o-d/index.html @@ -0,0 +1,37 @@ + + + + REQUEST_METHOD + + +
+
+ + +
+
+
+
+
+
+ +
+

REQUEST_METHOD

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-t-i-m-e/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-t-i-m-e/index.html new file mode 100644 index 000000000..04c9a7109 --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-t-i-m-e/index.html @@ -0,0 +1,37 @@ + + + + REQUEST_TIME + + +
+
+ + +
+
+
+
+
+
+ +
+

REQUEST_TIME

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-u-r-l/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-u-r-l/index.html new file mode 100644 index 000000000..487a3cceb --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-u-r-l/index.html @@ -0,0 +1,37 @@ + + + + REQUEST_URL + + +
+
+ + +
+
+
+
+
+
+ +
+

REQUEST_URL

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-b-o-d-y/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-b-o-d-y/index.html new file mode 100644 index 000000000..249fbad5e --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-b-o-d-y/index.html @@ -0,0 +1,37 @@ + + + + RESPONSE_BODY + + +
+
+ + +
+
+
+
+
+
+ +
+

RESPONSE_BODY

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-n-d/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-n-d/index.html new file mode 100644 index 000000000..1296504f1 --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-n-d/index.html @@ -0,0 +1,37 @@ + + + + RESPONSE_END + + +
+
+ + +
+
+
+
+
+
+ +
+

RESPONSE_END

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-r-r-o-r/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-r-r-o-r/index.html new file mode 100644 index 000000000..91843e22f --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-r-r-o-r/index.html @@ -0,0 +1,37 @@ + + + + RESPONSE_ERROR + + +
+
+ + +
+
+
+
+
+
+ +
+

RESPONSE_ERROR

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-h-e-a-d-e-r/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-h-e-a-d-e-r/index.html new file mode 100644 index 000000000..932f30a46 --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-h-e-a-d-e-r/index.html @@ -0,0 +1,37 @@ + + + + RESPONSE_HEADER + + +
+
+ + +
+
+
+
+
+
+ +
+

RESPONSE_HEADER

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-s-t-a-t-u-s/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-s-t-a-t-u-s/index.html new file mode 100644 index 000000000..0eb4108ec --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-s-t-a-t-u-s/index.html @@ -0,0 +1,37 @@ + + + + RESPONSE_STATUS + + +
+
+ + +
+
+
+
+
+
+ +
+

RESPONSE_STATUS

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-t-i-m-e/index.html b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-t-i-m-e/index.html new file mode 100644 index 000000000..871459403 --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-t-i-m-e/index.html @@ -0,0 +1,37 @@ + + + + RESPONSE_TIME + + +
+
+ + +
+
+
+
+
+
+ +
+

RESPONSE_TIME

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/-u-n-k-n-o-w-n/index.html b/api/-net/com.drake.net.log/-message-type/-u-n-k-n-o-w-n/index.html new file mode 100644 index 000000000..699b871aa --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/-u-n-k-n-o-w-n/index.html @@ -0,0 +1,37 @@ + + + + UNKNOWN + + +
+
+ + +
+
+
+
+
+
+ +
+

UNKNOWN

+
UNKNOWN("UNKNOWN")
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/index.html b/api/-net/com.drake.net.log/-message-type/index.html new file mode 100644 index 000000000..1ba3bbc23 --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/index.html @@ -0,0 +1,224 @@ + + + + MessageType + + +
+
+ + +
+
+
+
+
+
+ +
+

MessageType

+
enum MessageType : Enum<MessageType>
+
+
+
+
+

Entries

+
+
+
+
UNKNOWN +
Link copied to clipboard
+
+
+
+
UNKNOWN("UNKNOWN")
+
+
+
+
+ +
+
+
RESPONSE_ERROR +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
RESPONSE_END +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
RESPONSE_BODY +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
RESPONSE_HEADER +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
RESPONSE_STATUS +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
RESPONSE_TIME +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
REQUEST_END +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
REQUEST_BODY +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
REQUEST_HEADER +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
REQUEST_METHOD +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
REQUEST_TIME +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
REQUEST_URL +
Link copied to clipboard
+
+
+
+
+
+
+
+
+
+

Properties

+
+
+
+
type +
Link copied to clipboard
+
+
+
+
var type: String
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/-message-type/type.html b/api/-net/com.drake.net.log/-message-type/type.html new file mode 100644 index 000000000..d4f0e17eb --- /dev/null +++ b/api/-net/com.drake.net.log/-message-type/type.html @@ -0,0 +1,38 @@ + + + + type + + +
+
+ + +
+
+
+
+
+
+ +
+

type

+
+
+ +
+
var type: String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.log/index.html b/api/-net/com.drake.net.log/index.html new file mode 100644 index 000000000..d5952b795 --- /dev/null +++ b/api/-net/com.drake.net.log/index.html @@ -0,0 +1,73 @@ + + + + com.drake.net.log + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.log

+
+
+
+
+

Types

+
+
+
+
LogRecorder +
Link copied to clipboard
+
+
+
+ +
+
object LogRecorder
+
+
日志记录器
+
+
+
+
+ +
+
+
MessageType +
Link copied to clipboard
+
+
+
+ +
+
enum MessageType : Enum<MessageType>
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/index.html b/api/-net/com.drake.net.okhttp/index.html new file mode 100644 index 000000000..bf9d8dc0e --- /dev/null +++ b/api/-net/com.drake.net.okhttp/index.html @@ -0,0 +1,187 @@ + + + + com.drake.net.okhttp + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.okhttp

+
+
+
+
+

Functions

+
+
+
+
setConverter +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.Builder.setConverter(converter: NetConverter): <ERROR CLASS>
+
+
转换器
+
+
+
+
+ +
+
+
setDebug +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.Builder.setDebug(enabled: Boolean, tag: String = NetConfig.TAG): <ERROR CLASS>
+
+
开启日志
+
+
+
+
+ +
+
+
setDialogFactory +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.Builder.setDialogFactory(dialogFactory: NetDialogFactory): <ERROR CLASS>
+
+
请求对话框构建工厂
+
+
+
+
+ +
+
+
setErrorHandler +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.Builder.setErrorHandler(handler: NetErrorHandler): <ERROR CLASS>
+
+
全局错误处理器
+
+
+
+
+ +
+
+
setRequestInterceptor +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.Builder.setRequestInterceptor(interceptor: RequestInterceptor): <ERROR CLASS>
+
+
添加轻量级的请求拦截器, 可以在每次请求之前修改参数或者客户端配置 该拦截器不同于OkHttp的Interceptor无需处理请求动作
+
+
+
+
+ +
+
+
setSSLCertificate +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.Builder.setSSLCertificate(trustManager: X509TrustManager?, bksFile: InputStream? = null, password: String? = null): <ERROR CLASS>
+
+
配置信任所有证书
+
+ +
+
fun OkHttpClient.Builder.setSSLCertificate(vararg certificates: InputStream, bksFile: InputStream? = null, password: String? = null): <ERROR CLASS>
+
+
配置信任所有证书
+
+
+
+
+ +
+
+
toNetOkhttp +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.toNetOkhttp(): <ERROR CLASS>
+
+
Net要求经过该函数处理创建特殊的OkHttpClient
+
+ +
+
fun OkHttpClient.Builder.toNetOkhttp(): <ERROR CLASS>
+
+
Net要求经过该函数处理创建特殊的OkHttpClient
+
+
+
+
+ +
+
+
trustSSLCertificate +
Link copied to clipboard
+
+
+
+ +
+
fun OkHttpClient.Builder.trustSSLCertificate(): <ERROR CLASS>
+
+
信任所有证书
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/set-converter.html b/api/-net/com.drake.net.okhttp/set-converter.html new file mode 100644 index 000000000..b095623aa --- /dev/null +++ b/api/-net/com.drake.net.okhttp/set-converter.html @@ -0,0 +1,38 @@ + + + + setConverter + + +
+
+ + +
+
+
+
+
+
+ +
+

setConverter

+
+
+ +
+
fun OkHttpClient.Builder.setConverter(converter: NetConverter): <ERROR CLASS>
+
+

转换器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/set-debug.html b/api/-net/com.drake.net.okhttp/set-debug.html new file mode 100644 index 000000000..7d02a951d --- /dev/null +++ b/api/-net/com.drake.net.okhttp/set-debug.html @@ -0,0 +1,38 @@ + + + + setDebug + + +
+
+ + +
+
+
+
+
+
+ +
+

setDebug

+
+
+ +
+
fun OkHttpClient.Builder.setDebug(enabled: Boolean, tag: String = NetConfig.TAG): <ERROR CLASS>
+
+

开启日志

Parameters

enabled

是否启用日志

tag

日志标签

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/set-dialog-factory.html b/api/-net/com.drake.net.okhttp/set-dialog-factory.html new file mode 100644 index 000000000..eef96ca15 --- /dev/null +++ b/api/-net/com.drake.net.okhttp/set-dialog-factory.html @@ -0,0 +1,38 @@ + + + + setDialogFactory + + +
+
+ + +
+
+
+
+
+
+ +
+

setDialogFactory

+
+
+ +
+
fun OkHttpClient.Builder.setDialogFactory(dialogFactory: NetDialogFactory): <ERROR CLASS>
+
+

请求对话框构建工厂

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/set-error-handler.html b/api/-net/com.drake.net.okhttp/set-error-handler.html new file mode 100644 index 000000000..5ebc2d2dc --- /dev/null +++ b/api/-net/com.drake.net.okhttp/set-error-handler.html @@ -0,0 +1,38 @@ + + + + setErrorHandler + + +
+
+ + +
+
+
+
+
+
+ +
+

setErrorHandler

+
+
+ +
+
fun OkHttpClient.Builder.setErrorHandler(handler: NetErrorHandler): <ERROR CLASS>
+
+

全局错误处理器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/set-request-interceptor.html b/api/-net/com.drake.net.okhttp/set-request-interceptor.html new file mode 100644 index 000000000..137c09893 --- /dev/null +++ b/api/-net/com.drake.net.okhttp/set-request-interceptor.html @@ -0,0 +1,38 @@ + + + + setRequestInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

setRequestInterceptor

+
+
+ +
+
fun OkHttpClient.Builder.setRequestInterceptor(interceptor: RequestInterceptor): <ERROR CLASS>
+
+

添加轻量级的请求拦截器, 可以在每次请求之前修改参数或者客户端配置 该拦截器不同于OkHttp的Interceptor无需处理请求动作

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/set-s-s-l-certificate.html b/api/-net/com.drake.net.okhttp/set-s-s-l-certificate.html new file mode 100644 index 000000000..f1366d2e1 --- /dev/null +++ b/api/-net/com.drake.net.okhttp/set-s-s-l-certificate.html @@ -0,0 +1,44 @@ + + + + setSSLCertificate + + +
+
+ + +
+
+
+
+
+
+ +
+

setSSLCertificate

+
+
+ +
+
fun OkHttpClient.Builder.setSSLCertificate(trustManager: X509TrustManager?, bksFile: InputStream? = null, password: String? = null): <ERROR CLASS>
+
+

配置信任所有证书

Parameters

trustManager

如果需要自己校验,那么可以自己实现相关校验,如果不需要自己校验,那么传null即可

bksFile

客户端使用bks证书校验服务端证书

password

bks证书的密码

+
+ +
+
fun OkHttpClient.Builder.setSSLCertificate(vararg certificates: InputStream, bksFile: InputStream? = null, password: String? = null): <ERROR CLASS>
+
+

配置信任所有证书

Parameters

certificates

含有服务端公钥的证书校验服务端证书

bksFile

客户端使用bks证书校验服务端证书

password

bks证书的密码

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/to-net-okhttp.html b/api/-net/com.drake.net.okhttp/to-net-okhttp.html new file mode 100644 index 000000000..22a4a34bf --- /dev/null +++ b/api/-net/com.drake.net.okhttp/to-net-okhttp.html @@ -0,0 +1,38 @@ + + + + toNetOkhttp + + +
+
+ + +
+
+
+
+
+
+ +
+

toNetOkhttp

+
+
+ +
+
fun OkHttpClient.Builder.toNetOkhttp(): <ERROR CLASS>
fun OkHttpClient.toNetOkhttp(): <ERROR CLASS>
+
+

Net要求经过该函数处理创建特殊的OkHttpClient

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.okhttp/trust-s-s-l-certificate.html b/api/-net/com.drake.net.okhttp/trust-s-s-l-certificate.html new file mode 100644 index 000000000..f0551a5b8 --- /dev/null +++ b/api/-net/com.drake.net.okhttp/trust-s-s-l-certificate.html @@ -0,0 +1,38 @@ + + + + trustSSLCertificate + + +
+
+ + +
+
+
+
+
+
+ +
+

trustSSLCertificate

+
+
+ +
+
fun OkHttpClient.Builder.trustSSLCertificate(): <ERROR CLASS>
+
+

信任所有证书

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-preconditions/check-argument.html b/api/-net/com.drake.net.reflect/$-gson$-preconditions/check-argument.html new file mode 100644 index 000000000..93fa8d54b --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-preconditions/check-argument.html @@ -0,0 +1,38 @@ + + + + checkArgument + + +
+
+ + +
+
+
+
+
+
+ +
+

checkArgument

+
+
+ +
+
open fun checkArgument(condition: Boolean)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-preconditions/check-not-null.html b/api/-net/com.drake.net.reflect/$-gson$-preconditions/check-not-null.html new file mode 100644 index 000000000..ace36e256 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-preconditions/check-not-null.html @@ -0,0 +1,38 @@ + + + + checkNotNull + + +
+
+ + +
+
+
+
+
+
+ +
+

checkNotNull

+
+
+ +
+
open fun <T> checkNotNull(obj: T): T
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-preconditions/index.html b/api/-net/com.drake.net.reflect/$-gson$-preconditions/index.html new file mode 100644 index 000000000..f28367af8 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-preconditions/index.html @@ -0,0 +1,78 @@ + + + + $Gson$Preconditions + + +
+
+ + +
+
+
+
+
+
+ +
+

$Gson$Preconditions

+
class $Gson$Preconditions

A simple utility class used to check method Preconditions.

public long divideBy(long value) {
+  Preconditions.checkArgument(value != 0);
+  return this.value / value;
+}
+

Author

Inderjeet Singh

Joel Leitch

+
+
+
+
+

Functions

+
+
+
+
checkArgument +
Link copied to clipboard
+
+
+
+ +
+
open fun checkArgument(condition: Boolean)
+
+
+
+
+
+
+ +
+
+
checkNotNull +
Link copied to clipboard
+
+
+
+ +
+
open fun <T> checkNotNull(obj: T): T
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/array-of.html b/api/-net/com.drake.net.reflect/$-gson$-types/array-of.html new file mode 100644 index 000000000..b2ea4d611 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/array-of.html @@ -0,0 +1,38 @@ + + + + arrayOf + + +
+
+ + +
+
+
+
+
+
+ +
+

arrayOf

+
+
+ +
+
open fun arrayOf(componentType: Type): GenericArrayType
+
+

Returns an array type whose elements are all instances of {@code componentType}.

Return

a serializable generic array type.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/canonicalize.html b/api/-net/com.drake.net.reflect/$-gson$-types/canonicalize.html new file mode 100644 index 000000000..7b3639ae6 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/canonicalize.html @@ -0,0 +1,38 @@ + + + + canonicalize + + +
+
+ + +
+
+
+
+
+
+ +
+

canonicalize

+
+
+ +
+
open fun canonicalize(type: Type): Type
+
+

Returns a type that is functionally equal but not necessarily equalaccording to Object.equals(). The returnedtype is Serializable.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/equals.html b/api/-net/com.drake.net.reflect/$-gson$-types/equals.html new file mode 100644 index 000000000..fb72590b7 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/equals.html @@ -0,0 +1,38 @@ + + + + equals + + +
+
+ + +
+
+
+
+
+
+ +
+

equals

+
+
+ +
+
open fun equals(a: Type, b: Type): Boolean
+
+

Returns true if {@code a} and {@code b} are equal.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/get-array-component-type.html b/api/-net/com.drake.net.reflect/$-gson$-types/get-array-component-type.html new file mode 100644 index 000000000..121298a7b --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/get-array-component-type.html @@ -0,0 +1,38 @@ + + + + getArrayComponentType + + +
+
+ + +
+
+
+
+
+
+ +
+

getArrayComponentType

+
+
+ +
+
open fun getArrayComponentType(array: Type): Type
+
+

Returns the component type of this array type.

Throws

if this type is not an array.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/get-collection-element-type.html b/api/-net/com.drake.net.reflect/$-gson$-types/get-collection-element-type.html new file mode 100644 index 000000000..54053abbe --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/get-collection-element-type.html @@ -0,0 +1,38 @@ + + + + getCollectionElementType + + +
+
+ + +
+
+
+
+
+
+ +
+

getCollectionElementType

+
+
+ +
+
open fun getCollectionElementType(context: Type, contextRawType: Class<out Any>): Type
+
+

Returns the element type of this collection type.

Throws

if this type is not a collection.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/get-map-key-and-value-types.html b/api/-net/com.drake.net.reflect/$-gson$-types/get-map-key-and-value-types.html new file mode 100644 index 000000000..122ba5988 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/get-map-key-and-value-types.html @@ -0,0 +1,38 @@ + + + + getMapKeyAndValueTypes + + +
+
+ + +
+
+
+
+
+
+ +
+

getMapKeyAndValueTypes

+
+
+ +
+
open fun getMapKeyAndValueTypes(context: Type, contextRawType: Class<out Any>): Array<Type>
+
+

Returns a two element array containing this map's key and value types inpositions 0 and 1 respectively.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/get-raw-type.html b/api/-net/com.drake.net.reflect/$-gson$-types/get-raw-type.html new file mode 100644 index 000000000..02bcab1ab --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/get-raw-type.html @@ -0,0 +1,38 @@ + + + + getRawType + + +
+
+ + +
+
+
+
+
+
+ +
+

getRawType

+
+
+ +
+
open fun getRawType(type: Type): Class<out Any>
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/index.html b/api/-net/com.drake.net.reflect/$-gson$-types/index.html new file mode 100644 index 000000000..427603e47 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/index.html @@ -0,0 +1,244 @@ + + + + $Gson$Types + + +
+
+ + +
+
+
+
+
+
+ +
+

$Gson$Types

+
class $Gson$Types

Static methods for working with types.

Author

Bob Lee

Jesse Wilson

+
+
+
+
+

Functions

+
+
+
+
arrayOf +
Link copied to clipboard
+
+
+
+ +
+
open fun arrayOf(componentType: Type): GenericArrayType
+
+
Returns an array type whose elements are all instances of {@code componentType}.
+
+
+
+
+ +
+
+
canonicalize +
Link copied to clipboard
+
+
+
+ +
+
open fun canonicalize(type: Type): Type
+
+
Returns a type that is functionally equal but not necessarily equalaccording to Object.equals().
+
+
+
+
+ +
+
+
equals +
Link copied to clipboard
+
+
+
+ +
+
open fun equals(a: Type, b: Type): Boolean
+
+
Returns true if {@code a} and {@code b} are equal.
+
+
+
+
+ +
+
+
getArrayComponentType +
Link copied to clipboard
+
+
+
+ +
+
open fun getArrayComponentType(array: Type): Type
+
+
Returns the component type of this array type.
+
+
+
+
+ +
+
+
getCollectionElementType +
Link copied to clipboard
+
+
+
+ +
+
open fun getCollectionElementType(context: Type, contextRawType: Class<out Any>): Type
+
+
Returns the element type of this collection type.
+
+
+
+
+ +
+
+
getMapKeyAndValueTypes +
Link copied to clipboard
+
+
+
+ +
+
open fun getMapKeyAndValueTypes(context: Type, contextRawType: Class<out Any>): Array<Type>
+
+
Returns a two element array containing this map's key and value types inpositions 0 and 1 respectively.
+
+
+
+
+ +
+
+
getRawType +
Link copied to clipboard
+
+
+
+ +
+
open fun getRawType(type: Type): Class<out Any>
+
+
+
+
+
+
+ +
+
+
newParameterizedTypeWithOwner +
Link copied to clipboard
+
+
+
+ +
+
open fun newParameterizedTypeWithOwner(ownerType: Type, rawType: Type, typeArguments: Array<Type>): ParameterizedType
+
+
Returns a new parameterized type, applying {@code typeArguments} to {@code rawType} and enclosed by {@code ownerType}.
+
+
+
+
+ +
+
+
resolve +
Link copied to clipboard
+
+
+
+ +
+
open fun resolve(context: Type, contextRawType: Class<out Any>, toResolve: Type): Type
+
+
+
+
+
+
+ +
+
+
subtypeOf +
Link copied to clipboard
+
+
+
+ +
+
open fun subtypeOf(bound: Type): WildcardType
+
+
Returns a type that represents an unknown type that extends {@code bound}.
+
+
+
+
+ +
+
+
supertypeOf +
Link copied to clipboard
+
+
+
+ +
+
open fun supertypeOf(bound: Type): WildcardType
+
+
Returns a type that represents an unknown supertype of {@code bound}.
+
+
+
+
+ +
+
+
typeToString +
Link copied to clipboard
+
+
+
+ +
+
open fun typeToString(type: Type): String
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/new-parameterized-type-with-owner.html b/api/-net/com.drake.net.reflect/$-gson$-types/new-parameterized-type-with-owner.html new file mode 100644 index 000000000..2d234643f --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/new-parameterized-type-with-owner.html @@ -0,0 +1,38 @@ + + + + newParameterizedTypeWithOwner + + +
+
+ + +
+
+
+
+
+
+ +
+

newParameterizedTypeWithOwner

+
+
+ +
+
open fun newParameterizedTypeWithOwner(ownerType: Type, rawType: Type, typeArguments: Array<Type>): ParameterizedType
+
+

Returns a new parameterized type, applying {@code typeArguments} to {@code rawType} and enclosed by {@code ownerType}.

Return

a serializable parameterized type.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/resolve.html b/api/-net/com.drake.net.reflect/$-gson$-types/resolve.html new file mode 100644 index 000000000..eb28139ac --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/resolve.html @@ -0,0 +1,38 @@ + + + + resolve + + +
+
+ + +
+
+
+
+
+
+ +
+

resolve

+
+
+ +
+
open fun resolve(context: Type, contextRawType: Class<out Any>, toResolve: Type): Type
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/subtype-of.html b/api/-net/com.drake.net.reflect/$-gson$-types/subtype-of.html new file mode 100644 index 000000000..1250a9a49 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/subtype-of.html @@ -0,0 +1,38 @@ + + + + subtypeOf + + +
+
+ + +
+
+
+
+
+
+ +
+

subtypeOf

+
+
+ +
+
open fun subtypeOf(bound: Type): WildcardType
+
+

Returns a type that represents an unknown type that extends {@code bound}.For example, if {@code bound} is {@code CharSequence.class}, this returns {@code ? extends CharSequence}. If {@code bound} is {@code Object.class},this returns {@code ?}, which is shorthand for {@code ? extends Object}.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/supertype-of.html b/api/-net/com.drake.net.reflect/$-gson$-types/supertype-of.html new file mode 100644 index 000000000..64b6801af --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/supertype-of.html @@ -0,0 +1,38 @@ + + + + supertypeOf + + +
+
+ + +
+
+
+
+
+
+ +
+

supertypeOf

+
+
+ +
+
open fun supertypeOf(bound: Type): WildcardType
+
+

Returns a type that represents an unknown supertype of {@code bound}. Forexample, if {@code bound} is {@code String.class}, this returns {@code ? * super String}.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/$-gson$-types/type-to-string.html b/api/-net/com.drake.net.reflect/$-gson$-types/type-to-string.html new file mode 100644 index 000000000..937583c30 --- /dev/null +++ b/api/-net/com.drake.net.reflect/$-gson$-types/type-to-string.html @@ -0,0 +1,38 @@ + + + + typeToString + + +
+
+ + +
+
+
+
+
+
+ +
+

typeToString

+
+
+ +
+
open fun typeToString(type: Type): String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/equals.html b/api/-net/com.drake.net.reflect/-type-token/equals.html new file mode 100644 index 000000000..586f98e82 --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/equals.html @@ -0,0 +1,38 @@ + + + + equals + + +
+
+ + +
+
+
+
+
+
+ +
+

equals

+
+
+ +
+
fun equals(o: Any): Boolean
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/get-array.html b/api/-net/com.drake.net.reflect/-type-token/get-array.html new file mode 100644 index 000000000..e648d984c --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/get-array.html @@ -0,0 +1,38 @@ + + + + getArray + + +
+
+ + +
+
+
+
+
+
+ +
+

getArray

+
+
+ +
+
open fun getArray(componentType: Type): TypeToken<out Any>
+
+

Gets type literal for the array type whose elements are all instances of {@code componentType}.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/get-parameterized.html b/api/-net/com.drake.net.reflect/-type-token/get-parameterized.html new file mode 100644 index 000000000..6a4354563 --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/get-parameterized.html @@ -0,0 +1,38 @@ + + + + getParameterized + + +
+
+ + +
+
+
+
+
+
+ +
+

getParameterized

+
+
+ +
+
open fun getParameterized(rawType: Type, typeArguments: Array<Type>): TypeToken<out Any>
+
+

Gets type literal for the parameterized type represented by applying {@code typeArguments} to {@code rawType}.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/get.html b/api/-net/com.drake.net.reflect/-type-token/get.html new file mode 100644 index 000000000..99ba13f62 --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/get.html @@ -0,0 +1,44 @@ + + + + get + + +
+
+ + +
+
+
+
+
+
+ +
+

get

+
+
+ +
+
open fun get(type: Type): TypeToken<out Any>
+
+

Gets type literal for the given {@code Type} instance.

+
+ +
+
open fun <T> get(type: Class<T>): TypeToken<T>
+
+

Gets type literal for the given {@code Class} instance.

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/hash-code.html b/api/-net/com.drake.net.reflect/-type-token/hash-code.html new file mode 100644 index 000000000..73ac7977a --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/hash-code.html @@ -0,0 +1,38 @@ + + + + hashCode + + +
+
+ + +
+
+
+
+
+
+ +
+

hashCode

+
+
+ +
+
fun hashCode(): Int
val hashCode: Int
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/index.html b/api/-net/com.drake.net.reflect/-type-token/index.html new file mode 100644 index 000000000..fe622fdd1 --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/index.html @@ -0,0 +1,189 @@ + + + + TypeToken + + +
+
+ + +
+
+
+
+
+
+ +
+

TypeToken

+
open class TypeToken<T>

Represents a generic type {@code T}. Java doesn't yet provide a way to represent generic types, so this class does. Forces clients to create a subclass of this class which enables retrieval the type information even at runtime.

For example, to create a type literal for {@code List}, you can create an empty anonymous inner class:

{@code TypeToken

This syntax cannot be used to create type literals that have wildcard parameters, such as {@code Class} or {@code List}.

Author

Bob Lee

Sven Mawson

Jesse Wilson

+
+
+
+
+

Functions

+
+
+
+
equals +
Link copied to clipboard
+
+
+
+ +
+
fun equals(o: Any): Boolean
+
+
+
+
+
+
+ +
+
+
get +
Link copied to clipboard
+
+
+
+ +
+
open fun <T> get(type: Class<T>): TypeToken<T>
+
+
Gets type literal for the given {@code Class} instance.
+
+ +
+
open fun get(type: Type): TypeToken<out Any>
+
+
Gets type literal for the given {@code Type} instance.
+
+
+
+
+ +
+
+
getArray +
Link copied to clipboard
+
+
+
+ +
+
open fun getArray(componentType: Type): TypeToken<out Any>
+
+
Gets type literal for the array type whose elements are all instances of {@code componentType}.
+
+
+
+
+ +
+
+
getParameterized +
Link copied to clipboard
+
+
+
+ +
+
open fun getParameterized(rawType: Type, typeArguments: Array<Type>): TypeToken<out Any>
+
+
Gets type literal for the parameterized type represented by applying {@code typeArguments} to {@code rawType}.
+
+
+
+
+ +
+
+
hashCode +
Link copied to clipboard
+
+
+
+ +
+
fun hashCode(): Int
+
+
+
+
+
+
+ +
+
+
toString +
Link copied to clipboard
+
+
+
+ +
+
fun toString(): String
+
+
+
+
+
+
+
+

Properties

+
+
+
+
hashCode +
Link copied to clipboard
+
+
+
+
val hashCode: Int
+
+
+
+
+ +
+
+
rawType +
Link copied to clipboard
+
+
+
+
val rawType: Class<out Any>
+
+
+
+
+ +
+
+
type +
Link copied to clipboard
+
+
+
+
val type: Type
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/raw-type.html b/api/-net/com.drake.net.reflect/-type-token/raw-type.html new file mode 100644 index 000000000..74c868c30 --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/raw-type.html @@ -0,0 +1,38 @@ + + + + rawType + + +
+
+ + +
+
+
+
+
+
+ +
+

rawType

+
+
+ +
+
val rawType: Class<out Any>
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/to-string.html b/api/-net/com.drake.net.reflect/-type-token/to-string.html new file mode 100644 index 000000000..331ffca22 --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/to-string.html @@ -0,0 +1,38 @@ + + + + toString + + +
+
+ + +
+
+
+
+
+
+ +
+

toString

+
+
+ +
+
fun toString(): String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/-type-token/type.html b/api/-net/com.drake.net.reflect/-type-token/type.html new file mode 100644 index 000000000..8ff96e8cd --- /dev/null +++ b/api/-net/com.drake.net.reflect/-type-token/type.html @@ -0,0 +1,38 @@ + + + + type + + +
+
+ + +
+
+
+
+
+
+ +
+

type

+
+
+ +
+
val type: Type
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/index.html b/api/-net/com.drake.net.reflect/index.html new file mode 100644 index 000000000..4cff357fc --- /dev/null +++ b/api/-net/com.drake.net.reflect/index.html @@ -0,0 +1,109 @@ + + + + com.drake.net.reflect + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.reflect

+
+
+
+
+

Types

+
+
+
+
$Gson$Preconditions +
Link copied to clipboard
+
+
+
+ +
+
class $Gson$Preconditions
+
+
A simple utility class used to check method Preconditions.
+
+
+
+
+ +
+
+
$Gson$Types +
Link copied to clipboard
+
+
+
+ +
+
class $Gson$Types
+
+
Static methods for working with types.
+
+
+
+
+ +
+
+
TypeToken +
Link copied to clipboard
+
+
+
+ +
+
open class TypeToken<T>
+
+
Represents a generic type {@code T}.
+
+
+
+
+
+

Functions

+
+
+
+
typeTokenOf +
Link copied to clipboard
+
+
+
+ +
+
inline fun <T> typeTokenOf(): Type
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.reflect/type-token-of.html b/api/-net/com.drake.net.reflect/type-token-of.html new file mode 100644 index 000000000..16c345f01 --- /dev/null +++ b/api/-net/com.drake.net.reflect/type-token-of.html @@ -0,0 +1,38 @@ + + + + typeTokenOf + + +
+
+ + +
+
+
+
+
+
+ +
+

typeTokenOf

+
+
+ +
+
inline fun <T> typeTokenOf(): Type
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/-base-request.html b/api/-net/com.drake.net.request/-base-request/-base-request.html new file mode 100644 index 000000000..42fb32ecf --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/-base-request.html @@ -0,0 +1,38 @@ + + + + BaseRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

BaseRequest

+
+
+ +
+
fun BaseRequest()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/add-download-listener.html b/api/-net/com.drake.net.request/-base-request/add-download-listener.html new file mode 100644 index 000000000..972fd18e6 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/add-download-listener.html @@ -0,0 +1,38 @@ + + + + addDownloadListener + + +
+
+ + +
+
+
+
+
+
+ +
+

addDownloadListener

+
+
+ +
+
fun addDownloadListener(progressListener: ProgressListener)
+
+

下载监听器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/add-header.html b/api/-net/com.drake.net.request/-base-request/add-header.html new file mode 100644 index 000000000..2622acbd1 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/add-header.html @@ -0,0 +1,38 @@ + + + + addHeader + + +
+
+ + +
+
+
+
+
+
+ +
+

addHeader

+
+
+ +
+
fun addHeader(name: String, value: String)
+
+

添加请求头 如果已存在相同name的请求头会添加而不会覆盖, 因为请求头本身存在多个值

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/add-query.html b/api/-net/com.drake.net.request/-base-request/add-query.html new file mode 100644 index 000000000..a74525be8 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/add-query.html @@ -0,0 +1,38 @@ + + + + addQuery + + +
+
+ + +
+
+
+
+
+
+ +
+

addQuery

+
+
+ +
+
fun addQuery(name: String, value: String?, encoded: Boolean = false)
fun addQuery(name: String, value: Number?)
fun addQuery(name: String, value: Boolean?)
+
+

添加Url上的Query参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/build-request.html b/api/-net/com.drake.net.request/-base-request/build-request.html new file mode 100644 index 000000000..e72677717 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/build-request.html @@ -0,0 +1,38 @@ + + + + buildRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

buildRequest

+
+
+ +
+
open fun buildRequest(): Request
+
+

构建请求对象Request

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/converter.html b/api/-net/com.drake.net.request/-base-request/converter.html new file mode 100644 index 000000000..2485fd1c0 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/converter.html @@ -0,0 +1,38 @@ + + + + converter + + +
+
+ + +
+
+
+
+
+
+ +
+

converter

+
+
+ +
+
open var converter: NetConverter
+
+

当前请求的数据转换器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/enqueue.html b/api/-net/com.drake.net.request/-base-request/enqueue.html new file mode 100644 index 000000000..cb163f2af --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/enqueue.html @@ -0,0 +1,38 @@ + + + + enqueue + + +
+
+ + +
+
+
+
+
+
+ +
+

enqueue

+
+
+ +
+
fun enqueue(block: Callback): Call
+
+

队列请求. 支持OkHttp的Callback函数组件

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/execute.html b/api/-net/com.drake.net.request/-base-request/execute.html new file mode 100644 index 000000000..4f20dbeda --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/execute.html @@ -0,0 +1,44 @@ + + + + execute + + +
+
+ + +
+
+
+
+
+
+ +
+

execute

+
+
+ +
+
inline fun <R> execute(): R
+
+

执行同步请求

+
+ +
+
fun <R> execute(type: Type): R
+
+

执行同步请求 本方法仅为兼容Java使用存在

Parameters

type

如果存在泛型嵌套要求使用typeTokenOf或者TypeToken获取, 否则泛型会被擦除导致无法解析

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/headers.html b/api/-net/com.drake.net.request/-base-request/headers.html new file mode 100644 index 000000000..5f679a090 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/headers.html @@ -0,0 +1,38 @@ + + + + headers + + +
+
+ + +
+
+
+
+
+
+ +
+

headers

+
+
+ +
+
fun headers(): Headers.Builder
+
+

全部请求头

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/http-url.html b/api/-net/com.drake.net.request/-base-request/http-url.html new file mode 100644 index 000000000..6f4065a0e --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/http-url.html @@ -0,0 +1,38 @@ + + + + httpUrl + + +
+
+ + +
+
+
+
+
+
+ +
+

httpUrl

+
+
+ +
+
open var httpUrl: HttpUrl.Builder
+
+

请求的Url构造器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/index.html b/api/-net/com.drake.net.request/-base-request/index.html new file mode 100644 index 000000000..87d0e0cb0 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/index.html @@ -0,0 +1,743 @@ + + + + BaseRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

BaseRequest

+
abstract class BaseRequest
+
+
+
+
+

Functions

+
+
+
+
addDownloadListener +
Link copied to clipboard
+
+
+
+ +
+
fun addDownloadListener(progressListener: ProgressListener)
+
+
下载监听器
+
+
+
+
+ +
+
+
addHeader +
Link copied to clipboard
+
+
+
+ +
+
fun addHeader(name: String, value: String)
+
+
添加请求头 如果已存在相同name的请求头会添加而不会覆盖, 因为请求头本身存在多个值
+
+
+
+
+ +
+
+
addQuery +
Link copied to clipboard
+
+
+
+ +
+
fun addQuery(name: String, value: Boolean?)
+
+
添加Url上的Query参数
+
+ +
+
fun addQuery(name: String, value: Number?)
+
+
添加Url上的Query参数
+
+ +
+
fun addQuery(name: String, value: String?, encoded: Boolean = false)
+
+
添加Url上的Query参数
+
+
+
+
+ +
+
+
buildRequest +
Link copied to clipboard
+
+
+
+ +
+
open fun buildRequest(): Request
+
+
构建请求对象Request
+
+
+
+
+ +
+
+
enqueue +
Link copied to clipboard
+
+
+
+ +
+
fun enqueue(block: Callback): Call
+
+
队列请求.
+
+
+
+
+ +
+
+
execute +
Link copied to clipboard
+
+
+
+ +
+
inline fun <R> execute(): R
+
+
执行同步请求
+
+ +
+
fun <R> execute(type: Type): R
+
+
执行同步请求 本方法仅为兼容Java使用存在
+
+
+
+
+ +
+
+
headers +
Link copied to clipboard
+
+
+
+ +
+
fun headers(): Headers.Builder
+
+
全部请求头
+
+
+
+
+ +
+
+
param +
Link copied to clipboard
+
+
+
+ +
+
abstract fun param(name: String, value: Boolean?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
abstract fun param(name: String, value: Number?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
abstract fun param(name: String, value: String?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
abstract fun param(name: String, value: String?, encoded: Boolean)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+
+
+
+ +
+
+
removeHeader +
Link copied to clipboard
+
+
+
+ +
+
fun removeHeader(name: String)
+
+
删除请求头
+
+
+
+
+ +
+
+
setCacheControl +
Link copied to clipboard
+
+
+
+ +
+
fun setCacheControl(cacheControl: CacheControl)
+
+
设置Http缓存协议头的缓存控制
+
+
+
+
+ +
+
+
setCacheKey +
Link copied to clipboard
+
+
+
+ +
+
fun setCacheKey(key: String)
+
+
自定义强制缓存使用的Key, 本方法对于Http缓存协议无效
+
+
+
+
+ +
+
+
setCacheMode +
Link copied to clipboard
+
+
+
+ +
+
fun setCacheMode(mode: CacheMode)
+
+
设置缓存模式 缓存模式将无视Http缓存协议进行强制读取/写入缓存
+
+
+
+
+ +
+
+
setCacheValidTime +
Link copied to clipboard
+
+
+
+ +
+
fun setCacheValidTime(duration: Long, unit: TimeUnit = TimeUnit.MILLISECONDS)
+
+
强制缓存有效期 注意即使缓存有效期很长也无法阻止LRU最近最少使用算法清除超出缓存最大限制标准Http缓存协议遵守协议本身的有效期, 当前方法配置无效
+
+
+
+
+ +
+
+
setClient +
Link copied to clipboard
+
+
+
+ +
+
fun setClient(block: OkHttpClient.Builder.() -> Unit)
+
+
修改当前Request的OkHttpClient配置, 不会影响全局默认的OkHttpClient
+
+
+
+
+ +
+
+
setDownloadDir +
Link copied to clipboard
+
+
+
+ +
+
fun setDownloadDir(name: File)
+
+
下载保存的目录, 也支持包含文件名称的完整路径, 如果使用完整路径则无视setDownloadFileName设置
+
+ +
+
fun setDownloadDir(name: String)
+
+
下载保存的目录, 也支持包含文件名称的完整路径, 如果使用完整路径则无视setDownloadFileName设置
+
+
+
+
+ +
+
+
setDownloadFileName +
Link copied to clipboard
+
+
+
+ +
+
fun setDownloadFileName(name: String)
+
+
下载文件名 如果setDownloadDir函数使用完整路径(包含文件名的参数)作为参数则将无视本函数设置 如果不调用本函数则默认是读取服务器返回的文件名
+
+
+
+
+ +
+
+
setDownloadFileNameConflict +
Link copied to clipboard
+
+
+
+ +
+
fun setDownloadFileNameConflict(enabled: Boolean = true)
+
+
下载文件路径存在同名文件时是创建新文件(添加序号)还是覆盖 重命名规则是: $文件名_($序号).
+
+
+
+
+ +
+
+
setDownloadFileNameDecode +
Link copied to clipboard
+
+
+
+ +
+
fun setDownloadFileNameDecode(enabled: Boolean = true)
+
+
文件名称是否使用URL解码 例如下载的文件名如果是中文, 服务器传输给你的会是被URL编码的字符串.
+
+
+
+
+ +
+
+
setDownloadMd5Verify +
Link copied to clipboard
+
+
+
+ +
+
fun setDownloadMd5Verify(enabled: Boolean = true)
+
+
下载文件MD5校验 如果服务器响应头Content-MD5值和指定路径已经存在的文件MD5相同, 则跳过下载直接返回该File
+
+
+
+
+ +
+
+
setDownloadTempFile +
Link copied to clipboard
+
+
+
+ +
+
fun setDownloadTempFile(enabled: Boolean = true)
+
+
下载是否使用临时文件 避免下载失败后覆盖同名文件或者无法判别是否已下载完整, 仅在下载完整以后才会显示为原有文件名 临时文件命名规则: 文件名 + .downloading 下载文件名: install.apk, 临时文件名: install.apk.
+
+
+
+
+ +
+
+
setExtra +
Link copied to clipboard
+
+
+
+ +
+
fun setExtra(name: String, tag: Any?)
+
+
设置额外信息
+
+
+
+
+ +
+
+
setGroup +
Link copied to clipboard
+
+
+
+ +
+
fun setGroup(group: Any?)
+
+
请求分组 Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求
+
+
+
+
+ +
+
+
setHeader +
Link copied to clipboard
+
+
+
+ +
+
fun setHeader(name: String, value: String)
+
+
设置请求头, 会覆盖请求头而不像addHeader是添加
+
+
+
+
+ +
+
+
setHeaders +
Link copied to clipboard
+
+
+
+ +
+
fun setHeaders(headers: Headers)
+
+
批量设置请求头
+
+
+
+
+ +
+
+
setId +
Link copied to clipboard
+
+
+
+ +
+
fun setId(id: Any?)
+
+
请求ID Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求
+
+
+
+
+ +
+
+
setKType +
Link copied to clipboard
+
+
+
+ +
+
inline fun <T> setKType()
+
+
为请求附着KType信息 KType属于Kotlin特有的Type, 某些Kotlin框架可能会使用到, 例如 kotlin.
+
+
+
+
+ +
+
+
setPath +
Link copied to clipboard
+
+
+
+ +
+
fun setPath(path: String?)
+
+
解析配置Path, 支持识别query参数和绝对路径
+
+
+
+
+ +
+
+
setQuery +
Link copied to clipboard
+
+
+
+ +
+
fun setQuery(name: String, value: Boolean?)
+
+
设置Url上的Query参数
+
+ +
+
fun setQuery(name: String, value: Number?)
+
+
设置Url上的Query参数
+
+ +
+
fun setQuery(name: String, value: String?, encoded: Boolean = false)
+
+
设置Url上的Query参数
+
+
+
+
+ +
+
+
setUrl +
Link copied to clipboard
+
+
+
+ +
+
open fun setUrl(url: URL)
+
+
设置Url
+
+ +
+
open fun setUrl(url: String)
+
+
设置一个Url字符串, 其参数不会和你初始化时设置的主域名NetConfig.host进行拼接 一般情况下我建议使用更为聪明的setPath
+
+ +
+
open fun setUrl(url: HttpUrl)
+
+
设置Url
+
+
+
+
+ +
+
+
tag +
Link copied to clipboard
+
+
+
+ +
+
fun tag(tag: Any?)
+
+
使用Any::class作为键名添加标签 使用Request.
+
+ +
+
fun <T> tag(type: Class<in T>, tag: T?)
+
+
使用type作为key添加标签 使用Request.
+
+
+
+
+ +
+
+
tagOf +
Link copied to clipboard
+
+
+
+ +
+
inline fun <T> tagOf(tag: T?)
+
+
添加tag 使用Request.
+
+
+
+
+ +
+
+
toResult +
Link copied to clipboard
+
+
+
+ +
+
inline fun <R> toResult(): Result<R>
+
+
执行同步请求
+
+
+
+
+
+

Properties

+
+
+
+
converter +
Link copied to clipboard
+
+
+
+
open var converter: NetConverter
当前请求的数据转换器
+
+
+
+
+ +
+
+
httpUrl +
Link copied to clipboard
+
+
+
+
open var httpUrl: HttpUrl.Builder
请求的Url构造器
+
+
+
+
+ +
+
+
method +
Link copied to clipboard
+
+
+
+
open var method: Method
请求的方法
+
+
+
+
+ +
+
+
okHttpClient +
Link copied to clipboard
+
+
+
+
open var okHttpClient: OkHttpClient
请求客户端
+
+
+
+
+ +
+
+
okHttpRequest +
Link copied to clipboard
+
+
+
+
open var okHttpRequest: Request.Builder
请求对象构造器
+
+
+
+
+
+

Inheritors

+
+
+
+
BodyRequest +
Link copied to clipboard
+
+
+
+
+ +
+
+
UrlRequest +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/method.html b/api/-net/com.drake.net.request/-base-request/method.html new file mode 100644 index 000000000..5133fedd1 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/method.html @@ -0,0 +1,38 @@ + + + + method + + +
+
+ + +
+
+
+
+
+
+ +
+

method

+
+
+ +
+
open var method: Method
+
+

请求的方法

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/ok-http-client.html b/api/-net/com.drake.net.request/-base-request/ok-http-client.html new file mode 100644 index 000000000..0c6588569 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/ok-http-client.html @@ -0,0 +1,38 @@ + + + + okHttpClient + + +
+
+ + +
+
+
+
+
+
+ +
+

okHttpClient

+
+
+ +
+
open var okHttpClient: OkHttpClient
+
+

请求客户端

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/ok-http-request.html b/api/-net/com.drake.net.request/-base-request/ok-http-request.html new file mode 100644 index 000000000..df623d4fd --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/ok-http-request.html @@ -0,0 +1,38 @@ + + + + okHttpRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

okHttpRequest

+
+
+ +
+
open var okHttpRequest: Request.Builder
+
+

请求对象构造器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/param.html b/api/-net/com.drake.net.request/-base-request/param.html new file mode 100644 index 000000000..6bc41130d --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/param.html @@ -0,0 +1,44 @@ + + + + param + + +
+
+ + +
+
+
+
+
+
+ +
+

param

+
+
+ +
+
abstract fun param(name: String, value: String?)
abstract fun param(name: String, value: Number?)
abstract fun param(name: String, value: Boolean?)
+
+

基础类型表单参数

如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数

+
+ +
+
abstract fun param(name: String, value: String?, encoded: Boolean)
+
+

基础类型表单参数

如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数

Parameters

encoded

对应OkHttp参数函数中的encoded表示当前字段参数已经编码过. 不会再被自动编码

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/remove-header.html b/api/-net/com.drake.net.request/-base-request/remove-header.html new file mode 100644 index 000000000..7e5bbc788 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/remove-header.html @@ -0,0 +1,38 @@ + + + + removeHeader + + +
+
+ + +
+
+
+
+
+
+ +
+

removeHeader

+
+
+ +
+
fun removeHeader(name: String)
+
+

删除请求头

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-cache-control.html b/api/-net/com.drake.net.request/-base-request/set-cache-control.html new file mode 100644 index 000000000..7fc72cf40 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-cache-control.html @@ -0,0 +1,38 @@ + + + + setCacheControl + + +
+
+ + +
+
+
+
+
+
+ +
+

setCacheControl

+
+
+ +
+
fun setCacheControl(cacheControl: CacheControl)
+
+

设置Http缓存协议头的缓存控制

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-cache-key.html b/api/-net/com.drake.net.request/-base-request/set-cache-key.html new file mode 100644 index 000000000..8078ea92c --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-cache-key.html @@ -0,0 +1,38 @@ + + + + setCacheKey + + +
+
+ + +
+
+
+
+
+
+ +
+

setCacheKey

+
+
+ +
+
fun setCacheKey(key: String)
+
+

自定义强制缓存使用的Key, 本方法对于Http缓存协议无效

Parameters

key

缓存的Key无论是自定义还是默认(使用RequestMethod+URL作为Key)最终都会被进行SHA1编码, 所以无需考虑特殊字符问题

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-cache-mode.html b/api/-net/com.drake.net.request/-base-request/set-cache-mode.html new file mode 100644 index 000000000..b40304a60 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-cache-mode.html @@ -0,0 +1,38 @@ + + + + setCacheMode + + +
+
+ + +
+
+
+
+
+
+ +
+

setCacheMode

+
+
+ +
+
fun setCacheMode(mode: CacheMode)
+
+

设置缓存模式 缓存模式将无视Http缓存协议进行强制读取/写入缓存

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-cache-valid-time.html b/api/-net/com.drake.net.request/-base-request/set-cache-valid-time.html new file mode 100644 index 000000000..be9f29025 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-cache-valid-time.html @@ -0,0 +1,38 @@ + + + + setCacheValidTime + + +
+
+ + +
+
+
+
+
+
+ +
+

setCacheValidTime

+
+
+ +
+
fun setCacheValidTime(duration: Long, unit: TimeUnit = TimeUnit.MILLISECONDS)
+
+

强制缓存有效期 注意即使缓存有效期很长也无法阻止LRU最近最少使用算法清除超出缓存最大限制

标准Http缓存协议遵守协议本身的有效期, 当前方法配置无效

Parameters

duration

持续时间

unit

时间单位, 默认毫秒

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-client.html b/api/-net/com.drake.net.request/-base-request/set-client.html new file mode 100644 index 000000000..920df33a0 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-client.html @@ -0,0 +1,38 @@ + + + + setClient + + +
+
+ + +
+
+
+
+
+
+ +
+

setClient

+
+
+ +
+
fun setClient(block: OkHttpClient.Builder.() -> Unit)
+
+

修改当前Request的OkHttpClient配置, 不会影响全局默认的OkHttpClient

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-download-dir.html b/api/-net/com.drake.net.request/-base-request/set-download-dir.html new file mode 100644 index 000000000..01fed71db --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-download-dir.html @@ -0,0 +1,38 @@ + + + + setDownloadDir + + +
+
+ + +
+
+
+
+
+
+ +
+

setDownloadDir

+
+
+ +
+
fun setDownloadDir(name: String)
fun setDownloadDir(name: File)
+
+

下载保存的目录, 也支持包含文件名称的完整路径, 如果使用完整路径则无视setDownloadFileName设置

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-download-file-name-conflict.html b/api/-net/com.drake.net.request/-base-request/set-download-file-name-conflict.html new file mode 100644 index 000000000..fad6cd0e7 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-download-file-name-conflict.html @@ -0,0 +1,38 @@ + + + + setDownloadFileNameConflict + + +
+
+ + +
+
+
+
+
+
+ +
+

setDownloadFileNameConflict

+
+
+ +
+
fun setDownloadFileNameConflict(enabled: Boolean = true)
+
+

下载文件路径存在同名文件时是创建新文件(添加序号)还是覆盖 重命名规则是: $文件名_($序号).$后缀, 例如file_name(1).apk

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-download-file-name-decode.html b/api/-net/com.drake.net.request/-base-request/set-download-file-name-decode.html new file mode 100644 index 000000000..b31c1ff66 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-download-file-name-decode.html @@ -0,0 +1,38 @@ + + + + setDownloadFileNameDecode + + +
+
+ + +
+
+
+
+
+
+ +
+

setDownloadFileNameDecode

+
+
+ +
+
fun setDownloadFileNameDecode(enabled: Boolean = true)
+
+

文件名称是否使用URL解码 例如下载的文件名如果是中文, 服务器传输给你的会是被URL编码的字符串. 你使用URL解码后才是可读的中文名称

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-download-file-name.html b/api/-net/com.drake.net.request/-base-request/set-download-file-name.html new file mode 100644 index 000000000..36ed8b0ad --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-download-file-name.html @@ -0,0 +1,38 @@ + + + + setDownloadFileName + + +
+
+ + +
+
+
+
+
+
+ +
+

setDownloadFileName

+
+
+ +
+
fun setDownloadFileName(name: String)
+
+

下载文件名 如果setDownloadDir函数使用完整路径(包含文件名的参数)作为参数则将无视本函数设置 如果不调用本函数则默认是读取服务器返回的文件名

See also

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-download-md5-verify.html b/api/-net/com.drake.net.request/-base-request/set-download-md5-verify.html new file mode 100644 index 000000000..2514b5e84 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-download-md5-verify.html @@ -0,0 +1,38 @@ + + + + setDownloadMd5Verify + + +
+
+ + +
+
+
+
+
+
+ +
+

setDownloadMd5Verify

+
+
+ +
+
fun setDownloadMd5Verify(enabled: Boolean = true)
+
+

下载文件MD5校验 如果服务器响应头Content-MD5值和指定路径已经存在的文件MD5相同, 则跳过下载直接返回该File

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-download-temp-file.html b/api/-net/com.drake.net.request/-base-request/set-download-temp-file.html new file mode 100644 index 000000000..09effee4b --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-download-temp-file.html @@ -0,0 +1,38 @@ + + + + setDownloadTempFile + + +
+
+ + +
+
+
+
+
+
+ +
+

setDownloadTempFile

+
+
+ +
+
fun setDownloadTempFile(enabled: Boolean = true)
+
+

下载是否使用临时文件 避免下载失败后覆盖同名文件或者无法判别是否已下载完整, 仅在下载完整以后才会显示为原有文件名 临时文件命名规则: 文件名 + .downloading 下载文件名: install.apk, 临时文件名: install.apk.downloading

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-extra.html b/api/-net/com.drake.net.request/-base-request/set-extra.html new file mode 100644 index 000000000..e24a0c069 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-extra.html @@ -0,0 +1,38 @@ + + + + setExtra + + +
+
+ + +
+
+
+
+
+
+ +
+

setExtra

+
+
+ +
+
fun setExtra(name: String, tag: Any?)
+
+

设置额外信息

See also

extra

读取

extras

全部额外信息

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-group.html b/api/-net/com.drake.net.request/-base-request/set-group.html new file mode 100644 index 000000000..833fe92a8 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-group.html @@ -0,0 +1,38 @@ + + + + setGroup + + +
+
+ + +
+
+
+
+
+
+ +
+

setGroup

+
+
+ +
+
fun setGroup(group: Any?)
+
+

请求分组 Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-header.html b/api/-net/com.drake.net.request/-base-request/set-header.html new file mode 100644 index 000000000..99b94a8fe --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-header.html @@ -0,0 +1,38 @@ + + + + setHeader + + +
+
+ + +
+
+
+
+
+
+ +
+

setHeader

+
+
+ +
+
fun setHeader(name: String, value: String)
+
+

设置请求头, 会覆盖请求头而不像addHeader是添加

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-headers.html b/api/-net/com.drake.net.request/-base-request/set-headers.html new file mode 100644 index 000000000..6fbcd930a --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-headers.html @@ -0,0 +1,38 @@ + + + + setHeaders + + +
+
+ + +
+
+
+
+
+
+ +
+

setHeaders

+
+
+ +
+
fun setHeaders(headers: Headers)
+
+

批量设置请求头

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-id.html b/api/-net/com.drake.net.request/-base-request/set-id.html new file mode 100644 index 000000000..562c1d10a --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-id.html @@ -0,0 +1,38 @@ + + + + setId + + +
+
+ + +
+
+
+
+
+
+ +
+

setId

+
+
+ +
+
fun setId(id: Any?)
+
+

请求ID Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-k-type.html b/api/-net/com.drake.net.request/-base-request/set-k-type.html new file mode 100644 index 000000000..8ccb14abb --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-k-type.html @@ -0,0 +1,38 @@ + + + + setKType + + +
+
+ + +
+
+
+
+
+
+ +
+

setKType

+
+
+ +
+
inline fun <T> setKType()
+
+

为请求附着KType信息 KType属于Kotlin特有的Type, 某些Kotlin框架可能会使用到, 例如 kotlin.serialization

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-path.html b/api/-net/com.drake.net.request/-base-request/set-path.html new file mode 100644 index 000000000..ce96cce2e --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-path.html @@ -0,0 +1,38 @@ + + + + setPath + + +
+
+ + +
+
+
+
+
+
+ +
+

setPath

+
+
+ +
+
fun setPath(path: String?)
+
+

解析配置Path, 支持识别query参数和绝对路径

Parameters

path

如果其不包含http/https则会自动拼接NetConfig.host

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-query.html b/api/-net/com.drake.net.request/-base-request/set-query.html new file mode 100644 index 000000000..5be4a326d --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-query.html @@ -0,0 +1,38 @@ + + + + setQuery + + +
+
+ + +
+
+
+
+
+
+ +
+

setQuery

+
+
+ +
+
fun setQuery(name: String, value: String?, encoded: Boolean = false)
fun setQuery(name: String, value: Number?)
fun setQuery(name: String, value: Boolean?)
+
+

设置Url上的Query参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/set-url.html b/api/-net/com.drake.net.request/-base-request/set-url.html new file mode 100644 index 000000000..e1a9b4b98 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/set-url.html @@ -0,0 +1,44 @@ + + + + setUrl + + +
+
+ + +
+
+
+
+
+
+ +
+

setUrl

+
+
+ +
+
open fun setUrl(url: String)
+
+

设置一个Url字符串, 其参数不会和你初始化时设置的主域名NetConfig.host进行拼接 一般情况下我建议使用更为聪明的setPath

+
+ +
+
open fun setUrl(url: HttpUrl)
open fun setUrl(url: URL)
+
+

设置Url

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/tag-of.html b/api/-net/com.drake.net.request/-base-request/tag-of.html new file mode 100644 index 000000000..0d4f6104a --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/tag-of.html @@ -0,0 +1,38 @@ + + + + tagOf + + +
+
+ + +
+
+
+
+
+
+ +
+

tagOf

+
+
+ +
+
inline fun <T> tagOf(tag: T?)
+
+

添加tag 使用Request.tagOf()或者Request.tag(Class)读取tag

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/tag.html b/api/-net/com.drake.net.request/-base-request/tag.html new file mode 100644 index 000000000..b0f9e2171 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/tag.html @@ -0,0 +1,44 @@ + + + + tag + + +
+
+ + +
+
+
+
+
+
+ +
+

tag

+
+
+ +
+
fun tag(tag: Any?)
+
+

使用Any::class作为键名添加标签 使用Request.tag()返回tag

+
+ +
+
fun <T> tag(type: Class<in T>, tag: T?)
+
+

使用type作为key添加标签 使用Request.tagOf()或者Request.tag(Class)读取tag

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-base-request/to-result.html b/api/-net/com.drake.net.request/-base-request/to-result.html new file mode 100644 index 000000000..7fafdf205 --- /dev/null +++ b/api/-net/com.drake.net.request/-base-request/to-result.html @@ -0,0 +1,38 @@ + + + + toResult + + +
+
+ + +
+
+
+
+
+
+ +
+

toResult

+
+
+ +
+
inline fun <R> toResult(): Result<R>
+
+

执行同步请求

Return

一个包含请求成功和错误的Result

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/-body-request.html b/api/-net/com.drake.net.request/-body-request/-body-request.html new file mode 100644 index 000000000..41c48ec72 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/-body-request.html @@ -0,0 +1,38 @@ + + + + BodyRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

BodyRequest

+
+
+ +
+
fun BodyRequest()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/add-upload-listener.html b/api/-net/com.drake.net.request/-body-request/add-upload-listener.html new file mode 100644 index 000000000..a5c78f51c --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/add-upload-listener.html @@ -0,0 +1,38 @@ + + + + addUploadListener + + +
+
+ + +
+
+
+
+
+
+ +
+

addUploadListener

+
+
+ +
+
fun addUploadListener(progressListener: ProgressListener)
+
+

添加上传进度监听器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/body.html b/api/-net/com.drake.net.request/-body-request/body.html new file mode 100644 index 000000000..efee611b3 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/body.html @@ -0,0 +1,38 @@ + + + + body + + +
+
+ + +
+
+
+
+
+
+ +
+

body

+
+
+ +
+
open var body: RequestBody? = null
+
+

请求体

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/build-request.html b/api/-net/com.drake.net.request/-body-request/build-request.html new file mode 100644 index 000000000..1102c1165 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/build-request.html @@ -0,0 +1,38 @@ + + + + buildRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

buildRequest

+
+
+ +
+
open override fun buildRequest(): Request
+
+

构建请求对象Request

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/form-body.html b/api/-net/com.drake.net.request/-body-request/form-body.html new file mode 100644 index 000000000..eba8ccd26 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/form-body.html @@ -0,0 +1,38 @@ + + + + formBody + + +
+
+ + +
+
+
+
+
+
+ +
+

formBody

+
+
+ +
+
open var formBody: FormBody.Builder
+
+

表单请求体 当你设置partBody后当前表单请求体中的所有参数都会被存放到partBody中

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/index.html b/api/-net/com.drake.net.request/-body-request/index.html new file mode 100644 index 000000000..49ad4fb65 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/index.html @@ -0,0 +1,223 @@ + + + + BodyRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

BodyRequest

+
open class BodyRequest : BaseRequest
+
+
+
+
+

Functions

+
+
+
+
addUploadListener +
Link copied to clipboard
+
+
+
+ +
+
fun addUploadListener(progressListener: ProgressListener)
+
+
添加上传进度监听器
+
+
+
+
+ +
+
+
buildRequest +
Link copied to clipboard
+
+
+
+ +
+
open override fun buildRequest(): Request
+
+
构建请求对象Request
+
+
+
+
+ +
+
+
json +
Link copied to clipboard
+
+
+
+ +
+
fun json(vararg body: Pair<String, Any?>)
+
+
添加Json对象为请求体
+
+ +
+
fun json(body: String?)
+
+
添加Json为请求体
+
+ +
+
fun json(body: Map<String, Any?>?)
+
+
添加Json为请求体
+
+ +
+
fun json(body: JSONArray?)
+
+
添加Json为请求体
+
+ +
+
fun json(body: JSONObject?)
+
+
添加Json为请求体
+
+
+
+
+ +
+
+
param +
Link copied to clipboard
+
+
+
+ +
+
fun param(body: MultipartBody.Part)
fun param(name: String, value: Uri?)
fun param(name: String, value: File?)
fun param(name: String, value: ByteArray?)
fun param(name: String, value: List<File?>?)
fun param(name: String, value: RequestBody?)
fun param(name: String, value: ByteString?)
fun param(name: String, fileName: String?, value: File?)
+
+
+
+ +
+
open override fun param(name: String, value: Boolean?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
open override fun param(name: String, value: Number?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
open override fun param(name: String, value: String?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
open override fun param(name: String, value: String?, encoded: Boolean)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+
+
+
+
+

Properties

+
+
+
+
body +
Link copied to clipboard
+
+
+
+
open var body: RequestBody? = null
请求体
+
+
+
+
+ +
+
+
formBody +
Link copied to clipboard
+
+
+
+
open var formBody: FormBody.Builder
表单请求体 当你设置partBody后当前表单请求体中的所有参数都会被存放到partBody中
+
+
+
+
+ +
+
+
mediaType +
Link copied to clipboard
+
+
+
+
open var mediaType: MediaType
multipart请求体的媒体类型
+
+
+
+
+ +
+
+
method +
Link copied to clipboard
+
+
+
+
open override var method: Method
请求方法
+
+
+
+
+ +
+
+
partBody +
Link copied to clipboard
+
+
+
+
open var partBody: MultipartBody.Builder
multipart请求体 主要存放文件/IO流
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/json.html b/api/-net/com.drake.net.request/-body-request/json.html new file mode 100644 index 000000000..b90be8173 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/json.html @@ -0,0 +1,44 @@ + + + + json + + +
+
+ + +
+
+
+
+
+
+ +
+

json

+
+
+ +
+
fun json(body: JSONObject?)
fun json(body: JSONArray?)
fun json(body: String?)
fun json(body: Map<String, Any?>?)
+
+

添加Json为请求体

+
+ +
+
fun json(vararg body: Pair<String, Any?>)
+
+

添加Json对象为请求体

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/media-type.html b/api/-net/com.drake.net.request/-body-request/media-type.html new file mode 100644 index 000000000..d5d1fb60e --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/media-type.html @@ -0,0 +1,38 @@ + + + + mediaType + + +
+
+ + +
+
+
+
+
+
+ +
+

mediaType

+
+
+ +
+
open var mediaType: MediaType
+
+

multipart请求体的媒体类型

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/method.html b/api/-net/com.drake.net.request/-body-request/method.html new file mode 100644 index 000000000..18e7809db --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/method.html @@ -0,0 +1,38 @@ + + + + method + + +
+
+ + +
+
+
+
+
+
+ +
+

method

+
+
+ +
+
open override var method: Method
+
+

请求方法

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/param.html b/api/-net/com.drake.net.request/-body-request/param.html new file mode 100644 index 000000000..389079aa3 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/param.html @@ -0,0 +1,50 @@ + + + + param + + +
+
+ + +
+
+
+
+
+
+ +
+

param

+
+
+ +
+
open override fun param(name: String, value: String?)
open override fun param(name: String, value: Number?)
open override fun param(name: String, value: Boolean?)
+
+

基础类型表单参数

如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数

+
+ +
+
open override fun param(name: String, value: String?, encoded: Boolean)
+
+

基础类型表单参数

如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数

Parameters

encoded

对应OkHttp参数函数中的encoded表示当前字段参数已经编码过. 不会再被自动编码

+
+ +
+
fun param(name: String, value: RequestBody?)
fun param(name: String, value: ByteString?)
fun param(name: String, value: ByteArray?)
fun param(name: String, value: Uri?)
fun param(name: String, value: File?)
fun param(name: String, value: List<File?>?)
fun param(name: String, fileName: String?, value: File?)
fun param(body: MultipartBody.Part)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-body-request/part-body.html b/api/-net/com.drake.net.request/-body-request/part-body.html new file mode 100644 index 000000000..d5245f187 --- /dev/null +++ b/api/-net/com.drake.net.request/-body-request/part-body.html @@ -0,0 +1,38 @@ + + + + partBody + + +
+
+ + +
+
+
+
+
+
+ +
+

partBody

+
+
+ +
+
open var partBody: MultipartBody.Builder
+
+

multipart请求体 主要存放文件/IO流

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-f-o-r-m.html b/api/-net/com.drake.net.request/-media-const/-f-o-r-m.html new file mode 100644 index 000000000..049e02332 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-f-o-r-m.html @@ -0,0 +1,38 @@ + + + + FORM + + +
+
+ + +
+
+
+
+
+
+ +
+

FORM

+
+
+ +
+
val FORM: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-g-i-f.html b/api/-net/com.drake.net.request/-media-const/-g-i-f.html new file mode 100644 index 000000000..9e55d16cf --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-g-i-f.html @@ -0,0 +1,38 @@ + + + + GIF + + +
+
+ + +
+
+
+
+
+
+ +
+

GIF

+
+
+ +
+
val GIF: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-h-t-m-l.html b/api/-net/com.drake.net.request/-media-const/-h-t-m-l.html new file mode 100644 index 000000000..88987dfa5 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-h-t-m-l.html @@ -0,0 +1,38 @@ + + + + HTML + + +
+
+ + +
+
+
+
+
+
+ +
+

HTML

+
+
+ +
+
val HTML: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-i-m-g.html b/api/-net/com.drake.net.request/-media-const/-i-m-g.html new file mode 100644 index 000000000..e294a7336 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-i-m-g.html @@ -0,0 +1,38 @@ + + + + IMG + + +
+
+ + +
+
+
+
+
+
+ +
+

IMG

+
+
+ +
+
val IMG: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-j-p-e-g.html b/api/-net/com.drake.net.request/-media-const/-j-p-e-g.html new file mode 100644 index 000000000..41df3052c --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-j-p-e-g.html @@ -0,0 +1,38 @@ + + + + JPEG + + +
+
+ + +
+
+
+
+
+
+ +
+

JPEG

+
+
+ +
+
val JPEG: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-j-s-o-n.html b/api/-net/com.drake.net.request/-media-const/-j-s-o-n.html new file mode 100644 index 000000000..aac8ae22d --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-j-s-o-n.html @@ -0,0 +1,38 @@ + + + + JSON + + +
+
+ + +
+
+
+
+
+
+ +
+

JSON

+
+
+ +
+
val JSON: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-m-p4.html b/api/-net/com.drake.net.request/-media-const/-m-p4.html new file mode 100644 index 000000000..78fd8ad4d --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-m-p4.html @@ -0,0 +1,38 @@ + + + + MP4 + + +
+
+ + +
+
+
+
+
+
+ +
+

MP4

+
+
+ +
+
val MP4: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-o-c-t-e-t_-s-t-r-e-a-m.html b/api/-net/com.drake.net.request/-media-const/-o-c-t-e-t_-s-t-r-e-a-m.html new file mode 100644 index 000000000..9336be5ce --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-o-c-t-e-t_-s-t-r-e-a-m.html @@ -0,0 +1,38 @@ + + + + OCTET_STREAM + + +
+
+ + +
+
+
+
+
+
+ +
+

OCTET_STREAM

+
+
+ +
+
val OCTET_STREAM: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-p-n-g.html b/api/-net/com.drake.net.request/-media-const/-p-n-g.html new file mode 100644 index 000000000..5a727a978 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-p-n-g.html @@ -0,0 +1,38 @@ + + + + PNG + + +
+
+ + +
+
+
+
+
+
+ +
+

PNG

+
+
+ +
+
val PNG: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-t-x-t.html b/api/-net/com.drake.net.request/-media-const/-t-x-t.html new file mode 100644 index 000000000..bd7ed8d83 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-t-x-t.html @@ -0,0 +1,38 @@ + + + + TXT + + +
+
+ + +
+
+
+
+
+
+ +
+

TXT

+
+
+ +
+
val TXT: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-u-r-l-e-n-c-o-d-e-d.html b/api/-net/com.drake.net.request/-media-const/-u-r-l-e-n-c-o-d-e-d.html new file mode 100644 index 000000000..bd6f61bb4 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-u-r-l-e-n-c-o-d-e-d.html @@ -0,0 +1,38 @@ + + + + URLENCODED + + +
+
+ + +
+
+
+
+
+
+ +
+

URLENCODED

+
+
+ +
+
val URLENCODED: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/-x-m-l.html b/api/-net/com.drake.net.request/-media-const/-x-m-l.html new file mode 100644 index 000000000..5cb548490 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/-x-m-l.html @@ -0,0 +1,38 @@ + + + + XML + + +
+
+ + +
+
+
+
+
+
+ +
+

XML

+
+
+ +
+
val XML: MediaType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-media-const/index.html b/api/-net/com.drake.net.request/-media-const/index.html new file mode 100644 index 000000000..8e5178088 --- /dev/null +++ b/api/-net/com.drake.net.request/-media-const/index.html @@ -0,0 +1,196 @@ + + + + MediaConst + + +
+
+ + +
+
+
+
+
+
+ +
+

MediaConst

+
object MediaConst
+
+
+
+
+

Properties

+
+
+
+
FORM +
Link copied to clipboard
+
+
+
+
val FORM: MediaType
+
+
+
+
+ +
+
+
GIF +
Link copied to clipboard
+
+
+
+
val GIF: MediaType
+
+
+
+
+ +
+
+
HTML +
Link copied to clipboard
+
+
+
+
val HTML: MediaType
+
+
+
+
+ +
+
+
IMG +
Link copied to clipboard
+
+
+
+
val IMG: MediaType
+
+
+
+
+ +
+
+
JPEG +
Link copied to clipboard
+
+
+
+
val JPEG: MediaType
+
+
+
+
+ +
+
+
JSON +
Link copied to clipboard
+
+
+
+
val JSON: MediaType
+
+
+
+
+ +
+
+
MP4 +
Link copied to clipboard
+
+
+
+
val MP4: MediaType
+
+
+
+
+ +
+
+
OCTET_STREAM +
Link copied to clipboard
+
+
+
+
val OCTET_STREAM: MediaType
+
+
+
+
+ +
+
+
PNG +
Link copied to clipboard
+
+
+
+
val PNG: MediaType
+
+
+
+
+ +
+
+
TXT +
Link copied to clipboard
+
+
+
+
val TXT: MediaType
+
+
+
+
+ +
+
+
URLENCODED +
Link copied to clipboard
+
+
+
+
val URLENCODED: MediaType
+
+
+
+
+ +
+
+
XML +
Link copied to clipboard
+
+
+
+
val XML: MediaType
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-d-e-l-e-t-e/index.html b/api/-net/com.drake.net.request/-method/-d-e-l-e-t-e/index.html new file mode 100644 index 000000000..403de311a --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-d-e-l-e-t-e/index.html @@ -0,0 +1,37 @@ + + + + DELETE + + +
+
+ + +
+
+
+
+
+
+ +
+

DELETE

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-g-e-t/index.html b/api/-net/com.drake.net.request/-method/-g-e-t/index.html new file mode 100644 index 000000000..04fb9bb53 --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-g-e-t/index.html @@ -0,0 +1,37 @@ + + + + GET + + +
+
+ + +
+
+
+
+
+
+ +
+

GET

+
GET()
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-h-e-a-d/index.html b/api/-net/com.drake.net.request/-method/-h-e-a-d/index.html new file mode 100644 index 000000000..c3bd5f21d --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-h-e-a-d/index.html @@ -0,0 +1,37 @@ + + + + HEAD + + +
+
+ + +
+
+
+
+
+
+ +
+

HEAD

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-o-p-t-i-o-n-s/index.html b/api/-net/com.drake.net.request/-method/-o-p-t-i-o-n-s/index.html new file mode 100644 index 000000000..701d60348 --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-o-p-t-i-o-n-s/index.html @@ -0,0 +1,37 @@ + + + + OPTIONS + + +
+
+ + +
+
+
+
+
+
+ +
+

OPTIONS

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-p-a-t-c-h/index.html b/api/-net/com.drake.net.request/-method/-p-a-t-c-h/index.html new file mode 100644 index 000000000..7be94d87c --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-p-a-t-c-h/index.html @@ -0,0 +1,37 @@ + + + + PATCH + + +
+
+ + +
+
+
+
+
+
+ +
+

PATCH

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-p-o-s-t/index.html b/api/-net/com.drake.net.request/-method/-p-o-s-t/index.html new file mode 100644 index 000000000..1d52066ba --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-p-o-s-t/index.html @@ -0,0 +1,37 @@ + + + + POST + + +
+
+ + +
+
+
+
+
+
+ +
+

POST

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-p-u-t/index.html b/api/-net/com.drake.net.request/-method/-p-u-t/index.html new file mode 100644 index 000000000..3d1508493 --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-p-u-t/index.html @@ -0,0 +1,37 @@ + + + + PUT + + +
+
+ + +
+
+
+
+
+
+ +
+

PUT

+
PUT()
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/-t-r-a-c-e/index.html b/api/-net/com.drake.net.request/-method/-t-r-a-c-e/index.html new file mode 100644 index 000000000..c9b7b1c0f --- /dev/null +++ b/api/-net/com.drake.net.request/-method/-t-r-a-c-e/index.html @@ -0,0 +1,37 @@ + + + + TRACE + + +
+
+ + +
+
+
+
+
+
+ +
+

TRACE

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-method/index.html b/api/-net/com.drake.net.request/-method/index.html new file mode 100644 index 000000000..27b78b0ce --- /dev/null +++ b/api/-net/com.drake.net.request/-method/index.html @@ -0,0 +1,144 @@ + + + + Method + + +
+
+ + +
+
+
+
+
+
+ +
+

Method

+
enum Method : Enum<Method>
+
+
+
+
+

Entries

+
+
+
+
PATCH +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
PUT +
Link copied to clipboard
+
+
+
+
PUT()
+
+
+
+
+ +
+
+
DELETE +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
POST +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
TRACE +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
OPTIONS +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
HEAD +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
GET +
Link copied to clipboard
+
+
+
+
GET()
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-url-request/-url-request.html b/api/-net/com.drake.net.request/-url-request/-url-request.html new file mode 100644 index 000000000..adceadb4a --- /dev/null +++ b/api/-net/com.drake.net.request/-url-request/-url-request.html @@ -0,0 +1,38 @@ + + + + UrlRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

UrlRequest

+
+
+ +
+
fun UrlRequest()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-url-request/index.html b/api/-net/com.drake.net.request/-url-request/index.html new file mode 100644 index 000000000..e9a97d6bb --- /dev/null +++ b/api/-net/com.drake.net.request/-url-request/index.html @@ -0,0 +1,75 @@ + + + + UrlRequest + + +
+
+ + +
+
+
+
+
+
+ +
+

UrlRequest

+
open class UrlRequest : BaseRequest
+
+
+
+
+

Functions

+
+
+
+
param +
Link copied to clipboard
+
+
+
+ +
+
open override fun param(name: String, value: Boolean?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
open override fun param(name: String, value: Number?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
open override fun param(name: String, value: String?)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+ +
+
open override fun param(name: String, value: String?, encoded: Boolean)
+
+
基础类型表单参数如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/-url-request/param.html b/api/-net/com.drake.net.request/-url-request/param.html new file mode 100644 index 000000000..5fdd8e3d4 --- /dev/null +++ b/api/-net/com.drake.net.request/-url-request/param.html @@ -0,0 +1,44 @@ + + + + param + + +
+
+ + +
+
+
+
+
+
+ +
+

param

+
+
+ +
+
open override fun param(name: String, value: String?)
open override fun param(name: String, value: Number?)
open override fun param(name: String, value: Boolean?)
+
+

基础类型表单参数

如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数

+
+ +
+
open override fun param(name: String, value: String?, encoded: Boolean)
+
+

基础类型表单参数

如果当前请求为Url请求则为Query参数 如果当前请求为表单请求则为表单参数 如果当前为Multipart包含流/文件的请求则为multipart参数

Parameters

encoded

对应OkHttp参数函数中的encoded表示当前字段参数已经编码过. 不会再被自动编码

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/converter.html b/api/-net/com.drake.net.request/converter.html new file mode 100644 index 000000000..f962e045e --- /dev/null +++ b/api/-net/com.drake.net.request/converter.html @@ -0,0 +1,38 @@ + + + + converter + + +
+
+ + +
+
+
+
+
+
+ +
+

converter

+
+
+ +
+
fun Request.converter(): NetConverter
+
+

返回请求包含的转换器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/download-conflict-rename.html b/api/-net/com.drake.net.request/download-conflict-rename.html new file mode 100644 index 000000000..b416b3558 --- /dev/null +++ b/api/-net/com.drake.net.request/download-conflict-rename.html @@ -0,0 +1,38 @@ + + + + downloadConflictRename + + +
+
+ + +
+
+
+
+
+
+ +
+

downloadConflictRename

+
+
+ +
+
fun Request.downloadConflictRename(): Boolean
+
+

下载文件路径存在同名文件时是覆盖或创建新文件(添加序号) 重命名规则是: $文件名_($序号).$后缀, 例如file_name(1).apk

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/download-file-dir.html b/api/-net/com.drake.net.request/download-file-dir.html new file mode 100644 index 000000000..0e7060d4a --- /dev/null +++ b/api/-net/com.drake.net.request/download-file-dir.html @@ -0,0 +1,38 @@ + + + + downloadFileDir + + +
+
+ + +
+
+
+
+
+
+ +
+

downloadFileDir

+
+
+ +
+
fun Request.downloadFileDir(): String
+
+

下载文件目录

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/download-file-name-decode.html b/api/-net/com.drake.net.request/download-file-name-decode.html new file mode 100644 index 000000000..dd33a8e76 --- /dev/null +++ b/api/-net/com.drake.net.request/download-file-name-decode.html @@ -0,0 +1,38 @@ + + + + downloadFileNameDecode + + +
+
+ + +
+
+
+
+
+
+ +
+

downloadFileNameDecode

+
+
+ +
+
fun Request.downloadFileNameDecode(): Boolean
+
+

下载的文件名称是否解码 例如下载的文件名如果是中文, 服务器传输给你的会是被URL编码的字符串. 你使用URL解码后才是可读的中文名称

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/download-file-name.html b/api/-net/com.drake.net.request/download-file-name.html new file mode 100644 index 000000000..eba87d37c --- /dev/null +++ b/api/-net/com.drake.net.request/download-file-name.html @@ -0,0 +1,38 @@ + + + + downloadFileName + + +
+
+ + +
+
+
+
+
+
+ +
+

downloadFileName

+
+
+ +
+
fun Request.downloadFileName(): String?
+
+

下载文件名

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/download-listeners.html b/api/-net/com.drake.net.request/download-listeners.html new file mode 100644 index 000000000..e7c24c99e --- /dev/null +++ b/api/-net/com.drake.net.request/download-listeners.html @@ -0,0 +1,38 @@ + + + + downloadListeners + + +
+
+ + +
+
+
+
+
+
+ +
+

downloadListeners

+
+
+ +
+
fun Request.Builder.downloadListeners(): ConcurrentLinkedQueue<ProgressListener>
fun Request.downloadListeners(): ConcurrentLinkedQueue<ProgressListener>
+
+

全部的下载监听器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/download-md5-verify.html b/api/-net/com.drake.net.request/download-md5-verify.html new file mode 100644 index 000000000..4c0ca9017 --- /dev/null +++ b/api/-net/com.drake.net.request/download-md5-verify.html @@ -0,0 +1,38 @@ + + + + downloadMd5Verify + + +
+
+ + +
+
+
+
+
+
+ +
+

downloadMd5Verify

+
+
+ +
+
fun Request.downloadMd5Verify(): Boolean
+
+

下载文件MD5校验 如果服务器响应头Content-MD5值和指定路径已经存在的文件MD5相同, 则跳过下载直接返回该File

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/download-temp-file.html b/api/-net/com.drake.net.request/download-temp-file.html new file mode 100644 index 000000000..b94225c43 --- /dev/null +++ b/api/-net/com.drake.net.request/download-temp-file.html @@ -0,0 +1,38 @@ + + + + downloadTempFile + + +
+
+ + +
+
+
+
+
+
+ +
+

downloadTempFile

+
+
+ +
+
fun Request.downloadTempFile(): Boolean
+
+

下载是否使用临时文件 避免下载失败后覆盖同名文件或者无法判别是否已下载完整, 仅在下载完整以后才会显示为原有文件名 临时文件命名规则: 文件名 + .downloading 下载文件名: install.apk, 临时文件名: install.apk.downloading

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/extra.html b/api/-net/com.drake.net.request/extra.html new file mode 100644 index 000000000..1d3ff0f5b --- /dev/null +++ b/api/-net/com.drake.net.request/extra.html @@ -0,0 +1,38 @@ + + + + extra + + +
+
+ + +
+
+
+
+
+
+ +
+

extra

+
+
+ +
+
fun Request.extra(name: String): Any?
+
+

读取额外信息

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/extras.html b/api/-net/com.drake.net.request/extras.html new file mode 100644 index 000000000..e8b4efd26 --- /dev/null +++ b/api/-net/com.drake.net.request/extras.html @@ -0,0 +1,38 @@ + + + + extras + + +
+
+ + +
+
+
+
+
+
+ +
+

extras

+
+
+ +
+
fun Request.Builder.extras(): <ERROR CLASS><String, Any?>
fun Request.extras(): <ERROR CLASS><String, Any?>
+
+

全部额外信息

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/group.html b/api/-net/com.drake.net.request/group.html new file mode 100644 index 000000000..7bbd0387e --- /dev/null +++ b/api/-net/com.drake.net.request/group.html @@ -0,0 +1,38 @@ + + + + group + + +
+
+ + +
+
+
+
+
+
+ +
+

group

+
+
+ +
+
var Request.Builder.group: Any?
var Request.group: Any?
+
+

请求分组 Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/headers.html b/api/-net/com.drake.net.request/headers.html new file mode 100644 index 000000000..c5a0a3b55 --- /dev/null +++ b/api/-net/com.drake.net.request/headers.html @@ -0,0 +1,38 @@ + + + + headers + + +
+
+ + +
+
+
+
+
+
+ +
+

headers

+
+
+ +
+
fun Request.Builder.headers(): Headers.Builder
+
+

全部的请求头

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/id.html b/api/-net/com.drake.net.request/id.html new file mode 100644 index 000000000..79b89ef56 --- /dev/null +++ b/api/-net/com.drake.net.request/id.html @@ -0,0 +1,38 @@ + + + + id + + +
+
+ + +
+
+
+
+
+
+ +
+

id

+
+
+ +
+
var Request.Builder.id: Any?
var Request.id: Any?
+
+

请求Id Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/index.html b/api/-net/com.drake.net.request/index.html new file mode 100644 index 000000000..bcbe9ed15 --- /dev/null +++ b/api/-net/com.drake.net.request/index.html @@ -0,0 +1,520 @@ + + + + com.drake.net.request + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.request

+
+
+
+
+

Types

+
+
+
+
BaseRequest +
Link copied to clipboard
+
+
+
+ +
+
abstract class BaseRequest
+
+
+
+
+
+
+ +
+
+
BodyRequest +
Link copied to clipboard
+
+
+
+ +
+
open class BodyRequest : BaseRequest
+
+
+
+
+
+
+ +
+
+
MediaConst +
Link copied to clipboard
+
+
+
+ +
+
object MediaConst
+
+
+
+
+
+
+ +
+
+
Method +
Link copied to clipboard
+
+
+
+ +
+
enum Method : Enum<Method>
+
+
+
+
+
+
+ +
+
+
UrlRequest +
Link copied to clipboard
+
+
+
+ +
+
open class UrlRequest : BaseRequest
+
+
+
+
+
+
+
+

Functions

+
+
+
+
converter +
Link copied to clipboard
+
+
+
+ +
+
fun Request.converter(): NetConverter
+
+
返回请求包含的转换器
+
+
+
+
+ +
+
+
downloadConflictRename +
Link copied to clipboard
+
+
+
+ +
+
fun Request.downloadConflictRename(): Boolean
+
+
下载文件路径存在同名文件时是覆盖或创建新文件(添加序号) 重命名规则是: $文件名_($序号).
+
+
+
+
+ +
+
+
downloadFileDir +
Link copied to clipboard
+
+
+
+ +
+
fun Request.downloadFileDir(): String
+
+
下载文件目录
+
+
+
+
+ +
+
+
downloadFileName +
Link copied to clipboard
+
+
+
+ +
+
fun Request.downloadFileName(): String?
+
+
下载文件名
+
+
+
+
+ +
+
+
downloadFileNameDecode +
Link copied to clipboard
+
+
+
+ +
+
fun Request.downloadFileNameDecode(): Boolean
+
+
下载的文件名称是否解码 例如下载的文件名如果是中文, 服务器传输给你的会是被URL编码的字符串.
+
+
+
+
+ +
+
+
downloadListeners +
Link copied to clipboard
+
+
+
+ +
+
fun Request.downloadListeners(): ConcurrentLinkedQueue<ProgressListener>
+
+
全部的下载监听器
+
+ +
+
fun Request.Builder.downloadListeners(): ConcurrentLinkedQueue<ProgressListener>
+
+
全部的下载监听器
+
+
+
+
+ +
+
+
downloadMd5Verify +
Link copied to clipboard
+
+
+
+ +
+
fun Request.downloadMd5Verify(): Boolean
+
+
下载文件MD5校验 如果服务器响应头Content-MD5值和指定路径已经存在的文件MD5相同, 则跳过下载直接返回该File
+
+
+
+
+ +
+
+
downloadTempFile +
Link copied to clipboard
+
+
+
+ +
+
fun Request.downloadTempFile(): Boolean
+
+
下载是否使用临时文件 避免下载失败后覆盖同名文件或者无法判别是否已下载完整, 仅在下载完整以后才会显示为原有文件名 临时文件命名规则: 文件名 + .downloading 下载文件名: install.apk, 临时文件名: install.apk.
+
+
+
+
+ +
+
+
extra +
Link copied to clipboard
+
+
+
+ +
+
fun Request.extra(name: String): Any?
+
+
读取额外信息
+
+
+
+
+ +
+
+
extras +
Link copied to clipboard
+
+
+
+ +
+
fun Request.extras(): <ERROR CLASS><String, Any?>
+
+
全部额外信息
+
+ +
+
fun Request.Builder.extras(): <ERROR CLASS><String, Any?>
+
+
全部额外信息
+
+
+
+
+ +
+
+
headers +
Link copied to clipboard
+
+
+
+ +
+
fun Request.Builder.headers(): Headers.Builder
+
+
全部的请求头
+
+
+
+
+ +
+
+
setConverter +
Link copied to clipboard
+
+
+
+ +
+
fun Request.Builder.setConverter(converter: NetConverter): <ERROR CLASS>
+
+
设置转换器
+
+
+
+
+ +
+
+
setExtra +
Link copied to clipboard
+
+
+
+ +
+
fun Request.Builder.setExtra(name: String, value: Any?): <ERROR CLASS>
+
+
设置额外信息
+
+
+
+
+ +
+
+
tagOf +
Link copied to clipboard
+
+
+
+ +
+
inline fun <T> Request.tagOf(): T?
+
+
读取OkHttp的tag(通过Class区分的tag)
+
+ +
+
inline fun <T> Request.Builder.tagOf(): T?
+
+
读取OkHttp的tag(通过Class区分的tag)
+
+ +
+
inline fun <T> Request.tagOf(value: T?): <ERROR CLASS>
+
+
设置OkHttp的tag(通过Class区分的tag)
+
+ +
+
inline fun <T> Request.Builder.tagOf(value: T?): <ERROR CLASS>
+
+
设置OkHttp的tag(通过Class区分的tag)
+
+
+
+
+ +
+
+
tags +
Link copied to clipboard
+
+
+
+ +
+
fun Request.tags(): MutableMap<Class<*>, Any?>
+
+
全部tag
+
+ +
+
fun Request.Builder.tags(): MutableMap<Class<*>, Any?>
+
+
全部tag
+
+
+
+
+ +
+
+
uploadListeners +
Link copied to clipboard
+
+
+
+ +
+
fun Request.uploadListeners(): ConcurrentLinkedQueue<ProgressListener>
+
+
全部的上传监听器
+
+ +
+
fun Request.Builder.uploadListeners(): ConcurrentLinkedQueue<ProgressListener>
+
+
全部的上传监听器
+
+
+
+
+
+

Properties

+
+
+
+
group +
Link copied to clipboard
+
+
+
+
var Request.Builder.group: Any?
请求分组 Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求
+
+
+
+
+ +
+
+
group +
Link copied to clipboard
+
+
+
+
var Request.group: Any?
请求分组 Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求
+
+
+
+
+ +
+
+
id +
Link copied to clipboard
+
+
+
+
var Request.Builder.id: Any?
请求Id Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求
+
+
+
+
+ +
+
+
id +
Link copied to clipboard
+
+
+
+
var Request.id: Any?
请求Id Group和Id在使用场景上有所区别, 预期上Group允许重复赋值给多个请求, Id仅允许赋值给一个请求, 但实际上都允许重复赋值 在作用域中发起请求时会默认使用协程错误处理器作为Group: setGroup(coroutineContext[CoroutineExceptionHandler]) 如果你覆盖Group会导致协程结束不会自动取消请求
+
+
+
+
+ +
+
+
kType +
Link copied to clipboard
+
+
+
+
var Request.Builder.kType: KType?
为请求附着KType信息 KType属于Kotlin特有的Type, 某些Kotlin框架可能会使用到, 例如 kotlin.
+
+
+
+
+ +
+
+
kType +
Link copied to clipboard
+
+
+
+
var Request.kType: KType?
为请求附着KType信息 KType属于Kotlin特有的Type, 某些Kotlin框架可能会使用到, 例如 kotlin.
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/k-type.html b/api/-net/com.drake.net.request/k-type.html new file mode 100644 index 000000000..6fa509102 --- /dev/null +++ b/api/-net/com.drake.net.request/k-type.html @@ -0,0 +1,38 @@ + + + + kType + + +
+
+ + +
+
+
+
+
+
+ +
+

kType

+
+
+ +
+
var Request.Builder.kType: KType?
var Request.kType: KType?
+
+

为请求附着KType信息 KType属于Kotlin特有的Type, 某些Kotlin框架可能会使用到, 例如 kotlin.serialization

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/set-converter.html b/api/-net/com.drake.net.request/set-converter.html new file mode 100644 index 000000000..5a1b24002 --- /dev/null +++ b/api/-net/com.drake.net.request/set-converter.html @@ -0,0 +1,38 @@ + + + + setConverter + + +
+
+ + +
+
+
+
+
+
+ +
+

setConverter

+
+
+ +
+
fun Request.Builder.setConverter(converter: NetConverter): <ERROR CLASS>
+
+

设置转换器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/set-extra.html b/api/-net/com.drake.net.request/set-extra.html new file mode 100644 index 000000000..2bcbf0e63 --- /dev/null +++ b/api/-net/com.drake.net.request/set-extra.html @@ -0,0 +1,38 @@ + + + + setExtra + + +
+
+ + +
+
+
+
+
+
+ +
+

setExtra

+
+
+ +
+
fun Request.Builder.setExtra(name: String, value: Any?): <ERROR CLASS>
+
+

设置额外信息

See also

extra

读取

extras

全部额外信息

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/tag-of.html b/api/-net/com.drake.net.request/tag-of.html new file mode 100644 index 000000000..53e81d49f --- /dev/null +++ b/api/-net/com.drake.net.request/tag-of.html @@ -0,0 +1,44 @@ + + + + tagOf + + +
+
+ + +
+
+
+
+
+
+ +
+

tagOf

+
+
+ +
+
inline fun <T> Request.Builder.tagOf(): T?
inline fun <T> Request.tagOf(): T?
+
+

读取OkHttp的tag(通过Class区分的tag)

+
+ +
+
inline fun <T> Request.Builder.tagOf(value: T?): <ERROR CLASS>
inline fun <T> Request.tagOf(value: T?): <ERROR CLASS>
+
+

设置OkHttp的tag(通过Class区分的tag)

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/tags.html b/api/-net/com.drake.net.request/tags.html new file mode 100644 index 000000000..5cfce1668 --- /dev/null +++ b/api/-net/com.drake.net.request/tags.html @@ -0,0 +1,38 @@ + + + + tags + + +
+
+ + +
+
+
+
+
+
+ +
+

tags

+
+
+ +
+
fun Request.Builder.tags(): MutableMap<Class<*>, Any?>
fun Request.tags(): MutableMap<Class<*>, Any?>
+
+

全部tag

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.request/upload-listeners.html b/api/-net/com.drake.net.request/upload-listeners.html new file mode 100644 index 000000000..4b662d61c --- /dev/null +++ b/api/-net/com.drake.net.request/upload-listeners.html @@ -0,0 +1,38 @@ + + + + uploadListeners + + +
+
+ + +
+
+
+
+
+
+ +
+

uploadListeners

+
+
+ +
+
fun Request.Builder.uploadListeners(): ConcurrentLinkedQueue<ProgressListener>
fun Request.uploadListeners(): ConcurrentLinkedQueue<ProgressListener>
+
+

全部的上传监听器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.response/convert.html b/api/-net/com.drake.net.response/convert.html new file mode 100644 index 000000000..527d7fda1 --- /dev/null +++ b/api/-net/com.drake.net.response/convert.html @@ -0,0 +1,44 @@ + + + + convert + + +
+
+ + +
+
+
+
+
+
+ +
+

convert

+
+
+ +
+
inline fun <R> Response.convert(): R
+
+

响应体使用转换器处理数据

+
+ +
+
fun <R> Response.convert(type: Type): R
+
+

响应体使用转换器处理数据 本方法仅为兼容Java使用存在

Parameters

type

如果存在泛型嵌套要求使用typeTokenOf或者TypeToken获取, 否则泛型会被擦除导致无法解析

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.response/file-name.html b/api/-net/com.drake.net.response/file-name.html new file mode 100644 index 000000000..bf3e87e0d --- /dev/null +++ b/api/-net/com.drake.net.response/file-name.html @@ -0,0 +1,38 @@ + + + + fileName + + +
+
+ + +
+
+
+
+
+
+ +
+

fileName

+
+
+ +
+
fun Response.fileName(): String
+
+

按照以下顺序返回最终的下载文件的名称

  1. 指定文件名

  2. 响应头文件名

  3. 请求URL路径

  4. 时间戳

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.response/file.html b/api/-net/com.drake.net.response/file.html new file mode 100644 index 000000000..76ef2783a --- /dev/null +++ b/api/-net/com.drake.net.response/file.html @@ -0,0 +1,38 @@ + + + + file + + +
+
+ + +
+
+
+
+
+
+ +
+

file

+
+
+ +
+
fun Response.file(): File?
+
+

下载到指定文件

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.response/index.html b/api/-net/com.drake.net.response/index.html new file mode 100644 index 000000000..5f4c515eb --- /dev/null +++ b/api/-net/com.drake.net.response/index.html @@ -0,0 +1,96 @@ + + + + com.drake.net.response + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.response

+
+
+
+
+

Functions

+
+
+
+
convert +
Link copied to clipboard
+
+
+
+ +
+
inline fun <R> Response.convert(): R
+
+
响应体使用转换器处理数据
+
+ +
+
fun <R> Response.convert(type: Type): R
+
+
响应体使用转换器处理数据 本方法仅为兼容Java使用存在
+
+
+
+
+ +
+
+
file +
Link copied to clipboard
+
+
+
+ +
+
fun Response.file(): File?
+
+
下载到指定文件
+
+
+
+
+ +
+
+
fileName +
Link copied to clipboard
+
+
+
+ +
+
fun Response.fileName(): String
+
+
按照以下顺序返回最终的下载文件的名称
  1. 指定文件名

  2. 响应头文件名

  3. 请求URL路径

  4. 时间戳

+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/-android-scope.html b/api/-net/com.drake.net.scope/-android-scope/-android-scope.html new file mode 100644 index 000000000..3d3ed3737 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/-android-scope.html @@ -0,0 +1,38 @@ + + + + AndroidScope + + +
+
+ + +
+
+
+
+
+
+ +
+

AndroidScope

+
+
+ +
+
fun AndroidScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+

Parameters

lifecycleOwner

生命周期持有者

lifeEvent

生命周期事件, 默认为Lifecycle.Event.ON_DESTROY下取消协程作用域

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/cancel.html b/api/-net/com.drake.net.scope/-android-scope/cancel.html new file mode 100644 index 000000000..bece8ad2d --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/cancel.html @@ -0,0 +1,38 @@ + + + + cancel + + +
+
+ + +
+
+
+
+
+
+ +
+

cancel

+
+
+ +
+
open fun cancel(cause: <ERROR CLASS>? = null)
open fun cancel(message: String, cause: Throwable? = null)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/catch.html b/api/-net/com.drake.net.scope/-android-scope/catch.html new file mode 100644 index 000000000..fe4482b88 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/catch.html @@ -0,0 +1,38 @@ + + + + catch + + +
+
+ + +
+
+
+
+
+
+ +
+

catch

+
+
+ +
+
open fun catch(block: AndroidScope.(Throwable) -> Unit = {}): AndroidScope
+
+

当作用域内发生异常时回调

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/close.html b/api/-net/com.drake.net.scope/-android-scope/close.html new file mode 100644 index 000000000..9d9333e85 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/close.html @@ -0,0 +1,38 @@ + + + + close + + +
+
+ + +
+
+
+
+
+
+ +
+

close

+
+
+ +
+
open override fun close()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/coroutine-context.html b/api/-net/com.drake.net.scope/-android-scope/coroutine-context.html new file mode 100644 index 000000000..c66b0c544 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/coroutine-context.html @@ -0,0 +1,38 @@ + + + + coroutineContext + + +
+
+ + +
+
+
+
+
+
+ +
+

coroutineContext

+
+
+ +
+
open override val coroutineContext: CoroutineContext
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/dispatcher.html b/api/-net/com.drake.net.scope/-android-scope/dispatcher.html new file mode 100644 index 000000000..c45e5f6eb --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/dispatcher.html @@ -0,0 +1,38 @@ + + + + dispatcher + + +
+
+ + +
+
+
+
+
+
+ +
+

dispatcher

+
+
+ +
+
val dispatcher: CoroutineDispatcher
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/finally.html b/api/-net/com.drake.net.scope/-android-scope/finally.html new file mode 100644 index 000000000..81579d2a8 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/finally.html @@ -0,0 +1,38 @@ + + + + finally + + +
+
+ + +
+
+
+
+
+
+ +
+

finally

+
+
+ +
+
open fun finally(block: AndroidScope.(Throwable?) -> Unit = {}): AndroidScope
+
+

无论正常或者异常结束都将最终执行

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/handle-error.html b/api/-net/com.drake.net.scope/-android-scope/handle-error.html new file mode 100644 index 000000000..1bf18e761 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/handle-error.html @@ -0,0 +1,38 @@ + + + + handleError + + +
+
+ + +
+
+
+
+
+
+ +
+

handleError

+
+
+ +
+
open fun handleError(e: Throwable)
+
+

错误处理

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/index.html b/api/-net/com.drake.net.scope/-android-scope/index.html new file mode 100644 index 000000000..c80a6d1d0 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/index.html @@ -0,0 +1,213 @@ + + + + AndroidScope + + +
+
+ + +
+
+
+
+
+
+ +
+

AndroidScope

+
open class AndroidScope(lifecycleOwner: LifecycleOwner?, lifeEvent: Lifecycle.Event, dispatcher: CoroutineDispatcher) : CoroutineScope, Closeable

异步协程作用域

+
+
+
+
+

Parameters

+
+
lifecycleOwner

生命周期持有者

lifeEvent

生命周期事件, 默认为Lifecycle.Event.ON_DESTROY下取消协程作用域

+
+

Constructors

+
+
+
+
AndroidScope +
Link copied to clipboard
+
+
+
+
fun AndroidScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)
生命周期持有者
+
+
+
+
+
+

Functions

+
+
+
+
cancel +
Link copied to clipboard
+
+
+
+ +
+
open fun cancel(cause: <ERROR CLASS>? = null)
open fun cancel(message: String, cause: Throwable? = null)
+
+
+
+
+
+
+ +
+
+
catch +
Link copied to clipboard
+
+
+
+ +
+
open fun catch(block: AndroidScope.(Throwable) -> Unit = {}): AndroidScope
+
+
当作用域内发生异常时回调
+
+
+
+
+ +
+
+
close +
Link copied to clipboard
+
+
+
+ +
+
open override fun close()
+
+
+
+
+
+
+ +
+
+
finally +
Link copied to clipboard
+
+
+
+ +
+
open fun finally(block: AndroidScope.(Throwable?) -> Unit = {}): AndroidScope
+
+
无论正常或者异常结束都将最终执行
+
+
+
+
+ +
+
+
handleError +
Link copied to clipboard
+
+
+
+ +
+
open fun handleError(e: Throwable)
+
+
错误处理
+
+
+
+
+ +
+
+
launch +
Link copied to clipboard
+
+
+
+ +
+
open fun launch(block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+
+
+
+
+
+
+

Properties

+
+
+
+
coroutineContext +
Link copied to clipboard
+
+
+
+
open override val coroutineContext: CoroutineContext
+
+
+
+
+ +
+
+
dispatcher +
Link copied to clipboard
+
+
+
+
val dispatcher: CoroutineDispatcher
+
+
+
+
+ +
+
+
scopeGroup +
Link copied to clipboard
+
+
+
+
val scopeGroup: <ERROR CLASS>
+
+
+
+
+
+

Inheritors

+
+
+
+
NetCoroutineScope +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/launch.html b/api/-net/com.drake.net.scope/-android-scope/launch.html new file mode 100644 index 000000000..f80db345a --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/launch.html @@ -0,0 +1,38 @@ + + + + launch + + +
+
+ + +
+
+
+
+
+
+ +
+

launch

+
+
+ +
+
open fun launch(block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-android-scope/scope-group.html b/api/-net/com.drake.net.scope/-android-scope/scope-group.html new file mode 100644 index 000000000..aaff840f6 --- /dev/null +++ b/api/-net/com.drake.net.scope/-android-scope/scope-group.html @@ -0,0 +1,38 @@ + + + + scopeGroup + + +
+
+ + +
+
+
+
+
+
+ +
+

scopeGroup

+
+
+ +
+
val scopeGroup: <ERROR CLASS>
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-dialog-coroutine-scope/-dialog-coroutine-scope.html b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/-dialog-coroutine-scope.html new file mode 100644 index 000000000..b8663509a --- /dev/null +++ b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/-dialog-coroutine-scope.html @@ -0,0 +1,38 @@ + + + + DialogCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

DialogCoroutineScope

+
+
+ +
+
fun DialogCoroutineScope(activity: FragmentActivity, dialog: Dialog? = null, cancelable: Boolean? = null, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+

Parameters

activity

对话框跟随生命周期的FragmentActivity

dialog

不使用默认的加载对话框而指定对话框

cancelable

是否允许用户取消对话框

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-dialog-coroutine-scope/activity.html b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/activity.html new file mode 100644 index 000000000..85488cd72 --- /dev/null +++ b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/activity.html @@ -0,0 +1,38 @@ + + + + activity + + +
+
+ + +
+
+
+
+
+
+ +
+

activity

+
+
+ +
+
val activity: FragmentActivity
+
+

Parameters

activity

对话框跟随生命周期的FragmentActivity

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-dialog-coroutine-scope/cancelable.html b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/cancelable.html new file mode 100644 index 000000000..7005dbdc8 --- /dev/null +++ b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/cancelable.html @@ -0,0 +1,38 @@ + + + + cancelable + + +
+
+ + +
+
+
+
+
+
+ +
+

cancelable

+
+
+ +
+
val cancelable: Boolean? = null
+
+

Parameters

cancelable

是否允许用户取消对话框

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-dialog-coroutine-scope/dialog.html b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/dialog.html new file mode 100644 index 000000000..7895d445e --- /dev/null +++ b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/dialog.html @@ -0,0 +1,38 @@ + + + + dialog + + +
+
+ + +
+
+
+
+
+
+ +
+

dialog

+
+
+ +
+
var dialog: Dialog? = null
+
+

Parameters

dialog

不使用默认的加载对话框而指定对话框

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-dialog-coroutine-scope/index.html b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/index.html new file mode 100644 index 000000000..273565193 --- /dev/null +++ b/api/-net/com.drake.net.scope/-dialog-coroutine-scope/index.html @@ -0,0 +1,98 @@ + + + + DialogCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

DialogCoroutineScope

+
class DialogCoroutineScope(activity: FragmentActivity, dialog: Dialog?, cancelable: Boolean?, dispatcher: CoroutineDispatcher) : NetCoroutineScope, LifecycleObserver

自动加载对话框网络请求

开始: 显示对话框 错误: 提示错误信息, 关闭对话框 完全: 关闭对话框

+
+
+
+
+

Parameters

+
+
activity

对话框跟随生命周期的FragmentActivity

dialog

不使用默认的加载对话框而指定对话框

cancelable

是否允许用户取消对话框

+
+

Constructors

+
+
+
+
DialogCoroutineScope +
Link copied to clipboard
+
+
+
+
fun DialogCoroutineScope(activity: FragmentActivity, dialog: Dialog? = null, cancelable: Boolean? = null, dispatcher: CoroutineDispatcher = Dispatchers.Main)
对话框跟随生命周期的FragmentActivity
+
+
+
+
+
+

Properties

+
+
+
+
activity +
Link copied to clipboard
+
+
+
+
val activity: FragmentActivity
对话框跟随生命周期的FragmentActivity
+
+
+
+
+ +
+
+
cancelable +
Link copied to clipboard
+
+
+
+
val cancelable: Boolean? = null
是否允许用户取消对话框
+
+
+
+
+ +
+
+
dialog +
Link copied to clipboard
+
+
+
+
var dialog: Dialog? = null
不使用默认的加载对话框而指定对话框
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-net-coroutine-scope/-net-coroutine-scope.html b/api/-net/com.drake.net.scope/-net-coroutine-scope/-net-coroutine-scope.html new file mode 100644 index 000000000..c824d8e53 --- /dev/null +++ b/api/-net/com.drake.net.scope/-net-coroutine-scope/-net-coroutine-scope.html @@ -0,0 +1,38 @@ + + + + NetCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

NetCoroutineScope

+
+
+ +
+
fun NetCoroutineScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-net-coroutine-scope/cancel.html b/api/-net/com.drake.net.scope/-net-coroutine-scope/cancel.html new file mode 100644 index 000000000..51e0e9d51 --- /dev/null +++ b/api/-net/com.drake.net.scope/-net-coroutine-scope/cancel.html @@ -0,0 +1,38 @@ + + + + cancel + + +
+
+ + +
+
+
+
+
+
+ +
+

cancel

+
+
+ +
+
open override fun cancel(cause: <ERROR CLASS>?)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-net-coroutine-scope/handle-error.html b/api/-net/com.drake.net.scope/-net-coroutine-scope/handle-error.html new file mode 100644 index 000000000..8dc905710 --- /dev/null +++ b/api/-net/com.drake.net.scope/-net-coroutine-scope/handle-error.html @@ -0,0 +1,38 @@ + + + + handleError + + +
+
+ + +
+
+
+
+
+
+ +
+

handleError

+
+
+ +
+
open override fun handleError(e: Throwable)
+
+

错误处理

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-net-coroutine-scope/index.html b/api/-net/com.drake.net.scope/-net-coroutine-scope/index.html new file mode 100644 index 000000000..e7e58847c --- /dev/null +++ b/api/-net/com.drake.net.scope/-net-coroutine-scope/index.html @@ -0,0 +1,161 @@ + + + + NetCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

NetCoroutineScope

+
open class NetCoroutineScope(lifecycleOwner: LifecycleOwner?, lifeEvent: Lifecycle.Event, dispatcher: CoroutineDispatcher) : AndroidScope

自动显示网络错误信息协程作用域

+
+
+
+
+

Constructors

+
+
+
+
NetCoroutineScope +
Link copied to clipboard
+
+
+
+
fun NetCoroutineScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+
+
+
+
+

Functions

+
+
+
+
cancel +
Link copied to clipboard
+
+
+
+ +
+
open override fun cancel(cause: <ERROR CLASS>?)
+
+
+
+
+
+
+ +
+
+
handleError +
Link copied to clipboard
+
+
+
+ +
+
open override fun handleError(e: Throwable)
+
+
错误处理
+
+
+
+
+ +
+
+
launch +
Link copied to clipboard
+
+
+
+ +
+
open override fun launch(block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
+
+
+
+
+ +
+
+
preview +
Link copied to clipboard
+
+
+
+ +
+
fun preview(breakError: Boolean = false, breakLoading: Boolean = true, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+
"预览"作用域 该函数一般用于缓存读取, 只在第一次启动作用域时回调 该函数在作用域NetCoroutineScope.launch之前执行 函数内部所有的异常都不会被抛出, 也不会终止作用域执行
+
+
+
+
+
+

Inheritors

+
+
+
+
DialogCoroutineScope +
Link copied to clipboard
+
+
+
+
+ +
+
+
PageCoroutineScope +
Link copied to clipboard
+
+
+
+
+ +
+
+
StateCoroutineScope +
Link copied to clipboard
+
+
+
+
+ +
+
+
ViewCoroutineScope +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-net-coroutine-scope/launch.html b/api/-net/com.drake.net.scope/-net-coroutine-scope/launch.html new file mode 100644 index 000000000..023463a31 --- /dev/null +++ b/api/-net/com.drake.net.scope/-net-coroutine-scope/launch.html @@ -0,0 +1,38 @@ + + + + launch + + +
+
+ + +
+
+
+
+
+
+ +
+

launch

+
+
+ +
+
open override fun launch(block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-net-coroutine-scope/preview.html b/api/-net/com.drake.net.scope/-net-coroutine-scope/preview.html new file mode 100644 index 000000000..8708de452 --- /dev/null +++ b/api/-net/com.drake.net.scope/-net-coroutine-scope/preview.html @@ -0,0 +1,38 @@ + + + + preview + + +
+
+ + +
+
+
+
+
+
+ +
+

preview

+
+
+ +
+
fun preview(breakError: Boolean = false, breakLoading: Boolean = true, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+

"预览"作用域 该函数一般用于缓存读取, 只在第一次启动作用域时回调 该函数在作用域NetCoroutineScope.launch之前执行 函数内部所有的异常都不会被抛出, 也不会终止作用域执行

Parameters

breakError

读取缓存成功后不再处理错误信息

breakLoading

读取缓存成功后结束加载动画

block

该作用域内的所有异常都算缓存读取失败, 不会吐司和打印任何错误

这里指的读取缓存也可以替换为其他任务, 比如读取数据库或者其他接口数据

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-page-coroutine-scope/--index--.html b/api/-net/com.drake.net.scope/-page-coroutine-scope/--index--.html new file mode 100644 index 000000000..079c9ba05 --- /dev/null +++ b/api/-net/com.drake.net.scope/-page-coroutine-scope/--index--.html @@ -0,0 +1,38 @@ + + + + index + + +
+
+ + +
+
+
+
+
+
+ +
+

index

+
+
+ +
+
val index: Int
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-page-coroutine-scope/-page-coroutine-scope.html b/api/-net/com.drake.net.scope/-page-coroutine-scope/-page-coroutine-scope.html new file mode 100644 index 000000000..e0ec98a54 --- /dev/null +++ b/api/-net/com.drake.net.scope/-page-coroutine-scope/-page-coroutine-scope.html @@ -0,0 +1,38 @@ + + + + PageCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

PageCoroutineScope

+
+
+ +
+
fun PageCoroutineScope(page: PageRefreshLayout, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-page-coroutine-scope/handle-error.html b/api/-net/com.drake.net.scope/-page-coroutine-scope/handle-error.html new file mode 100644 index 000000000..029ee5bf9 --- /dev/null +++ b/api/-net/com.drake.net.scope/-page-coroutine-scope/handle-error.html @@ -0,0 +1,38 @@ + + + + handleError + + +
+
+ + +
+
+
+
+
+
+ +
+

handleError

+
+
+ +
+
open override fun handleError(e: Throwable)
+
+

错误处理

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-page-coroutine-scope/index.html b/api/-net/com.drake.net.scope/-page-coroutine-scope/index.html new file mode 100644 index 000000000..47b3f6280 --- /dev/null +++ b/api/-net/com.drake.net.scope/-page-coroutine-scope/index.html @@ -0,0 +1,85 @@ + + + + PageCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

PageCoroutineScope

+
class PageCoroutineScope(page: PageRefreshLayout, dispatcher: CoroutineDispatcher) : NetCoroutineScope
+
+
+
+
+

Functions

+
+
+
+
handleError +
Link copied to clipboard
+
+
+
+ +
+
open override fun handleError(e: Throwable)
+
+
错误处理
+
+
+
+
+
+

Properties

+
+
+
+
index +
Link copied to clipboard
+
+
+
+
val index: Int
+
+
+
+
+ +
+
+
page +
Link copied to clipboard
+
+
+
+
val page: PageRefreshLayout
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-page-coroutine-scope/page.html b/api/-net/com.drake.net.scope/-page-coroutine-scope/page.html new file mode 100644 index 000000000..294cf38f1 --- /dev/null +++ b/api/-net/com.drake.net.scope/-page-coroutine-scope/page.html @@ -0,0 +1,38 @@ + + + + page + + +
+
+ + +
+
+
+
+
+
+ +
+

page

+
+
+ +
+
val page: PageRefreshLayout
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-state-coroutine-scope/-state-coroutine-scope.html b/api/-net/com.drake.net.scope/-state-coroutine-scope/-state-coroutine-scope.html new file mode 100644 index 000000000..bc24733cb --- /dev/null +++ b/api/-net/com.drake.net.scope/-state-coroutine-scope/-state-coroutine-scope.html @@ -0,0 +1,38 @@ + + + + StateCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

StateCoroutineScope

+
+
+ +
+
fun StateCoroutineScope(state: StateLayout, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-state-coroutine-scope/handle-error.html b/api/-net/com.drake.net.scope/-state-coroutine-scope/handle-error.html new file mode 100644 index 000000000..aed75e30c --- /dev/null +++ b/api/-net/com.drake.net.scope/-state-coroutine-scope/handle-error.html @@ -0,0 +1,38 @@ + + + + handleError + + +
+
+ + +
+
+
+
+
+
+ +
+

handleError

+
+
+ +
+
open override fun handleError(e: Throwable)
+
+

错误处理

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-state-coroutine-scope/index.html b/api/-net/com.drake.net.scope/-state-coroutine-scope/index.html new file mode 100644 index 000000000..0b24b589f --- /dev/null +++ b/api/-net/com.drake.net.scope/-state-coroutine-scope/index.html @@ -0,0 +1,87 @@ + + + + StateCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

StateCoroutineScope

+
class StateCoroutineScope(state: StateLayout, dispatcher: CoroutineDispatcher) : NetCoroutineScope

缺省页作用域

+
+
+
+
+

Constructors

+
+
+
+
StateCoroutineScope +
Link copied to clipboard
+
+
+
+
fun StateCoroutineScope(state: StateLayout, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+
+
+
+
+

Functions

+
+
+
+
handleError +
Link copied to clipboard
+
+
+
+ +
+
open override fun handleError(e: Throwable)
+
+
错误处理
+
+
+
+
+
+

Properties

+
+
+
+
state +
Link copied to clipboard
+
+
+
+
val state: StateLayout
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-state-coroutine-scope/state.html b/api/-net/com.drake.net.scope/-state-coroutine-scope/state.html new file mode 100644 index 000000000..1678429f7 --- /dev/null +++ b/api/-net/com.drake.net.scope/-state-coroutine-scope/state.html @@ -0,0 +1,38 @@ + + + + state + + +
+
+ + +
+
+
+
+
+
+ +
+

state

+
+
+ +
+
val state: StateLayout
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-view-coroutine-scope/-view-coroutine-scope.html b/api/-net/com.drake.net.scope/-view-coroutine-scope/-view-coroutine-scope.html new file mode 100644 index 000000000..37f1a6c11 --- /dev/null +++ b/api/-net/com.drake.net.scope/-view-coroutine-scope/-view-coroutine-scope.html @@ -0,0 +1,38 @@ + + + + ViewCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

ViewCoroutineScope

+
+
+ +
+
fun ViewCoroutineScope(view: View, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-view-coroutine-scope/index.html b/api/-net/com.drake.net.scope/-view-coroutine-scope/index.html new file mode 100644 index 000000000..15e7f4013 --- /dev/null +++ b/api/-net/com.drake.net.scope/-view-coroutine-scope/index.html @@ -0,0 +1,68 @@ + + + + ViewCoroutineScope + + +
+
+ + +
+
+
+
+
+
+ +
+

ViewCoroutineScope

+
class ViewCoroutineScope(view: View, dispatcher: CoroutineDispatcher) : NetCoroutineScope

视图作用域 会在视图销毁时自动取消作用域

+
+
+
+
+

Constructors

+
+
+
+
ViewCoroutineScope +
Link copied to clipboard
+
+
+
+
fun ViewCoroutineScope(view: View, dispatcher: CoroutineDispatcher = Dispatchers.Main)
+
+
+
+
+
+

Properties

+
+
+
+
view +
Link copied to clipboard
+
+
+
+
val view: View
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/-view-coroutine-scope/view.html b/api/-net/com.drake.net.scope/-view-coroutine-scope/view.html new file mode 100644 index 000000000..5c82c9cab --- /dev/null +++ b/api/-net/com.drake.net.scope/-view-coroutine-scope/view.html @@ -0,0 +1,38 @@ + + + + view + + +
+
+ + +
+
+
+
+
+
+ +
+

view

+
+
+ +
+
val view: View
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.scope/index.html b/api/-net/com.drake.net.scope/index.html new file mode 100644 index 000000000..6a5c21efa --- /dev/null +++ b/api/-net/com.drake.net.scope/index.html @@ -0,0 +1,141 @@ + + + + com.drake.net.scope + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.scope

+
+
+
+
+

Types

+
+
+
+
AndroidScope +
Link copied to clipboard
+
+
+
+ +
+
open class AndroidScope(lifecycleOwner: LifecycleOwner?, lifeEvent: Lifecycle.Event, dispatcher: CoroutineDispatcher) : CoroutineScope, Closeable
+
+
异步协程作用域
+
+
+
+
+ +
+
+
DialogCoroutineScope +
Link copied to clipboard
+
+
+
+ +
+
class DialogCoroutineScope(activity: FragmentActivity, dialog: Dialog?, cancelable: Boolean?, dispatcher: CoroutineDispatcher) : NetCoroutineScope, LifecycleObserver
+
+
自动加载对话框网络请求开始: 显示对话框 错误: 提示错误信息, 关闭对话框 完全: 关闭对话框
+
+
+
+
+ +
+
+
NetCoroutineScope +
Link copied to clipboard
+
+
+
+ +
+
open class NetCoroutineScope(lifecycleOwner: LifecycleOwner?, lifeEvent: Lifecycle.Event, dispatcher: CoroutineDispatcher) : AndroidScope
+
+
自动显示网络错误信息协程作用域
+
+
+
+
+ +
+
+
PageCoroutineScope +
Link copied to clipboard
+
+
+
+ +
+
class PageCoroutineScope(page: PageRefreshLayout, dispatcher: CoroutineDispatcher) : NetCoroutineScope
+
+
+
+
+
+
+ +
+
+
StateCoroutineScope +
Link copied to clipboard
+
+
+
+ +
+
class StateCoroutineScope(state: StateLayout, dispatcher: CoroutineDispatcher) : NetCoroutineScope
+
+
缺省页作用域
+
+
+
+
+ +
+
+
ViewCoroutineScope +
Link copied to clipboard
+
+
+
+ +
+
class ViewCoroutineScope(view: View, dispatcher: CoroutineDispatcher) : NetCoroutineScope
+
+
视图作用域 会在视图销毁时自动取消作用域
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-cache-key/-cache-key.html b/api/-net/com.drake.net.tag/-net-tag/-cache-key/-cache-key.html new file mode 100644 index 000000000..948f8c1ae --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-cache-key/-cache-key.html @@ -0,0 +1,38 @@ + + + + CacheKey + + +
+
+ + +
+
+
+
+
+
+ +
+

CacheKey

+
+
+ +
+
fun CacheKey(value: String)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-cache-key/index.html b/api/-net/com.drake.net.tag/-net-tag/-cache-key/index.html new file mode 100644 index 000000000..21e583c18 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-cache-key/index.html @@ -0,0 +1,53 @@ + + + + CacheKey + + +
+
+ + +
+
+
+
+
+
+ +
+

CacheKey

+
class CacheKey(value: String)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: String
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-cache-key/value.html b/api/-net/com.drake.net.tag/-net-tag/-cache-key/value.html new file mode 100644 index 000000000..cadfb1dd8 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-cache-key/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/-cache-valid-time.html b/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/-cache-valid-time.html new file mode 100644 index 000000000..b44f9dc5f --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/-cache-valid-time.html @@ -0,0 +1,38 @@ + + + + CacheValidTime + + +
+
+ + +
+
+
+
+
+
+ +
+

CacheValidTime

+
+
+ +
+
fun CacheValidTime(value: Long)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/index.html b/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/index.html new file mode 100644 index 000000000..7df4e144d --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/index.html @@ -0,0 +1,53 @@ + + + + CacheValidTime + + +
+
+ + +
+
+
+
+
+
+ +
+

CacheValidTime

+
class CacheValidTime(value: Long)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: Long
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/value.html b/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/value.html new file mode 100644 index 000000000..1ee4348fc --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-cache-valid-time/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: Long
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/-download-file-conflict-rename.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/-download-file-conflict-rename.html new file mode 100644 index 000000000..e1b6b6e3c --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/-download-file-conflict-rename.html @@ -0,0 +1,38 @@ + + + + DownloadFileConflictRename + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileConflictRename

+
+
+ +
+
fun DownloadFileConflictRename(value: Boolean = true)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/index.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/index.html new file mode 100644 index 000000000..f2f645d86 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/index.html @@ -0,0 +1,53 @@ + + + + DownloadFileConflictRename + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileConflictRename

+
class DownloadFileConflictRename(value: Boolean)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: Boolean = true
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/value.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/value.html new file mode 100644 index 000000000..11914c380 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: Boolean = true
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/-download-file-dir.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/-download-file-dir.html new file mode 100644 index 000000000..802f9097b --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/-download-file-dir.html @@ -0,0 +1,38 @@ + + + + DownloadFileDir + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileDir

+
+
+ +
+
fun DownloadFileDir(fileDir: File)
fun DownloadFileDir(value: String)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/index.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/index.html new file mode 100644 index 000000000..5a71dfdf4 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/index.html @@ -0,0 +1,68 @@ + + + + DownloadFileDir + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileDir

+
class DownloadFileDir(value: String)
+
+
+
+
+

Constructors

+
+
+
+
DownloadFileDir +
Link copied to clipboard
+
+
+
+
fun DownloadFileDir(fileDir: File)
+
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: String
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/value.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/value.html new file mode 100644 index 000000000..e2e48bdd4 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-dir/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/-download-file-m-d5-verify.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/-download-file-m-d5-verify.html new file mode 100644 index 000000000..7be5974dc --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/-download-file-m-d5-verify.html @@ -0,0 +1,38 @@ + + + + DownloadFileMD5Verify + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileMD5Verify

+
+
+ +
+
fun DownloadFileMD5Verify(value: Boolean = true)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/index.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/index.html new file mode 100644 index 000000000..21bec30e6 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/index.html @@ -0,0 +1,53 @@ + + + + DownloadFileMD5Verify + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileMD5Verify

+
class DownloadFileMD5Verify(value: Boolean)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: Boolean = true
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/value.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/value.html new file mode 100644 index 000000000..75bddf441 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: Boolean = true
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/-download-file-name-decode.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/-download-file-name-decode.html new file mode 100644 index 000000000..614c72e52 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/-download-file-name-decode.html @@ -0,0 +1,38 @@ + + + + DownloadFileNameDecode + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileNameDecode

+
+
+ +
+
fun DownloadFileNameDecode(value: Boolean = true)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/index.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/index.html new file mode 100644 index 000000000..db5e94b9a --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/index.html @@ -0,0 +1,53 @@ + + + + DownloadFileNameDecode + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileNameDecode

+
class DownloadFileNameDecode(value: Boolean)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: Boolean = true
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/value.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/value.html new file mode 100644 index 000000000..220a14309 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: Boolean = true
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-name/-download-file-name.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-name/-download-file-name.html new file mode 100644 index 000000000..f5a79285a --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-name/-download-file-name.html @@ -0,0 +1,38 @@ + + + + DownloadFileName + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileName

+
+
+ +
+
fun DownloadFileName(value: String)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-name/index.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-name/index.html new file mode 100644 index 000000000..07dd1272a --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-name/index.html @@ -0,0 +1,53 @@ + + + + DownloadFileName + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadFileName

+
class DownloadFileName(value: String)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: String
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-file-name/value.html b/api/-net/com.drake.net.tag/-net-tag/-download-file-name/value.html new file mode 100644 index 000000000..231b97b21 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-file-name/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: String
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-listeners/-download-listeners.html b/api/-net/com.drake.net.tag/-net-tag/-download-listeners/-download-listeners.html new file mode 100644 index 000000000..8e64ce9f1 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-listeners/-download-listeners.html @@ -0,0 +1,38 @@ + + + + DownloadListeners + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadListeners

+
+
+ +
+
fun DownloadListeners()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-listeners/index.html b/api/-net/com.drake.net.tag/-net-tag/-download-listeners/index.html new file mode 100644 index 000000000..35d2329a0 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-listeners/index.html @@ -0,0 +1,37 @@ + + + + DownloadListeners + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadListeners

+
class DownloadListeners : ConcurrentLinkedQueue<ProgressListener>
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/-download-temp-file.html b/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/-download-temp-file.html new file mode 100644 index 000000000..35eb33dd7 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/-download-temp-file.html @@ -0,0 +1,38 @@ + + + + DownloadTempFile + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadTempFile

+
+
+ +
+
fun DownloadTempFile(value: Boolean = true)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/index.html b/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/index.html new file mode 100644 index 000000000..08981f038 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/index.html @@ -0,0 +1,53 @@ + + + + DownloadTempFile + + +
+
+ + +
+
+
+
+
+
+ +
+

DownloadTempFile

+
class DownloadTempFile(value: Boolean)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: Boolean = true
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/value.html b/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/value.html new file mode 100644 index 000000000..63df74865 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-download-temp-file/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: Boolean = true
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-extras/-extras.html b/api/-net/com.drake.net.tag/-net-tag/-extras/-extras.html new file mode 100644 index 000000000..5d0d431cd --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-extras/-extras.html @@ -0,0 +1,38 @@ + + + + Extras + + +
+
+ + +
+
+
+
+
+
+ +
+

Extras

+
+
+ +
+
fun Extras()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-extras/index.html b/api/-net/com.drake.net.tag/-net-tag/-extras/index.html new file mode 100644 index 000000000..17ea86419 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-extras/index.html @@ -0,0 +1,37 @@ + + + + Extras + + +
+
+ + +
+
+
+
+
+
+ +
+

Extras

+
class Extras
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-group/-request-group.html b/api/-net/com.drake.net.tag/-net-tag/-request-group/-request-group.html new file mode 100644 index 000000000..4660d32f4 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-group/-request-group.html @@ -0,0 +1,38 @@ + + + + RequestGroup + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestGroup

+
+
+ +
+
fun RequestGroup(value: Any)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-group/index.html b/api/-net/com.drake.net.tag/-net-tag/-request-group/index.html new file mode 100644 index 000000000..ba0c24982 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-group/index.html @@ -0,0 +1,53 @@ + + + + RequestGroup + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestGroup

+
class RequestGroup(value: Any)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: Any
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-group/value.html b/api/-net/com.drake.net.tag/-net-tag/-request-group/value.html new file mode 100644 index 000000000..ad35e99d2 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-group/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: Any
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-id/-request-id.html b/api/-net/com.drake.net.tag/-net-tag/-request-id/-request-id.html new file mode 100644 index 000000000..b6aedf757 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-id/-request-id.html @@ -0,0 +1,38 @@ + + + + RequestId + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestId

+
+
+ +
+
fun RequestId(value: Any)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-id/index.html b/api/-net/com.drake.net.tag/-net-tag/-request-id/index.html new file mode 100644 index 000000000..a745da93c --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-id/index.html @@ -0,0 +1,53 @@ + + + + RequestId + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestId

+
class RequestId(value: Any)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: Any
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-id/value.html b/api/-net/com.drake.net.tag/-net-tag/-request-id/value.html new file mode 100644 index 000000000..5bc0a2867 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-id/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: Any
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-k-type/-request-k-type.html b/api/-net/com.drake.net.tag/-net-tag/-request-k-type/-request-k-type.html new file mode 100644 index 000000000..445dbcc9e --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-k-type/-request-k-type.html @@ -0,0 +1,38 @@ + + + + RequestKType + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestKType

+
+
+ +
+
fun RequestKType(value: KType)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-k-type/index.html b/api/-net/com.drake.net.tag/-net-tag/-request-k-type/index.html new file mode 100644 index 000000000..a262172a5 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-k-type/index.html @@ -0,0 +1,53 @@ + + + + RequestKType + + +
+
+ + +
+
+
+
+
+
+ +
+

RequestKType

+
class RequestKType(value: KType)
+
+
+
+
+

Properties

+
+
+
+
value +
Link copied to clipboard
+
+
+
+
val value: KType
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-request-k-type/value.html b/api/-net/com.drake.net.tag/-net-tag/-request-k-type/value.html new file mode 100644 index 000000000..4c0dccb39 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-request-k-type/value.html @@ -0,0 +1,38 @@ + + + + value + + +
+
+ + +
+
+
+
+
+
+ +
+

value

+
+
+ +
+
val value: KType
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-upload-listeners/-upload-listeners.html b/api/-net/com.drake.net.tag/-net-tag/-upload-listeners/-upload-listeners.html new file mode 100644 index 000000000..252ba2148 --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-upload-listeners/-upload-listeners.html @@ -0,0 +1,38 @@ + + + + UploadListeners + + +
+
+ + +
+
+
+
+
+
+ +
+

UploadListeners

+
+
+ +
+
fun UploadListeners()
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/-upload-listeners/index.html b/api/-net/com.drake.net.tag/-net-tag/-upload-listeners/index.html new file mode 100644 index 000000000..91327aabd --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/-upload-listeners/index.html @@ -0,0 +1,37 @@ + + + + UploadListeners + + +
+
+ + +
+
+
+
+
+
+ +
+

UploadListeners

+
class UploadListeners : ConcurrentLinkedQueue<ProgressListener>
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/-net-tag/index.html b/api/-net/com.drake.net.tag/-net-tag/index.html new file mode 100644 index 000000000..78a35378c --- /dev/null +++ b/api/-net/com.drake.net.tag/-net-tag/index.html @@ -0,0 +1,278 @@ + + + + NetTag + + +
+
+ + +
+
+
+
+
+
+ +
+

NetTag

+
sealed class NetTag
+
+
+
+
+

Types

+
+
+
+
CacheKey +
Link copied to clipboard
+
+
+
+ +
+
class CacheKey(value: String)
+
+
+
+
+
+
+ +
+
+
CacheValidTime +
Link copied to clipboard
+
+
+
+ +
+
class CacheValidTime(value: Long)
+
+
+
+
+
+
+ +
+
+
DownloadFileConflictRename +
Link copied to clipboard
+
+
+
+ +
+
class DownloadFileConflictRename(value: Boolean)
+
+
+
+
+
+
+ +
+
+
DownloadFileDir +
Link copied to clipboard
+
+
+
+ +
+
class DownloadFileDir(value: String)
+
+
+
+
+
+
+ +
+
+
DownloadFileMD5Verify +
Link copied to clipboard
+
+
+
+ +
+
class DownloadFileMD5Verify(value: Boolean)
+
+
+
+
+
+
+ +
+
+
DownloadFileName +
Link copied to clipboard
+
+
+
+ +
+
class DownloadFileName(value: String)
+
+
+
+
+
+
+ +
+
+
DownloadFileNameDecode +
Link copied to clipboard
+
+
+
+ +
+
class DownloadFileNameDecode(value: Boolean)
+
+
+
+
+
+
+ +
+
+
DownloadListeners +
Link copied to clipboard
+
+
+
+ +
+
class DownloadListeners : ConcurrentLinkedQueue<ProgressListener>
+
+
+
+
+
+
+ +
+
+
DownloadTempFile +
Link copied to clipboard
+
+
+
+ +
+
class DownloadTempFile(value: Boolean)
+
+
+
+
+
+
+ +
+
+
Extras +
Link copied to clipboard
+
+
+
+ +
+
class Extras
+
+
+
+
+
+
+ +
+
+
RequestGroup +
Link copied to clipboard
+
+
+
+ +
+
class RequestGroup(value: Any)
+
+
+
+
+
+
+ +
+
+
RequestId +
Link copied to clipboard
+
+
+
+ +
+
class RequestId(value: Any)
+
+
+
+
+
+
+ +
+
+
RequestKType +
Link copied to clipboard
+
+
+
+ +
+
class RequestKType(value: KType)
+
+
+
+
+
+
+ +
+
+
UploadListeners +
Link copied to clipboard
+
+
+
+ +
+
class UploadListeners : ConcurrentLinkedQueue<ProgressListener>
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.tag/index.html b/api/-net/com.drake.net.tag/index.html new file mode 100644 index 000000000..ecfc115b9 --- /dev/null +++ b/api/-net/com.drake.net.tag/index.html @@ -0,0 +1,56 @@ + + + + com.drake.net.tag + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.tag

+
+
+
+
+

Types

+
+
+
+
NetTag +
Link copied to clipboard
+
+
+
+ +
+
sealed class NetTag
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-a-c-t-i-v-e/index.html b/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-a-c-t-i-v-e/index.html new file mode 100644 index 000000000..b142d91b4 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-a-c-t-i-v-e/index.html @@ -0,0 +1,37 @@ + + + + STATE_ACTIVE + + +
+
+ + +
+
+
+
+
+
+ +
+

STATE_ACTIVE

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-i-d-l-e/index.html b/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-i-d-l-e/index.html new file mode 100644 index 000000000..f1f08a002 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-i-d-l-e/index.html @@ -0,0 +1,37 @@ + + + + STATE_IDLE + + +
+
+ + +
+
+
+
+
+
+ +
+

STATE_IDLE

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-p-a-u-s-e/index.html b/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-p-a-u-s-e/index.html new file mode 100644 index 000000000..e42db0494 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-p-a-u-s-e/index.html @@ -0,0 +1,37 @@ + + + + STATE_PAUSE + + +
+
+ + +
+
+
+
+
+
+ +
+

STATE_PAUSE

+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval-status/index.html b/api/-net/com.drake.net.time/-interval-status/index.html new file mode 100644 index 000000000..83cc8cd04 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval-status/index.html @@ -0,0 +1,79 @@ + + + + IntervalStatus + + +
+
+ + +
+
+
+
+
+
+ +
+

IntervalStatus

+
enum IntervalStatus : Enum<IntervalStatus>

计时器的状态

+
+
+
+
+

Entries

+
+
+
+
STATE_PAUSE +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
STATE_IDLE +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+
STATE_ACTIVE +
Link copied to clipboard
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/-interval.html b/api/-net/com.drake.net.time/-interval/-interval.html new file mode 100644 index 000000000..57dde5b67 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/-interval.html @@ -0,0 +1,44 @@ + + + + Interval + + +
+
+ + +
+
+
+
+
+
+ +
+

Interval

+
+
+ +
+
fun Interval(period: Long, unit: TimeUnit, initialDelay: Long = 0)
+
+

创建一个不会自动结束的轮询器/计时器

Parameters

period

间隔时间

unit

时间单位

initialDelay

初次间隔时间, 默认为0即立即开始

+
+ +
+
fun Interval(end: Long, period: Long, unit: TimeUnit, start: Long = 0, initialDelay: Long = 0)
+
+

Parameters

end

结束值, -1 表示永远不结束

period

计时器间隔

unit

计时器单位

initialDelay

第一次事件的间隔时间, 默认0

start

开始值, 当start]比end值大, 且end不等于-1时, 即为倒计时, 反之正计时

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/cancel.html b/api/-net/com.drake.net.time/-interval/cancel.html new file mode 100644 index 000000000..d0def750d --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/cancel.html @@ -0,0 +1,38 @@ + + + + cancel + + +
+
+ + +
+
+
+
+
+
+ +
+

cancel

+
+
+ +
+
fun cancel()
+
+

取消 区别于stop并不会执行finish

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/close.html b/api/-net/com.drake.net.time/-interval/close.html new file mode 100644 index 000000000..cb6cfcb57 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/close.html @@ -0,0 +1,38 @@ + + + + close + + +
+
+ + +
+
+
+
+
+
+ +
+

close

+
+
+ +
+
open override fun close()
+
+

等于cancel

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/count.html b/api/-net/com.drake.net.time/-interval/count.html new file mode 100644 index 000000000..ec633a729 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/count.html @@ -0,0 +1,38 @@ + + + + count + + +
+
+ + +
+
+
+
+
+
+ +
+

count

+
+
+ +
+
var count: Long
+
+

轮询器的计数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/end.html b/api/-net/com.drake.net.time/-interval/end.html new file mode 100644 index 000000000..a30347fb5 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/end.html @@ -0,0 +1,38 @@ + + + + end + + +
+
+ + +
+
+
+
+
+
+ +
+

end

+
+
+ +
+
var end: Long
+
+

Parameters

end

结束值, -1 表示永远不结束

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/finish.html b/api/-net/com.drake.net.time/-interval/finish.html new file mode 100644 index 000000000..46fe7f96b --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/finish.html @@ -0,0 +1,38 @@ + + + + finish + + +
+
+ + +
+
+
+
+
+
+ +
+

finish

+
+
+ +
+
fun finish(block: Interval.(Long) -> Unit): <ERROR CLASS>
+
+

轮询器完成时回调该函数

See also

com.drake.net.time.Interval

使用该函数取消轮询器不会回调finish

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/index.html b/api/-net/com.drake.net.time/-interval/index.html new file mode 100644 index 000000000..a3a8524fb --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/index.html @@ -0,0 +1,342 @@ + + + + Interval + + +
+
+ + +
+
+
+
+
+
+ +
+

Interval

+
open class Interval @JvmOverloads() constructor(end: Long, period: Long, unit: TimeUnit, start: Long, initialDelay: Long) : Serializable, Closeable

创建一个轮询器

操作

  1. 开启 start 只有在闲置状态下才可以开始

  2. 停止 stop

  3. 暂停 pause

  4. 继续 resume

  5. 重置 reset 重置不会导致轮询器停止

  6. 开关 switch 开启|暂停切换

  7. 生命周期 life

函数回调: 允许多次订阅同一个轮询器

  1. 每个事件 subscribe

  2. 停止或者结束 finish

+
+
+
+
+

Parameters

+
+
end

结束值, -1 表示永远不结束

period

计时器间隔

unit

计时器单位

initialDelay

第一次事件的间隔时间, 默认0

start

开始值, 当start]比end值大, 且end不等于-1时, 即为倒计时, 反之正计时

+
+

Constructors

+
+
+
+
Interval +
Link copied to clipboard
+
+
+
+
fun Interval(period: Long, unit: TimeUnit, initialDelay: Long = 0)
创建一个不会自动结束的轮询器/计时器
+
+
+
+
+ +
+
+
Interval +
Link copied to clipboard
+
+
+
+
fun Interval(end: Long, period: Long, unit: TimeUnit, start: Long = 0, initialDelay: Long = 0)
结束值, -1 表示永远不结束
+
+
+
+
+
+

Functions

+
+
+
+
cancel +
Link copied to clipboard
+
+
+
+ +
+
fun cancel()
+
+
取消 区别于stop并不会执行finish
+
+
+
+
+ +
+
+
close +
Link copied to clipboard
+
+
+
+ +
+
open override fun close()
+
+
等于cancel
+
+
+
+
+ +
+
+
finish +
Link copied to clipboard
+
+
+
+ +
+
fun finish(block: Interval.(Long) -> Unit): <ERROR CLASS>
+
+
轮询器完成时回调该函数
+
+
+
+
+ +
+
+
life +
Link copied to clipboard
+
+
+
+ +
+
fun life(fragment: Fragment, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY): Interval
+
+
自动在指定生命周期后取消cancel轮询器
+
+ +
+
fun life(lifecycleOwner: LifecycleOwner, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY): <ERROR CLASS>
+
+
自动在指定生命周期后取消cancel轮询器
+
+
+
+
+ +
+
+
onlyResumed +
Link copied to clipboard
+
+
+
+ +
+
fun onlyResumed(lifecycleOwner: LifecycleOwner): <ERROR CLASS>
+
+
当界面不可见时暂停pause, 当界面可见时继续resume, 当界面销毁时cancel轮询器
+
+
+
+
+ +
+
+
pause +
Link copied to clipboard
+
+
+
+ +
+
fun pause()
+
+
暂停
+
+
+
+
+ +
+
+
reset +
Link copied to clipboard
+
+
+
+ +
+
fun reset()
+
+
重置
+
+
+
+
+ +
+
+
resume +
Link copied to clipboard
+
+
+
+ +
+
fun resume()
+
+
继续 要求轮询器为暂停状态IntervalStatus.STATE_PAUSE, 否则无效
+
+
+
+
+ +
+
+
start +
Link copied to clipboard
+
+
+
+ +
+
fun start(): <ERROR CLASS>
+
+
开始 如果当前为暂停状态将重新开始轮询
+
+
+
+
+ +
+
+
stop +
Link copied to clipboard
+
+
+
+ +
+
fun stop()
+
+
停止
+
+
+
+
+ +
+
+
subscribe +
Link copied to clipboard
+
+
+
+ +
+
fun subscribe(block: Interval.(Long) -> Unit): <ERROR CLASS>
+
+
订阅轮询器 每次轮询器计时都会调用该回调函数 轮询器完成时会同时触发回调blockfinish
+
+
+
+
+ +
+
+
switch +
Link copied to clipboard
+
+
+
+ +
+
fun switch()
+
+
切换轮询器开始或结束 假设轮询器为暂停IntervalStatus.STATE_PAUSE状态将继续运行resume
+
+
+
+
+
+

Properties

+
+
+
+
count +
Link copied to clipboard
+
+
+
+
var count: Long
轮询器的计数
+
+
+
+
+ +
+
+
end +
Link copied to clipboard
+
+
+
+
var end: Long
结束值, -1 表示永远不结束
+
+
+
+
+ +
+
+
state +
Link copied to clipboard
+
+
+
+
var state: IntervalStatus
轮询器当前状态
+
+
+
+
+
+

Extensions

+
+
+
+
life +
Link copied to clipboard
+
+
+
+ +
+
fun Interval.life(viewModel: ViewModel): <ERROR CLASS>
+
+
轮询器根据ViewModel生命周期自动取消
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/life.html b/api/-net/com.drake.net.time/-interval/life.html new file mode 100644 index 000000000..0179a9ff3 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/life.html @@ -0,0 +1,44 @@ + + + + life + + +
+
+ + +
+
+
+
+
+
+ +
+

life

+
+
+ +
+
fun life(lifecycleOwner: LifecycleOwner, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY): <ERROR CLASS>
+
+

自动在指定生命周期后取消cancel轮询器

Parameters

lifecycleOwner

生命周期持有者, 一般为Activity/Fragment

lifeEvent

销毁生命周期, 默认为 Lifecycle.Event.ON_DESTROY 时停止时停止轮询器

+
+ +
+
fun life(fragment: Fragment, lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY): Interval
+
+

自动在指定生命周期后取消cancel轮询器

Parameters

lifeEvent

销毁生命周期, 默认为 Lifecycle.Event.ON_DESTROY 时停止时停止轮询器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/only-resumed.html b/api/-net/com.drake.net.time/-interval/only-resumed.html new file mode 100644 index 000000000..1b262c014 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/only-resumed.html @@ -0,0 +1,38 @@ + + + + onlyResumed + + +
+
+ + +
+
+
+
+
+
+ +
+

onlyResumed

+
+
+ +
+
fun onlyResumed(lifecycleOwner: LifecycleOwner): <ERROR CLASS>
+
+

当界面不可见时暂停pause, 当界面可见时继续resume, 当界面销毁时cancel轮询器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/pause.html b/api/-net/com.drake.net.time/-interval/pause.html new file mode 100644 index 000000000..bab04f7df --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/pause.html @@ -0,0 +1,38 @@ + + + + pause + + +
+
+ + +
+
+
+
+
+
+ +
+

pause

+
+
+ +
+
fun pause()
+
+

暂停

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/reset.html b/api/-net/com.drake.net.time/-interval/reset.html new file mode 100644 index 000000000..c51ac8579 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/reset.html @@ -0,0 +1,38 @@ + + + + reset + + +
+
+ + +
+
+
+
+
+
+ +
+

reset

+
+
+ +
+
fun reset()
+
+

重置

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/resume.html b/api/-net/com.drake.net.time/-interval/resume.html new file mode 100644 index 000000000..c70930314 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/resume.html @@ -0,0 +1,38 @@ + + + + resume + + +
+
+ + +
+
+
+
+
+
+ +
+

resume

+
+
+ +
+
fun resume()
+
+

继续 要求轮询器为暂停状态IntervalStatus.STATE_PAUSE, 否则无效

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/start.html b/api/-net/com.drake.net.time/-interval/start.html new file mode 100644 index 000000000..e9d89e16f --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/start.html @@ -0,0 +1,38 @@ + + + + start + + +
+
+ + +
+
+
+
+
+
+ +
+

start

+
+
+ +
+
fun start(): <ERROR CLASS>
+
+

开始 如果当前为暂停状态将重新开始轮询

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/state.html b/api/-net/com.drake.net.time/-interval/state.html new file mode 100644 index 000000000..8f38f4f45 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/state.html @@ -0,0 +1,38 @@ + + + + state + + +
+
+ + +
+
+
+
+
+
+ +
+

state

+
+
+ +
+
var state: IntervalStatus
+
+

轮询器当前状态

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/stop.html b/api/-net/com.drake.net.time/-interval/stop.html new file mode 100644 index 000000000..1d47f4023 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/stop.html @@ -0,0 +1,38 @@ + + + + stop + + +
+
+ + +
+
+
+
+
+
+ +
+

stop

+
+
+ +
+
fun stop()
+
+

停止

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/subscribe.html b/api/-net/com.drake.net.time/-interval/subscribe.html new file mode 100644 index 000000000..22977dcde --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/subscribe.html @@ -0,0 +1,38 @@ + + + + subscribe + + +
+
+ + +
+
+
+
+
+
+ +
+

subscribe

+
+
+ +
+
fun subscribe(block: Interval.(Long) -> Unit): <ERROR CLASS>
+
+

订阅轮询器 每次轮询器计时都会调用该回调函数 轮询器完成时会同时触发回调blockfinish

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/-interval/switch.html b/api/-net/com.drake.net.time/-interval/switch.html new file mode 100644 index 000000000..730ba9245 --- /dev/null +++ b/api/-net/com.drake.net.time/-interval/switch.html @@ -0,0 +1,38 @@ + + + + switch + + +
+
+ + +
+
+
+
+
+
+ +
+

switch

+
+
+ +
+
fun switch()
+
+

切换轮询器开始或结束 假设轮询器为暂停IntervalStatus.STATE_PAUSE状态将继续运行resume

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.time/index.html b/api/-net/com.drake.net.time/index.html new file mode 100644 index 000000000..13d5ef6d7 --- /dev/null +++ b/api/-net/com.drake.net.time/index.html @@ -0,0 +1,73 @@ + + + + com.drake.net.time + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.time

+
+
+
+
+

Types

+
+
+
+
Interval +
Link copied to clipboard
+
+
+
+ +
+
open class Interval @JvmOverloads() constructor(end: Long, period: Long, unit: TimeUnit, start: Long, initialDelay: Long) : Serializable, Closeable
+
+
创建一个轮询器操作
  1. 开启 start 只有在闲置状态下才可以开始

  2. 停止 stop

  3. 暂停 pause

  4. 继续 resume

  5. 重置 reset 重置不会导致轮询器停止

  6. 开关 switch 开启|暂停切换

  7. 生命周期 life

函数回调: 允许多次订阅同一个轮询器
  1. 每个事件 subscribe

  2. 停止或者结束 finish

+
+
+
+
+ +
+
+
IntervalStatus +
Link copied to clipboard
+
+
+
+ +
+
enum IntervalStatus : Enum<IntervalStatus>
+
+
计时器的状态
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.transform/-deferred-transform/-deferred-transform.html b/api/-net/com.drake.net.transform/-deferred-transform/-deferred-transform.html new file mode 100644 index 000000000..3655c5f39 --- /dev/null +++ b/api/-net/com.drake.net.transform/-deferred-transform/-deferred-transform.html @@ -0,0 +1,38 @@ + + + + DeferredTransform + + +
+
+ + +
+
+
+
+
+
+ +
+

DeferredTransform

+
+
+ +
+
fun <T, R> DeferredTransform(deferred: Deferred<T>, block: (T) -> R)
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.transform/-deferred-transform/block.html b/api/-net/com.drake.net.transform/-deferred-transform/block.html new file mode 100644 index 000000000..7df344644 --- /dev/null +++ b/api/-net/com.drake.net.transform/-deferred-transform/block.html @@ -0,0 +1,38 @@ + + + + block + + +
+
+ + +
+
+
+
+
+
+ +
+

block

+
+
+ +
+
val block: (T) -> R
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.transform/-deferred-transform/deferred.html b/api/-net/com.drake.net.transform/-deferred-transform/deferred.html new file mode 100644 index 000000000..bd81a6161 --- /dev/null +++ b/api/-net/com.drake.net.transform/-deferred-transform/deferred.html @@ -0,0 +1,38 @@ + + + + deferred + + +
+
+ + +
+
+
+
+
+
+ +
+

deferred

+
+
+ +
+
val deferred: Deferred<T>
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.transform/-deferred-transform/index.html b/api/-net/com.drake.net.transform/-deferred-transform/index.html new file mode 100644 index 000000000..6855e9516 --- /dev/null +++ b/api/-net/com.drake.net.transform/-deferred-transform/index.html @@ -0,0 +1,66 @@ + + + + DeferredTransform + + +
+
+ + +
+
+
+
+
+
+ +
+

DeferredTransform

+
data class DeferredTransform<T, R>(deferred: Deferred<T>, block: (T) -> R)
+
+
+
+
+

Properties

+
+
+
+
block +
Link copied to clipboard
+
+
+
+
val block: (T) -> R
+
+
+
+
+ +
+
+
deferred +
Link copied to clipboard
+
+
+
+
val deferred: Deferred<T>
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.transform/index.html b/api/-net/com.drake.net.transform/index.html new file mode 100644 index 000000000..1f82adc8c --- /dev/null +++ b/api/-net/com.drake.net.transform/index.html @@ -0,0 +1,75 @@ + + + + com.drake.net.transform + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.transform

+
+
+
+
+

Types

+
+
+
+
DeferredTransform +
Link copied to clipboard
+
+
+
+ +
+
data class DeferredTransform<T, R>(deferred: Deferred<T>, block: (T) -> R)
+
+
+
+
+
+
+
+

Functions

+
+
+
+
transform +
Link copied to clipboard
+
+
+
+ +
+
fun <T, R> Deferred<T>.transform(block: (T) -> R): DeferredTransform<T, R>
+
+
可以将Deferred返回结果进行转换 blockDeferred执行成功返回结果时执行
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.transform/transform.html b/api/-net/com.drake.net.transform/transform.html new file mode 100644 index 000000000..56a9cee35 --- /dev/null +++ b/api/-net/com.drake.net.transform/transform.html @@ -0,0 +1,38 @@ + + + + transform + + +
+
+ + +
+
+
+
+
+
+ +
+

transform

+
+
+ +
+
fun <T, R> Deferred<T>.transform(block: (T) -> R): DeferredTransform<T, R>
+
+

可以将Deferred返回结果进行转换 blockDeferred执行成功返回结果时执行

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/-https/-un-safe-hostname-verifier.html b/api/-net/com.drake.net.utils/-https/-un-safe-hostname-verifier.html new file mode 100644 index 000000000..de9b0fc40 --- /dev/null +++ b/api/-net/com.drake.net.utils/-https/-un-safe-hostname-verifier.html @@ -0,0 +1,38 @@ + + + + UnSafeHostnameVerifier + + +
+
+ + +
+
+
+
+
+
+ +
+

UnSafeHostnameVerifier

+
+
+ +
+
var UnSafeHostnameVerifier: HostnameVerifier
+
+

此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配, 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/-https/-un-safe-trust-manager.html b/api/-net/com.drake.net.utils/-https/-un-safe-trust-manager.html new file mode 100644 index 000000000..0565fbf04 --- /dev/null +++ b/api/-net/com.drake.net.utils/-https/-un-safe-trust-manager.html @@ -0,0 +1,38 @@ + + + + UnSafeTrustManager + + +
+
+ + +
+
+
+
+
+
+ +
+

UnSafeTrustManager

+
+
+ +
+
var UnSafeTrustManager: X509TrustManager
+
+

为了解决客户端不信任服务器数字证书的问题,网络上大部分的解决方案都是让客户端不对证书做任何检查, 这是一种有很大安全漏洞的办法

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/-https/index.html b/api/-net/com.drake.net.utils/-https/index.html new file mode 100644 index 000000000..b1da3c50d --- /dev/null +++ b/api/-net/com.drake.net.utils/-https/index.html @@ -0,0 +1,66 @@ + + + + Https + + +
+
+ + +
+
+
+
+
+
+ +
+

Https

+
object Https
+
+
+
+
+

Properties

+
+
+
+
UnSafeHostnameVerifier +
Link copied to clipboard
+
+
+
+
var UnSafeHostnameVerifier: HostnameVerifier
此类是用于主机名验证的基接口。 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配, 则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。策略可以是基于证书的或依赖于其他验证方案。 当验证 URL 主机名使用的默认规则失败时使用这些回调。如果主机名是可接受的,则返回 true
+
+
+
+
+ +
+
+
UnSafeTrustManager +
Link copied to clipboard
+
+
+
+
var UnSafeTrustManager: X509TrustManager
为了解决客户端不信任服务器数字证书的问题,网络上大部分的解决方案都是让客户端不对证书做任何检查, 这是一种有很大安全漏洞的办法
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/-tip-utils/index.html b/api/-net/com.drake.net.utils/-tip-utils/index.html new file mode 100644 index 000000000..ee1f6cf0c --- /dev/null +++ b/api/-net/com.drake.net.utils/-tip-utils/index.html @@ -0,0 +1,57 @@ + + + + TipUtils + + +
+
+ + +
+
+
+
+
+
+ +
+

TipUtils

+
object TipUtils
+
+
+
+
+

Functions

+
+
+
+
toast +
Link copied to clipboard
+
+
+
+ +
+
fun toast(message: String?)
+
+
重复显示不会覆盖, 可以在子线程显示 本方法会导致报内存泄露, 这是因为为了避免吐司反复显示导致重叠会长期持有Toast引用来保持单例导致, 可以无视或者自己实现吐司
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/-tip-utils/toast.html b/api/-net/com.drake.net.utils/-tip-utils/toast.html new file mode 100644 index 000000000..10408852a --- /dev/null +++ b/api/-net/com.drake.net.utils/-tip-utils/toast.html @@ -0,0 +1,38 @@ + + + + toast + + +
+
+ + +
+
+
+
+
+
+ +
+

toast

+
+
+ +
+
fun toast(message: String?)
+
+

重复显示不会覆盖, 可以在子线程显示 本方法会导致报内存泄露, 这是因为为了避免吐司反复显示导致重叠会长期持有Toast引用来保持单例导致, 可以无视或者自己实现吐司

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/debounce.html b/api/-net/com.drake.net.utils/debounce.html new file mode 100644 index 000000000..97e720161 --- /dev/null +++ b/api/-net/com.drake.net.utils/debounce.html @@ -0,0 +1,38 @@ + + + + debounce + + +
+
+ + +
+
+
+
+
+
+ +
+

debounce

+
+
+ +
+
fun EditText.debounce(timeoutMillis: Long = 800): <ERROR CLASS>
+
+

为EditText的输入框文本变化启用节流阀, 即超过指定时间后(默认800毫秒)的输入框文本变化事件TextWatcher.onTextChanged会被下游收集到

Parameters

timeoutMillis

节流阀超时时间/单位毫秒, 默认值为800

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/fastest.html b/api/-net/com.drake.net.utils/fastest.html new file mode 100644 index 000000000..4e05745a0 --- /dev/null +++ b/api/-net/com.drake.net.utils/fastest.html @@ -0,0 +1,44 @@ + + + + fastest + + +
+
+ + +
+
+
+
+
+
+ +
+

fastest

+
+
+ +
+
suspend fun <T> fastest(listDeferred: List<Deferred<T>>, group: Any? = null): T
+
+

该函数将选择listDeferred中的Deferred执行Deferred.await, 然后将返回最快的结果 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常

Parameters

group

指定该值将在成功返回结果后取消掉对应uid的网络请求

listDeferred

一系列并发任务

+
+ +
+
@JvmName(name = fastestTransform)
suspend fun <T, R> fastest(listDeferred: List<DeferredTransform<T, R>>?, group: Any? = null): R
+
+

该函数将选择listDeferred中的Deferred执行Deferred.await, 然后将返回最快的结果 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常

See also

com.drake.net.transform.DeferredTransform

允许监听Deferred返回数据回调

Parameters

group

指定该值将在成功返回结果后取消掉对应uid的网络请求

listDeferred

一系列并发任务

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/file-name.html b/api/-net/com.drake.net.utils/file-name.html new file mode 100644 index 000000000..4fd682fbb --- /dev/null +++ b/api/-net/com.drake.net.utils/file-name.html @@ -0,0 +1,38 @@ + + + + fileName + + +
+
+ + +
+
+
+
+
+
+ +
+

fileName

+
+
+ +
+
fun Uri.fileName(): String?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/index.html b/api/-net/com.drake.net.utils/index.html new file mode 100644 index 000000000..435a5c973 --- /dev/null +++ b/api/-net/com.drake.net.utils/index.html @@ -0,0 +1,435 @@ + + + + com.drake.net.utils + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net.utils

+
+
+
+
+

Types

+
+
+
+
Https +
Link copied to clipboard
+
+
+
+ +
+
object Https
+
+
+
+
+
+
+ +
+
+
TipUtils +
Link copied to clipboard
+
+
+
+ +
+
object TipUtils
+
+
+
+
+
+
+
+

Functions

+
+
+
+
debounce +
Link copied to clipboard
+
+
+
+ +
+
fun EditText.debounce(timeoutMillis: Long = 800): <ERROR CLASS>
+
+
为EditText的输入框文本变化启用节流阀, 即超过指定时间后(默认800毫秒)的输入框文本变化事件TextWatcher.onTextChanged会被下游收集到
+
+
+
+
+ +
+
+
fastest +
Link copied to clipboard
+
+
+
+ +
+
@JvmName(name = fastestTransform)
suspend fun <T, R> fastest(listDeferred: List<DeferredTransform<T, R>>?, group: Any? = null): R
+
+
该函数将选择listDeferred中的Deferred执行Deferred.await, 然后将返回最快的结果 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常
+
+ +
+
suspend fun <T> fastest(listDeferred: List<Deferred<T>>, group: Any? = null): T
+
+
该函数将选择listDeferred中的Deferred执行Deferred.await, 然后将返回最快的结果 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常
+
+
+
+
+ +
+
+
fileName +
Link copied to clipboard
+
+
+
+ +
+
fun Uri.fileName(): String?
+
+
+
+
+
+
+ +
+
+
isNetworking +
Link copied to clipboard
+
+
+
+ +
+
fun Context.isNetworking(): Boolean
+
+
是否处于联网中
+
+
+
+
+ +
+
+
launchIn +
Link copied to clipboard
+
+
+
+ +
+
inline fun <T> Flow<T>.launchIn(owner: LifecycleOwner? = null, event: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, crossinline action: suspend CoroutineScope.(T) -> Unit): AndroidScope
+
+
Flow直接创建作用域
+
+
+
+
+ +
+
+
md5 +
Link copied to clipboard
+
+
+
+ +
+
fun File.md5(base64: Boolean = false): String?
+
+
返回文件的MD5值
+
+
+
+
+ +
+
+
mediaType +
Link copied to clipboard
+
+
+
+ +
+
fun Uri.mediaType(): MediaType?
+
+
+
+ +
+
fun File.mediaType(): MediaType?
+
+
返回文件的MediaType值, 如果不存在返回null
+
+
+
+
+ +
+
+
runMain +
Link copied to clipboard
+
+
+
+ +
+
fun runMain(block: () -> Unit)
+
+
在主线程运行
+
+
+
+
+ +
+
+
scope +
Link copied to clipboard
+
+
+
+ +
+
fun scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+
异步作用域该作用域生命周期跟随整个应用, 注意内存泄漏
+
+ +
+
fun PageRefreshLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): PageCoroutineScope
+
+
PageRefreshLayout的异步作用域
  1. 下拉刷新自动结束

  2. 上拉加载自动结束

  3. 捕获异常

  4. 打印异常日志

  5. 吐司部分异常com.drake.net.interfaces.NetErrorHandler.onStateError

  6. 判断添加还是覆盖数据

  7. 自动显示缺省页

布局被销毁或者界面关闭作用域被取消
+
+ +
+
fun StateLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
自动处理缺省页的异步作用域 作用域开始执行时显示加载中缺省页 作用域正常结束时显示成功缺省页 作用域抛出异常时显示错误缺省页 并且自动吐司错误信息, 可配置 com.drake.net.interfaces.NetErrorHandler.onStateError 自动打印异常日志 布局被销毁或者界面关闭作用域被取消
+
+
+
+
+ +
+
+
scopeDialog +
Link copied to clipboard
+
+
+
+ +
+
fun Fragment.scopeDialog(dialog: Dialog? = null, cancelable: Boolean = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
作用域开始时自动显示加载对话框, 结束时自动关闭加载对话框 可以设置全局对话框 com.drake.net.NetConfig.dialogFactory 对话框被取消或者界面关闭作用域被取消
+
+ +
+
fun FragmentActivity.scopeDialog(dialog: Dialog? = null, cancelable: Boolean = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
作用域开始时自动显示加载对话框, 结束时自动关闭加载对话框 可以设置全局对话框 com.drake.net.NetConfig.dialogFactory 对话框被取消或者界面关闭作用域被取消
+
+
+
+
+ +
+
+
scopeLife +
Link copied to clipboard
+
+
+
+ +
+
fun Fragment.scopeLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+
异步作用域该作用域生命周期跟随Fragment
+
+ +
+
fun LifecycleOwner.scopeLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+
异步作用域该作用域生命周期跟随LifecycleOwner
+
+
+
+
+ +
+
+
scopeNet +
Link copied to clipboard
+
+
+
+ +
+
fun scopeNet(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
该函数比scope多了以下功能该作用域生命周期跟随整个应用, 注意内存泄漏
+
+
+
+
+ +
+
+
scopeNetLife +
Link copied to clipboard
+
+
+
+ +
+
fun View.scopeNetLife(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): ViewCoroutineScope
+
+
视图作用域 会在视图销毁时自动取消作用域
+
+ +
+
fun Fragment.scopeNetLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
scopeNetLife功能相同, 只是接受者为Fragment
+
+ +
+
fun LifecycleOwner.scopeNetLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+
该函数比scopeNet多了自动取消作用域功能该作用域生命周期跟随LifecycleOwner.
+
+
+
+
+ +
+
+
toRequestBody +
Link copied to clipboard
+
+
+
+ +
+
fun Uri.toRequestBody(): RequestBody
+
+
当Uri指向的文件不存在时将抛出异常FileNotFoundException
+
+ +
+
fun File.toRequestBody(contentType: MediaType? = null): RequestBody
+
+
创建File的RequestBody
+
+
+
+
+ +
+
+
withDefault +
Link copied to clipboard
+
+
+
+ +
+
suspend fun <T> withDefault(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+
切换到默认调度器
+
+
+
+
+ +
+
+
withIO +
Link copied to clipboard
+
+
+
+ +
+
suspend fun <T> withIO(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+
切换到IO程调度器
+
+
+
+
+ +
+
+
withMain +
Link copied to clipboard
+
+
+
+ +
+
suspend fun <T> withMain(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+
切换到主线程调度器
+
+
+
+
+ +
+
+
withUnconfined +
Link copied to clipboard
+
+
+
+ +
+
suspend fun <T> withUnconfined(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+
切换到没有限制的调度器
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/is-networking.html b/api/-net/com.drake.net.utils/is-networking.html new file mode 100644 index 000000000..f844b4dab --- /dev/null +++ b/api/-net/com.drake.net.utils/is-networking.html @@ -0,0 +1,38 @@ + + + + isNetworking + + +
+
+ + +
+
+
+
+
+
+ +
+

isNetworking

+
+
+ +
+
fun Context.isNetworking(): Boolean
+
+

是否处于联网中

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/launch-in.html b/api/-net/com.drake.net.utils/launch-in.html new file mode 100644 index 000000000..be8c84f4d --- /dev/null +++ b/api/-net/com.drake.net.utils/launch-in.html @@ -0,0 +1,38 @@ + + + + launchIn + + +
+
+ + +
+
+
+
+
+
+ +
+

launchIn

+
+
+ +
+
inline fun <T> Flow<T>.launchIn(owner: LifecycleOwner? = null, event: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, crossinline action: suspend CoroutineScope.(T) -> Unit): AndroidScope
+
+

Flow直接创建作用域

Parameters

owner

跟随的生命周期组件

event

销毁时机

dispatcher

指定调度器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/md5.html b/api/-net/com.drake.net.utils/md5.html new file mode 100644 index 000000000..f16a57c68 --- /dev/null +++ b/api/-net/com.drake.net.utils/md5.html @@ -0,0 +1,38 @@ + + + + md5 + + +
+
+ + +
+
+
+
+
+
+ +
+

md5

+
+
+ +
+
fun File.md5(base64: Boolean = false): String?
+
+

返回文件的MD5值

Parameters

base64

是否将md5值进行base64编码, 否则将返回hex编码

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/media-type.html b/api/-net/com.drake.net.utils/media-type.html new file mode 100644 index 000000000..5a360db52 --- /dev/null +++ b/api/-net/com.drake.net.utils/media-type.html @@ -0,0 +1,44 @@ + + + + mediaType + + +
+
+ + +
+
+
+
+
+
+ +
+

mediaType

+
+
+ +
+
fun File.mediaType(): MediaType?
+
+

返回文件的MediaType值, 如果不存在返回null

+
+ +
+
fun Uri.mediaType(): MediaType?
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/run-main.html b/api/-net/com.drake.net.utils/run-main.html new file mode 100644 index 000000000..d371fbae0 --- /dev/null +++ b/api/-net/com.drake.net.utils/run-main.html @@ -0,0 +1,38 @@ + + + + runMain + + +
+
+ + +
+
+
+
+
+
+ +
+

runMain

+
+
+ +
+
fun runMain(block: () -> Unit)
+
+

在主线程运行

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/scope-dialog.html b/api/-net/com.drake.net.utils/scope-dialog.html new file mode 100644 index 000000000..08a1c29d1 --- /dev/null +++ b/api/-net/com.drake.net.utils/scope-dialog.html @@ -0,0 +1,38 @@ + + + + scopeDialog + + +
+
+ + +
+
+
+
+
+
+ +
+

scopeDialog

+
+
+ +
+
fun FragmentActivity.scopeDialog(dialog: Dialog? = null, cancelable: Boolean = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
fun Fragment.scopeDialog(dialog: Dialog? = null, cancelable: Boolean = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+

作用域开始时自动显示加载对话框, 结束时自动关闭加载对话框 可以设置全局对话框 com.drake.net.NetConfig.dialogFactory 对话框被取消或者界面关闭作用域被取消

Parameters

dialog

仅该作用域使用的对话框

cancelable

对话框是否可取消

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/scope-life.html b/api/-net/com.drake.net.utils/scope-life.html new file mode 100644 index 000000000..bad01d5e7 --- /dev/null +++ b/api/-net/com.drake.net.utils/scope-life.html @@ -0,0 +1,44 @@ + + + + scopeLife + + +
+
+ + +
+
+
+
+
+
+ +
+

scopeLife

+
+
+ +
+
fun LifecycleOwner.scopeLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+

异步作用域

该作用域生命周期跟随LifecycleOwner

Parameters

lifeEvent

生命周期事件, 默认为Lifecycle.Event.ON_DESTROY下取消协程作用域

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
fun Fragment.scopeLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+

异步作用域

该作用域生命周期跟随Fragment

Parameters

lifeEvent

生命周期事件, 默认为Lifecycle.Event.ON_DESTROY下取消协程作用域

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/scope-net-life.html b/api/-net/com.drake.net.utils/scope-net-life.html new file mode 100644 index 000000000..f81e6acf4 --- /dev/null +++ b/api/-net/com.drake.net.utils/scope-net-life.html @@ -0,0 +1,50 @@ + + + + scopeNetLife + + +
+
+ + +
+
+
+
+
+
+ +
+

scopeNetLife

+
+
+ +
+
fun View.scopeNetLife(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): ViewCoroutineScope
+
+

视图作用域 会在视图销毁时自动取消作用域

Parameters

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
fun LifecycleOwner.scopeNetLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+

该函数比scopeNet多了自动取消作用域功能

该作用域生命周期跟随LifecycleOwner. 比如传入Activity会默认在FragmentActivity.onDestroy时取消网络请求.

Parameters

<receiver>

可传入FragmentActivity/AppCompatActivity, 或者其他的实现了LifecycleOwner的类

lifeEvent

指定LifecycleOwner处于生命周期下取消网络请求/作用域

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
fun Fragment.scopeNetLife(lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+

scopeNetLife功能相同, 只是接受者为Fragment

Parameters

lifeEvent

生命周期事件, 默认为Lifecycle.Event.ON_DESTROY下取消协程作用域

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/scope-net.html b/api/-net/com.drake.net.utils/scope-net.html new file mode 100644 index 000000000..584203f46 --- /dev/null +++ b/api/-net/com.drake.net.utils/scope-net.html @@ -0,0 +1,38 @@ + + + + scopeNet + + +
+
+ + +
+
+
+
+
+
+ +
+

scopeNet

+
+
+ +
+
fun scopeNet(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+

该函数比scope多了以下功能

该作用域生命周期跟随整个应用, 注意内存泄漏

Parameters

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/scope.html b/api/-net/com.drake.net.utils/scope.html new file mode 100644 index 000000000..459f82093 --- /dev/null +++ b/api/-net/com.drake.net.utils/scope.html @@ -0,0 +1,50 @@ + + + + scope + + +
+
+ + +
+
+
+
+
+
+ +
+

scope

+
+
+ +
+
fun scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): AndroidScope
+
+

异步作用域

该作用域生命周期跟随整个应用, 注意内存泄漏

Parameters

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
fun StateLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): NetCoroutineScope
+
+

自动处理缺省页的异步作用域 作用域开始执行时显示加载中缺省页 作用域正常结束时显示成功缺省页 作用域抛出异常时显示错误缺省页 并且自动吐司错误信息, 可配置 com.drake.net.interfaces.NetErrorHandler.onStateError 自动打印异常日志 布局被销毁或者界面关闭作用域被取消

Parameters

<receiver>

当前视图会被缺省页包裹

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
fun PageRefreshLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> Unit): PageCoroutineScope
+
+

PageRefreshLayout的异步作用域

  1. 下拉刷新自动结束

  2. 上拉加载自动结束

  3. 捕获异常

  4. 打印异常日志

  5. 吐司部分异常com.drake.net.interfaces.NetErrorHandler.onStateError

  6. 判断添加还是覆盖数据

  7. 自动显示缺省页

布局被销毁或者界面关闭作用域被取消

Parameters

dispatcher

调度器, 默认运行在Dispatchers.Main即主线程下

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/to-request-body.html b/api/-net/com.drake.net.utils/to-request-body.html new file mode 100644 index 000000000..b058a5852 --- /dev/null +++ b/api/-net/com.drake.net.utils/to-request-body.html @@ -0,0 +1,44 @@ + + + + toRequestBody + + +
+
+ + +
+
+
+
+
+
+ +
+

toRequestBody

+
+
+ +
+
fun File.toRequestBody(contentType: MediaType? = null): RequestBody
+
+

创建File的RequestBody

Parameters

contentType

如果为null则通过判断扩展名来生成MediaType

+
+ +
+
fun Uri.toRequestBody(): RequestBody
+
+

当Uri指向的文件不存在时将抛出异常FileNotFoundException

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/with-default.html b/api/-net/com.drake.net.utils/with-default.html new file mode 100644 index 000000000..e1c24f7f3 --- /dev/null +++ b/api/-net/com.drake.net.utils/with-default.html @@ -0,0 +1,38 @@ + + + + withDefault + + +
+
+ + +
+
+
+
+
+
+ +
+

withDefault

+
+
+ +
+
suspend fun <T> withDefault(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+

切换到默认调度器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/with-i-o.html b/api/-net/com.drake.net.utils/with-i-o.html new file mode 100644 index 000000000..85c0a6c74 --- /dev/null +++ b/api/-net/com.drake.net.utils/with-i-o.html @@ -0,0 +1,38 @@ + + + + withIO + + +
+
+ + +
+
+
+
+
+
+ +
+

withIO

+
+
+ +
+
suspend fun <T> withIO(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+

切换到IO程调度器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/with-main.html b/api/-net/com.drake.net.utils/with-main.html new file mode 100644 index 000000000..048bf6e3a --- /dev/null +++ b/api/-net/com.drake.net.utils/with-main.html @@ -0,0 +1,38 @@ + + + + withMain + + +
+
+ + +
+
+
+
+
+
+ +
+

withMain

+
+
+ +
+
suspend fun <T> withMain(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+

切换到主线程调度器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net.utils/with-unconfined.html b/api/-net/com.drake.net.utils/with-unconfined.html new file mode 100644 index 000000000..15511996c --- /dev/null +++ b/api/-net/com.drake.net.utils/with-unconfined.html @@ -0,0 +1,38 @@ + + + + withUnconfined + + +
+
+ + +
+
+
+
+
+
+ +
+

withUnconfined

+
+
+ +
+
suspend fun <T> withUnconfined(block: suspend CoroutineScope.() -> T): <ERROR CLASS>
+
+

切换到没有限制的调度器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-delete.html b/api/-net/com.drake.net/-delete.html new file mode 100644 index 000000000..0409310c1 --- /dev/null +++ b/api/-net/com.drake.net/-delete.html @@ -0,0 +1,38 @@ + + + + Delete + + +
+
+ + +
+
+
+
+
+
+ +
+

Delete

+
+
+ +
+
inline fun <M> CoroutineScope.Delete(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-get.html b/api/-net/com.drake.net/-get.html new file mode 100644 index 000000000..ff16d45b3 --- /dev/null +++ b/api/-net/com.drake.net/-get.html @@ -0,0 +1,38 @@ + + + + Get + + +
+
+ + +
+
+
+
+
+
+ +
+

Get

+
+
+ +
+
inline fun <M> CoroutineScope.Get(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-head.html b/api/-net/com.drake.net/-head.html new file mode 100644 index 000000000..cd5aade5c --- /dev/null +++ b/api/-net/com.drake.net/-head.html @@ -0,0 +1,38 @@ + + + + Head + + +
+
+ + +
+
+
+
+
+
+ +
+

Head

+
+
+ +
+
inline fun <M> CoroutineScope.Head(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/-t-a-g.html b/api/-net/com.drake.net/-net-config/-t-a-g.html new file mode 100644 index 000000000..3481835c0 --- /dev/null +++ b/api/-net/com.drake.net/-net-config/-t-a-g.html @@ -0,0 +1,38 @@ + + + + TAG + + +
+
+ + +
+
+
+
+
+
+ +
+

TAG

+
+
+ +
+
var TAG: String
+
+

网络异常日志的标签

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/app.html b/api/-net/com.drake.net/-net-config/app.html new file mode 100644 index 000000000..e8596a62c --- /dev/null +++ b/api/-net/com.drake.net/-net-config/app.html @@ -0,0 +1,38 @@ + + + + app + + +
+
+ + +
+
+
+
+
+
+ +
+

app

+
+
+ +
+
lateinit var app: Context
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/converter.html b/api/-net/com.drake.net/-net-config/converter.html new file mode 100644 index 000000000..e07dcbfdb --- /dev/null +++ b/api/-net/com.drake.net/-net-config/converter.html @@ -0,0 +1,38 @@ + + + + converter + + +
+
+ + +
+
+
+
+
+
+ +
+

converter

+
+
+ +
+
var converter: NetConverter
+
+

响应数据转换器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/debug.html b/api/-net/com.drake.net/-net-config/debug.html new file mode 100644 index 000000000..6351f5431 --- /dev/null +++ b/api/-net/com.drake.net/-net-config/debug.html @@ -0,0 +1,38 @@ + + + + debug + + +
+
+ + +
+
+
+
+
+
+ +
+

debug

+
+
+ +
+
var debug: Boolean = true
+
+

是否启用日志

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/dialog-factory.html b/api/-net/com.drake.net/-net-config/dialog-factory.html new file mode 100644 index 000000000..cfbca860d --- /dev/null +++ b/api/-net/com.drake.net/-net-config/dialog-factory.html @@ -0,0 +1,38 @@ + + + + dialogFactory + + +
+
+ + +
+
+
+
+
+
+ +
+

dialogFactory

+
+
+ +
+
var dialogFactory: NetDialogFactory
+
+

请求对话框构建工厂

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/error-handler.html b/api/-net/com.drake.net/-net-config/error-handler.html new file mode 100644 index 000000000..1ffbdd865 --- /dev/null +++ b/api/-net/com.drake.net/-net-config/error-handler.html @@ -0,0 +1,38 @@ + + + + errorHandler + + +
+
+ + +
+
+
+
+
+
+ +
+

errorHandler

+
+
+ +
+
var errorHandler: NetErrorHandler
+
+

错误处理器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/host.html b/api/-net/com.drake.net/-net-config/host.html new file mode 100644 index 000000000..5441d2a30 --- /dev/null +++ b/api/-net/com.drake.net/-net-config/host.html @@ -0,0 +1,38 @@ + + + + host + + +
+
+ + +
+
+
+
+
+
+ +
+

host

+
+
+ +
+
var host: String
+
+

全局域名

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/index.html b/api/-net/com.drake.net/-net-config/index.html new file mode 100644 index 000000000..7b1cb4c4c --- /dev/null +++ b/api/-net/com.drake.net/-net-config/index.html @@ -0,0 +1,195 @@ + + + + NetConfig + + +
+
+ + +
+
+
+
+
+
+ +
+

NetConfig

+
object NetConfig

Net的全局配置

+
+
+
+
+

Functions

+
+
+
+
initialize +
Link copied to clipboard
+
+
+
+ +
+
fun initialize(host: String = "", context: Context? = null, config: OkHttpClient.Builder.() -> Unit = {})
+
+
初始化框架 不初始化也可以使用, 但是App使用多进程情况下要求为NetConfig.host或者context赋值, 否则会导致无法正常吐司或其他意外问题
+
+ +
+
fun initialize(host: String = "", context: Context? = null, config: OkHttpClient.Builder)
+
+
初始化框架 不初始化也可以使用, 但是App使用多进程情况下要求为NetConfig.host或者context赋值, 否则会导致无法正常吐司或其他意外问题
+
+
+
+
+
+

Properties

+
+
+
+
app +
Link copied to clipboard
+
+
+
+
lateinit var app: Context
+
+
+
+
+ +
+
+
converter +
Link copied to clipboard
+
+
+
+
var converter: NetConverter
响应数据转换器
+
+
+
+
+ +
+
+
debug +
Link copied to clipboard
+
+
+
+
var debug: Boolean = true
是否启用日志
+
+
+
+
+ +
+
+
dialogFactory +
Link copied to clipboard
+
+
+
+
var dialogFactory: NetDialogFactory
请求对话框构建工厂
+
+
+
+
+ +
+
+
errorHandler +
Link copied to clipboard
+
+
+
+
var errorHandler: NetErrorHandler
错误处理器
+
+
+
+
+ +
+
+
host +
Link copied to clipboard
+
+
+
+
var host: String
全局域名
+
+
+
+
+ +
+
+
okHttpClient +
Link copied to clipboard
+
+
+
+
var okHttpClient: OkHttpClient
全局单例请求客户端
+
+
+
+
+ +
+
+
requestInterceptor +
Link copied to clipboard
+
+
+
+
var requestInterceptor: RequestInterceptor? = null
请求拦截器
+
+
+
+
+ +
+
+
runningCalls +
Link copied to clipboard
+
+
+
+
var runningCalls: ConcurrentLinkedQueue<WeakReference<Call>>
运行中的请求
+
+
+
+
+ +
+
+
TAG +
Link copied to clipboard
+
+
+
+
var TAG: String
网络异常日志的标签
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/initialize.html b/api/-net/com.drake.net/-net-config/initialize.html new file mode 100644 index 000000000..adab8c275 --- /dev/null +++ b/api/-net/com.drake.net/-net-config/initialize.html @@ -0,0 +1,44 @@ + + + + initialize + + +
+
+ + +
+
+
+
+
+
+ +
+

initialize

+
+
+ +
+
fun initialize(host: String = "", context: Context? = null, config: OkHttpClient.Builder.() -> Unit = {})
+
+

初始化框架 不初始化也可以使用, 但是App使用多进程情况下要求为NetConfig.host或者context赋值, 否则会导致无法正常吐司或其他意外问题

Parameters

host

请求url的主机名

context

如果应用存在多进程请指定此参数初始化NetConfig.app

config

进行配置网络请求

+
+ +
+
fun initialize(host: String = "", context: Context? = null, config: OkHttpClient.Builder)
+
+

初始化框架 不初始化也可以使用, 但是App使用多进程情况下要求为NetConfig.host或者context赋值, 否则会导致无法正常吐司或其他意外问题

Parameters

host

请求url的主机名, 该参数会在每次请求时自动和请求路径进行拼接(如果路径包含https/http则不会拼接)

context

如果应用存在多进程请指定此参数初始化NetConfig.app

config

进行配置网络请求

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/ok-http-client.html b/api/-net/com.drake.net/-net-config/ok-http-client.html new file mode 100644 index 000000000..48de33e3e --- /dev/null +++ b/api/-net/com.drake.net/-net-config/ok-http-client.html @@ -0,0 +1,38 @@ + + + + okHttpClient + + +
+
+ + +
+
+
+
+
+
+ +
+

okHttpClient

+
+
+ +
+
var okHttpClient: OkHttpClient
+
+

全局单例请求客户端

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/request-interceptor.html b/api/-net/com.drake.net/-net-config/request-interceptor.html new file mode 100644 index 000000000..23f5edea9 --- /dev/null +++ b/api/-net/com.drake.net/-net-config/request-interceptor.html @@ -0,0 +1,38 @@ + + + + requestInterceptor + + +
+
+ + +
+
+
+
+
+
+ +
+

requestInterceptor

+
+
+ +
+
var requestInterceptor: RequestInterceptor? = null
+
+

请求拦截器

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net-config/running-calls.html b/api/-net/com.drake.net/-net-config/running-calls.html new file mode 100644 index 000000000..f1d075efc --- /dev/null +++ b/api/-net/com.drake.net/-net-config/running-calls.html @@ -0,0 +1,38 @@ + + + + runningCalls + + +
+
+ + +
+
+
+
+
+
+ +
+

runningCalls

+
+
+ +
+
var runningCalls: ConcurrentLinkedQueue<WeakReference<Call>>
+
+

运行中的请求

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/add-download-listener.html b/api/-net/com.drake.net/-net/add-download-listener.html new file mode 100644 index 000000000..71f9e27cf --- /dev/null +++ b/api/-net/com.drake.net/-net/add-download-listener.html @@ -0,0 +1,38 @@ + + + + addDownloadListener + + +
+
+ + +
+
+
+
+
+
+ +
+

addDownloadListener

+
+
+ +
+
fun addDownloadListener(id: Any, progressListener: ProgressListener): Boolean
+
+

监听正在请求的下载进度

See also

Parameters

id

请求的Id

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/add-upload-listener.html b/api/-net/com.drake.net/-net/add-upload-listener.html new file mode 100644 index 000000000..51d998425 --- /dev/null +++ b/api/-net/com.drake.net/-net/add-upload-listener.html @@ -0,0 +1,38 @@ + + + + addUploadListener + + +
+
+ + +
+
+
+
+
+
+ +
+

addUploadListener

+
+
+ +
+
fun addUploadListener(id: Any, progressListener: ProgressListener): Boolean
+
+

监听正在请求的上传进度

See also

Parameters

id

请求的Id

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/cancel-all.html b/api/-net/com.drake.net/-net/cancel-all.html new file mode 100644 index 000000000..4d6a10889 --- /dev/null +++ b/api/-net/com.drake.net/-net/cancel-all.html @@ -0,0 +1,38 @@ + + + + cancelAll + + +
+
+ + +
+
+
+
+
+
+ +
+

cancelAll

+
+
+ +
+
fun cancelAll()
+
+

取消全部网络请求

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/cancel-group.html b/api/-net/com.drake.net/-net/cancel-group.html new file mode 100644 index 000000000..9449e4d1c --- /dev/null +++ b/api/-net/com.drake.net/-net/cancel-group.html @@ -0,0 +1,38 @@ + + + + cancelGroup + + +
+
+ + +
+
+
+
+
+
+ +
+

cancelGroup

+
+
+ +
+
fun cancelGroup(group: Any?): Boolean
+
+

根据分组取消网络请求

Return

如果成功取消返回true, 无论取消个数

See also

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/cancel-id.html b/api/-net/com.drake.net/-net/cancel-id.html new file mode 100644 index 000000000..0ad77473b --- /dev/null +++ b/api/-net/com.drake.net/-net/cancel-id.html @@ -0,0 +1,38 @@ + + + + cancelId + + +
+
+ + +
+
+
+
+
+
+ +
+

cancelId

+
+
+ +
+
fun cancelId(id: Any?): Boolean
+
+

取消指定的网络请求, Id理论上是唯一的, 所以该函数一次只能取消一个请求

Return

如果成功取消返回true

See also

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/debug.html b/api/-net/com.drake.net/-net/debug.html new file mode 100644 index 000000000..97023a8fb --- /dev/null +++ b/api/-net/com.drake.net/-net/debug.html @@ -0,0 +1,38 @@ + + + + debug + + +
+
+ + +
+
+
+
+
+
+ +
+

debug

+
+
+ +
+
fun debug(message: Any)
+
+

输出异常日志

See also

Parameters

message

如果非Throwable则会自动追加代码位置(文件:行号)

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/delete.html b/api/-net/com.drake.net/-net/delete.html new file mode 100644 index 000000000..784520733 --- /dev/null +++ b/api/-net/com.drake.net/-net/delete.html @@ -0,0 +1,38 @@ + + + + delete + + +
+
+ + +
+
+
+
+
+
+ +
+

delete

+
+
+ +
+
fun delete(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/get-request-by-group.html b/api/-net/com.drake.net/-net/get-request-by-group.html new file mode 100644 index 000000000..24d80004e --- /dev/null +++ b/api/-net/com.drake.net/-net/get-request-by-group.html @@ -0,0 +1,38 @@ + + + + getRequestByGroup + + +
+
+ + +
+
+
+
+
+
+ +
+

getRequestByGroup

+
+
+ +
+
fun getRequestByGroup(group: Any): MutableList<Request>
+
+

根据Group获取请求对象

See also

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/get-request-by-id.html b/api/-net/com.drake.net/-net/get-request-by-id.html new file mode 100644 index 000000000..3686a1706 --- /dev/null +++ b/api/-net/com.drake.net/-net/get-request-by-id.html @@ -0,0 +1,38 @@ + + + + getRequestById + + +
+
+ + +
+
+
+
+
+
+ +
+

getRequestById

+
+
+ +
+
fun getRequestById(id: Any): Request?
+
+

根据ID获取请求对象

See also

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/get.html b/api/-net/com.drake.net/-net/get.html new file mode 100644 index 000000000..01620be22 --- /dev/null +++ b/api/-net/com.drake.net/-net/get.html @@ -0,0 +1,38 @@ + + + + get + + +
+
+ + +
+
+
+
+
+
+ +
+

get

+
+
+ +
+
fun get(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/head.html b/api/-net/com.drake.net/-net/head.html new file mode 100644 index 000000000..464bc3912 --- /dev/null +++ b/api/-net/com.drake.net/-net/head.html @@ -0,0 +1,38 @@ + + + + head + + +
+
+ + +
+
+
+
+
+
+ +
+

head

+
+
+ +
+
fun head(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/index.html b/api/-net/com.drake.net/-net/index.html new file mode 100644 index 000000000..bb1e19599 --- /dev/null +++ b/api/-net/com.drake.net/-net/index.html @@ -0,0 +1,346 @@ + + + + Net + + +
+
+ + +
+
+
+
+
+
+ +
+

Net

+
object Net
+
+
+
+
+

Functions

+
+
+
+
addDownloadListener +
Link copied to clipboard
+
+
+
+ +
+
fun addDownloadListener(id: Any, progressListener: ProgressListener): Boolean
+
+
监听正在请求的下载进度
+
+
+
+
+ +
+
+
addUploadListener +
Link copied to clipboard
+
+
+
+ +
+
fun addUploadListener(id: Any, progressListener: ProgressListener): Boolean
+
+
监听正在请求的上传进度
+
+
+
+
+ +
+
+
cancelAll +
Link copied to clipboard
+
+
+
+ +
+
fun cancelAll()
+
+
取消全部网络请求
+
+
+
+
+ +
+
+
cancelGroup +
Link copied to clipboard
+
+
+
+ +
+
fun cancelGroup(group: Any?): Boolean
+
+
根据分组取消网络请求
+
+
+
+
+ +
+
+
cancelId +
Link copied to clipboard
+
+
+
+ +
+
fun cancelId(id: Any?): Boolean
+
+
取消指定的网络请求, Id理论上是唯一的, 所以该函数一次只能取消一个请求
+
+
+
+
+ +
+
+
debug +
Link copied to clipboard
+
+
+
+ +
+
fun debug(message: Any)
+
+
输出异常日志
+
+
+
+
+ +
+
+
delete +
Link copied to clipboard
+
+
+
+ +
+
fun delete(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+ +
+
+
get +
Link copied to clipboard
+
+
+
+ +
+
fun get(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+ +
+
+
getRequestByGroup +
Link copied to clipboard
+
+
+
+ +
+
fun getRequestByGroup(group: Any): MutableList<Request>
+
+
根据Group获取请求对象
+
+
+
+
+ +
+
+
getRequestById +
Link copied to clipboard
+
+
+
+ +
+
fun getRequestById(id: Any): Request?
+
+
根据ID获取请求对象
+
+
+
+
+ +
+
+
head +
Link copied to clipboard
+
+
+
+ +
+
fun head(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+ +
+
+
options +
Link copied to clipboard
+
+
+
+ +
+
fun options(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+ +
+
+
patch +
Link copied to clipboard
+
+
+
+ +
+
fun patch(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+ +
+
+
post +
Link copied to clipboard
+
+
+
+ +
+
fun post(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+ +
+
+
put +
Link copied to clipboard
+
+
+
+ +
+
fun put(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+ +
+
+
removeDownloadListener +
Link copied to clipboard
+
+
+
+ +
+
fun removeDownloadListener(id: Any, progressListener: ProgressListener): Boolean
+
+
删除正在请求的下载进度监听器
+
+
+
+
+ +
+
+
removeUploadListener +
Link copied to clipboard
+
+
+
+ +
+
fun removeUploadListener(id: Any, progressListener: ProgressListener): Boolean
+
+
删除正在请求的上传进度监听器
+
+
+
+
+ +
+
+
trace +
Link copied to clipboard
+
+
+
+ +
+
fun trace(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+
同步网络请求
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/options.html b/api/-net/com.drake.net/-net/options.html new file mode 100644 index 000000000..d37e8d5cd --- /dev/null +++ b/api/-net/com.drake.net/-net/options.html @@ -0,0 +1,38 @@ + + + + options + + +
+
+ + +
+
+
+
+
+
+ +
+

options

+
+
+ +
+
fun options(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/patch.html b/api/-net/com.drake.net/-net/patch.html new file mode 100644 index 000000000..e9fc3b4bd --- /dev/null +++ b/api/-net/com.drake.net/-net/patch.html @@ -0,0 +1,38 @@ + + + + patch + + +
+
+ + +
+
+
+
+
+
+ +
+

patch

+
+
+ +
+
fun patch(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/post.html b/api/-net/com.drake.net/-net/post.html new file mode 100644 index 000000000..e5929719f --- /dev/null +++ b/api/-net/com.drake.net/-net/post.html @@ -0,0 +1,38 @@ + + + + post + + +
+
+ + +
+
+
+
+
+
+ +
+

post

+
+
+ +
+
fun post(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/put.html b/api/-net/com.drake.net/-net/put.html new file mode 100644 index 000000000..b2690c30e --- /dev/null +++ b/api/-net/com.drake.net/-net/put.html @@ -0,0 +1,38 @@ + + + + put + + +
+
+ + +
+
+
+
+
+
+ +
+

put

+
+
+ +
+
fun put(path: String, tag: Any? = null, block: BodyRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/remove-download-listener.html b/api/-net/com.drake.net/-net/remove-download-listener.html new file mode 100644 index 000000000..c82d1c4a4 --- /dev/null +++ b/api/-net/com.drake.net/-net/remove-download-listener.html @@ -0,0 +1,38 @@ + + + + removeDownloadListener + + +
+
+ + +
+
+
+
+
+
+ +
+

removeDownloadListener

+
+
+ +
+
fun removeDownloadListener(id: Any, progressListener: ProgressListener): Boolean
+
+

删除正在请求的下载进度监听器

See also

Parameters

id

请求的Id

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/remove-upload-listener.html b/api/-net/com.drake.net/-net/remove-upload-listener.html new file mode 100644 index 000000000..4c805b3f3 --- /dev/null +++ b/api/-net/com.drake.net/-net/remove-upload-listener.html @@ -0,0 +1,38 @@ + + + + removeUploadListener + + +
+
+ + +
+
+
+
+
+
+ +
+

removeUploadListener

+
+
+ +
+
fun removeUploadListener(id: Any, progressListener: ProgressListener): Boolean
+
+

删除正在请求的上传进度监听器

See also

Parameters

id

请求的Id

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-net/trace.html b/api/-net/com.drake.net/-net/trace.html new file mode 100644 index 000000000..1cb3695fa --- /dev/null +++ b/api/-net/com.drake.net/-net/trace.html @@ -0,0 +1,38 @@ + + + + trace + + +
+
+ + +
+
+
+
+
+
+ +
+

trace

+
+
+ +
+
fun trace(path: String, tag: Any? = null, block: UrlRequest.() -> Unit? = null): <ERROR CLASS>
+
+

同步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request请求, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-options.html b/api/-net/com.drake.net/-options.html new file mode 100644 index 000000000..a264dd05c --- /dev/null +++ b/api/-net/com.drake.net/-options.html @@ -0,0 +1,38 @@ + + + + Options + + +
+
+ + +
+
+
+
+
+
+ +
+

Options

+
+
+ +
+
inline fun <M> CoroutineScope.Options(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-patch.html b/api/-net/com.drake.net/-patch.html new file mode 100644 index 000000000..d1a7256f7 --- /dev/null +++ b/api/-net/com.drake.net/-patch.html @@ -0,0 +1,38 @@ + + + + Patch + + +
+
+ + +
+
+
+
+
+
+ +
+

Patch

+
+
+ +
+
inline fun <M> CoroutineScope.Patch(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-post.html b/api/-net/com.drake.net/-post.html new file mode 100644 index 000000000..6977f655e --- /dev/null +++ b/api/-net/com.drake.net/-post.html @@ -0,0 +1,38 @@ + + + + Post + + +
+
+ + +
+
+
+
+
+
+ +
+

Post

+
+
+ +
+
inline fun <M> CoroutineScope.Post(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-put.html b/api/-net/com.drake.net/-put.html new file mode 100644 index 000000000..4905aa85c --- /dev/null +++ b/api/-net/com.drake.net/-put.html @@ -0,0 +1,38 @@ + + + + Put + + +
+
+ + +
+
+
+
+
+
+ +
+

Put

+
+
+ +
+
inline fun <M> CoroutineScope.Put(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/-trace.html b/api/-net/com.drake.net/-trace.html new file mode 100644 index 000000000..1e4d558de --- /dev/null +++ b/api/-net/com.drake.net/-trace.html @@ -0,0 +1,38 @@ + + + + Trace + + +
+
+ + +
+
+
+
+
+
+ +
+

Trace

+
+
+ +
+
inline fun <M> CoroutineScope.Trace(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+

异步网络请求

Parameters

path

请求路径, 如果其不包含http/https则会自动拼接NetConfig.host

tag

可以传递对象给Request, 一般用于在拦截器/转换器中进行针对某个接口行为判断

block

函数中可以配置请求参数

+
+ +
+
+ + + diff --git a/api/-net/com.drake.net/index.html b/api/-net/com.drake.net/index.html new file mode 100644 index 000000000..5707b2cad --- /dev/null +++ b/api/-net/com.drake.net/index.html @@ -0,0 +1,211 @@ + + + + com.drake.net + + +
+
+ + +
+
+
+
+
+
+ +
+

Package com.drake.net

+
+
+
+
+

Types

+
+
+
+
Net +
Link copied to clipboard
+
+
+
+ +
+
object Net
+
+
+
+
+
+
+ +
+
+
NetConfig +
Link copied to clipboard
+
+
+
+ +
+
object NetConfig
+
+
Net的全局配置
+
+
+
+
+
+

Functions

+
+
+
+
Delete +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Delete(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+ +
+
+
Get +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Get(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+ +
+
+
Head +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Head(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+ +
+
+
Options +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Options(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+ +
+
+
Patch +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Patch(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+ +
+
+
Post +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Post(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+ +
+
+
Put +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Put(path: String, tag: Any? = null, noinline block: BodyRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+ +
+
+
Trace +
Link copied to clipboard
+
+
+
+ +
+
inline fun <M> CoroutineScope.Trace(path: String, tag: Any? = null, noinline block: UrlRequest.() -> Unit? = null): Deferred<M>
+
+
异步网络请求
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/okhttp3/-ok-http-utils/add-lenient.html b/api/-net/okhttp3/-ok-http-utils/add-lenient.html new file mode 100644 index 000000000..0f7d4a0cc --- /dev/null +++ b/api/-net/okhttp3/-ok-http-utils/add-lenient.html @@ -0,0 +1,38 @@ + + + + addLenient + + +
+
+ + +
+
+
+
+
+
+ +
+

addLenient

+
+
+ +
+
open fun addLenient(builder: Headers.Builder, line: String): Headers.Builder
+
+
+
+ +
+
+ + + diff --git a/api/-net/okhttp3/-ok-http-utils/disk-lru-cache.html b/api/-net/okhttp3/-ok-http-utils/disk-lru-cache.html new file mode 100644 index 000000000..518a0bd35 --- /dev/null +++ b/api/-net/okhttp3/-ok-http-utils/disk-lru-cache.html @@ -0,0 +1,38 @@ + + + + diskLruCache + + +
+
+ + +
+
+
+
+
+
+ +
+

diskLruCache

+
+
+ +
+
open fun diskLruCache(cache: Cache): DiskLruCache
+
+
+
+ +
+
+ + + diff --git a/api/-net/okhttp3/-ok-http-utils/headers.html b/api/-net/okhttp3/-ok-http-utils/headers.html new file mode 100644 index 000000000..86b810eac --- /dev/null +++ b/api/-net/okhttp3/-ok-http-utils/headers.html @@ -0,0 +1,38 @@ + + + + headers + + +
+
+ + +
+
+
+
+
+
+ +
+

headers

+
+
+ +
+
open fun headers(builder: Request.Builder): Headers.Builder
+
+

全部的请求头

+
+ +
+
+ + + diff --git a/api/-net/okhttp3/-ok-http-utils/index.html b/api/-net/okhttp3/-ok-http-utils/index.html new file mode 100644 index 000000000..9f5df44e5 --- /dev/null +++ b/api/-net/okhttp3/-ok-http-utils/index.html @@ -0,0 +1,114 @@ + + + + OkHttpUtils + + +
+
+ + +
+
+
+
+
+
+ +
+

OkHttpUtils

+
open class OkHttpUtils
+
+
+
+
+

Functions

+
+
+
+
addLenient +
Link copied to clipboard
+
+
+
+ +
+
open fun addLenient(builder: Headers.Builder, line: String): Headers.Builder
+
+
+
+
+
+
+ +
+
+
diskLruCache +
Link copied to clipboard
+
+
+
+ +
+
open fun diskLruCache(cache: Cache): DiskLruCache
+
+
+
+
+
+
+ +
+
+
headers +
Link copied to clipboard
+
+
+
+ +
+
open fun headers(builder: Request.Builder): Headers.Builder
+
+
全部的请求头
+
+
+
+
+ +
+
+
tags +
Link copied to clipboard
+
+
+
+ +
+
open fun tags(builder: Request.Builder): Map<Class<out Any>, Any>
+
+
标签集合
+
+ +
+
open fun tags(request: Request): Map<Class<out Any>, Any>
+
+
通过反射返回Request的标签可变集合
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/okhttp3/-ok-http-utils/tags.html b/api/-net/okhttp3/-ok-http-utils/tags.html new file mode 100644 index 000000000..4387da317 --- /dev/null +++ b/api/-net/okhttp3/-ok-http-utils/tags.html @@ -0,0 +1,44 @@ + + + + tags + + +
+
+ + +
+
+
+
+
+
+ +
+

tags

+
+
+ +
+
open fun tags(builder: Request.Builder): Map<Class<out Any>, Any>
+
+

标签集合

+
+ +
+
open fun tags(request: Request): Map<Class<out Any>, Any>
+
+

通过反射返回Request的标签可变集合

+
+ +
+
+ + + diff --git a/api/-net/okhttp3/index.html b/api/-net/okhttp3/index.html new file mode 100644 index 000000000..3fb5c5a01 --- /dev/null +++ b/api/-net/okhttp3/index.html @@ -0,0 +1,56 @@ + + + + okhttp3 + + +
+
+ + +
+
+
+
+
+
+ +
+

Package okhttp3

+
+
+
+
+

Types

+
+
+
+
OkHttpUtils +
Link copied to clipboard
+
+
+
+ +
+
open class OkHttpUtils
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/-net/package-list b/api/-net/package-list new file mode 100644 index 000000000..c50f8d134 --- /dev/null +++ b/api/-net/package-list @@ -0,0 +1,579 @@ +$dokka.format:html-v1 +$dokka.linkExtension:html +$dokka.location:androidx.lifecycle////PointingToDeclaration/-net/androidx.lifecycle/index.html +$dokka.location:androidx.lifecycle//life/com.drake.net.time.Interval#androidx.lifecycle.ViewModel/PointingToDeclaration/-net/androidx.lifecycle/life.html +$dokka.location:androidx.lifecycle//scopeLife/androidx.lifecycle.ViewModel#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/androidx.lifecycle/scope-life.html +$dokka.location:androidx.lifecycle//scopeNetLife/androidx.lifecycle.ViewModel#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/androidx.lifecycle/scope-net-life.html +$dokka.location:com.drake.net.body////PointingToDeclaration/-net/com.drake.net.body/index.html +$dokka.location:com.drake.net.body//fileName/okhttp3.MultipartBody.Part#/PointingToDeclaration/-net/com.drake.net.body/file-name.html +$dokka.location:com.drake.net.body//name/okhttp3.MultipartBody.Part#/PointingToDeclaration/-net/com.drake.net.body/name.html +$dokka.location:com.drake.net.body//peekBytes/okhttp3.RequestBody#kotlin.Long/PointingToDeclaration/-net/com.drake.net.body/peek-bytes.html +$dokka.location:com.drake.net.body//peekBytes/okhttp3.ResponseBody#kotlin.Long/PointingToDeclaration/-net/com.drake.net.body/peek-bytes.html +$dokka.location:com.drake.net.body//toNetRequestBody/okhttp3.RequestBody#java.util.concurrent.ConcurrentLinkedQueue[com.drake.net.interfaces.ProgressListener]?/PointingToDeclaration/-net/com.drake.net.body/to-net-request-body.html +$dokka.location:com.drake.net.body//toNetResponseBody/okhttp3.ResponseBody#java.util.concurrent.ConcurrentLinkedQueue[com.drake.net.interfaces.ProgressListener]?#kotlin.Function0[kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net.body/to-net-response-body.html +$dokka.location:com.drake.net.body//value/okhttp3.MultipartBody.Part#/PointingToDeclaration/-net/com.drake.net.body/value.html +$dokka.location:com.drake.net.body/NetRequestBody///PointingToDeclaration/-net/com.drake.net.body/-net-request-body/index.html +$dokka.location:com.drake.net.body/NetRequestBody/NetRequestBody/#okhttp3.RequestBody#java.util.concurrent.ConcurrentLinkedQueue[com.drake.net.interfaces.ProgressListener]?/PointingToDeclaration/-net/com.drake.net.body/-net-request-body/-net-request-body.html +$dokka.location:com.drake.net.body/NetRequestBody/contentLength/#/PointingToDeclaration/-net/com.drake.net.body/-net-request-body/content-length.html +$dokka.location:com.drake.net.body/NetRequestBody/contentType/#/PointingToDeclaration/-net/com.drake.net.body/-net-request-body/content-type.html +$dokka.location:com.drake.net.body/NetRequestBody/writeTo/#okio.BufferedSink/PointingToDeclaration/-net/com.drake.net.body/-net-request-body/write-to.html +$dokka.location:com.drake.net.body/NetResponseBody///PointingToDeclaration/-net/com.drake.net.body/-net-response-body/index.html +$dokka.location:com.drake.net.body/NetResponseBody/NetResponseBody/#okhttp3.ResponseBody#java.util.concurrent.ConcurrentLinkedQueue[com.drake.net.interfaces.ProgressListener]?#kotlin.Function0[kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net.body/-net-response-body/-net-response-body.html +$dokka.location:com.drake.net.body/NetResponseBody/contentLength/#/PointingToDeclaration/-net/com.drake.net.body/-net-response-body/content-length.html +$dokka.location:com.drake.net.body/NetResponseBody/contentType/#/PointingToDeclaration/-net/com.drake.net.body/-net-response-body/content-type.html +$dokka.location:com.drake.net.body/NetResponseBody/source/#/PointingToDeclaration/-net/com.drake.net.body/-net-response-body/source.html +$dokka.location:com.drake.net.cache////PointingToDeclaration/-net/com.drake.net.cache/index.html +$dokka.location:com.drake.net.cache/CacheMode.READ///PointingToDeclaration/-net/com.drake.net.cache/-cache-mode/-r-e-a-d/index.html +$dokka.location:com.drake.net.cache/CacheMode.READ_THEN_REQUEST///PointingToDeclaration/-net/com.drake.net.cache/-cache-mode/-r-e-a-d_-t-h-e-n_-r-e-q-u-e-s-t/index.html +$dokka.location:com.drake.net.cache/CacheMode.REQUEST_THEN_READ///PointingToDeclaration/-net/com.drake.net.cache/-cache-mode/-r-e-q-u-e-s-t_-t-h-e-n_-r-e-a-d/index.html +$dokka.location:com.drake.net.cache/CacheMode.WRITE///PointingToDeclaration/-net/com.drake.net.cache/-cache-mode/-w-r-i-t-e/index.html +$dokka.location:com.drake.net.cache/CacheMode///PointingToDeclaration/-net/com.drake.net.cache/-cache-mode/index.html +$dokka.location:com.drake.net.cache/ForceCache.Companion///PointingToDeclaration/-net/com.drake.net.cache/-force-cache/-companion/index.html +$dokka.location:com.drake.net.cache/ForceCache.Companion/hasVaryAll/okhttp3.Response#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/-companion/has-vary-all.html +$dokka.location:com.drake.net.cache/ForceCache.Companion/key/#okhttp3.Request/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/-companion/key.html +$dokka.location:com.drake.net.cache/ForceCache.Companion/varyHeaders/okhttp3.Response#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/-companion/vary-headers.html +$dokka.location:com.drake.net.cache/ForceCache.Companion/varyMatches/#okhttp3.Response#okhttp3.Headers#okhttp3.Request/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/-companion/vary-matches.html +$dokka.location:com.drake.net.cache/ForceCache///PointingToDeclaration/-net/com.drake.net.cache/-force-cache/index.html +$dokka.location:com.drake.net.cache/ForceCache/cache/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/cache.html +$dokka.location:com.drake.net.cache/ForceCache/close/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/close.html +$dokka.location:com.drake.net.cache/ForceCache/delete/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/delete.html +$dokka.location:com.drake.net.cache/ForceCache/directory/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/directory.html +$dokka.location:com.drake.net.cache/ForceCache/evictAll/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/evict-all.html +$dokka.location:com.drake.net.cache/ForceCache/flush/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/flush.html +$dokka.location:com.drake.net.cache/ForceCache/initialize/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/initialize.html +$dokka.location:com.drake.net.cache/ForceCache/isClosed/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/is-closed.html +$dokka.location:com.drake.net.cache/ForceCache/maxSize/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/max-size.html +$dokka.location:com.drake.net.cache/ForceCache/size/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/size.html +$dokka.location:com.drake.net.cache/ForceCache/urls/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/urls.html +$dokka.location:com.drake.net.cache/ForceCache/writeAbortCount/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/write-abort-count.html +$dokka.location:com.drake.net.cache/ForceCache/writeSuccessCount/#/PointingToDeclaration/-net/com.drake.net.cache/-force-cache/write-success-count.html +$dokka.location:com.drake.net.component////PointingToDeclaration/-net/com.drake.net.component/index.html +$dokka.location:com.drake.net.component/Progress///PointingToDeclaration/-net/com.drake.net.component/-progress/index.html +$dokka.location:com.drake.net.component/Progress/Progress/#/PointingToDeclaration/-net/com.drake.net.component/-progress/-progress.html +$dokka.location:com.drake.net.component/Progress/currentByteCount/#/PointingToDeclaration/-net/com.drake.net.component/-progress/current-byte-count.html +$dokka.location:com.drake.net.component/Progress/currentSize/#/PointingToDeclaration/-net/com.drake.net.component/-progress/current-size.html +$dokka.location:com.drake.net.component/Progress/finish/#/PointingToDeclaration/-net/com.drake.net.component/-progress/finish.html +$dokka.location:com.drake.net.component/Progress/intervalByteCount/#/PointingToDeclaration/-net/com.drake.net.component/-progress/interval-byte-count.html +$dokka.location:com.drake.net.component/Progress/intervalTime/#/PointingToDeclaration/-net/com.drake.net.component/-progress/interval-time.html +$dokka.location:com.drake.net.component/Progress/progress/#/PointingToDeclaration/-net/com.drake.net.component/-progress/progress.html +$dokka.location:com.drake.net.component/Progress/remainSize/#/PointingToDeclaration/-net/com.drake.net.component/-progress/remain-size.html +$dokka.location:com.drake.net.component/Progress/remainTime/#/PointingToDeclaration/-net/com.drake.net.component/-progress/remain-time.html +$dokka.location:com.drake.net.component/Progress/remainTimeSeconds/#/PointingToDeclaration/-net/com.drake.net.component/-progress/remain-time-seconds.html +$dokka.location:com.drake.net.component/Progress/speedBytes/#/PointingToDeclaration/-net/com.drake.net.component/-progress/speed-bytes.html +$dokka.location:com.drake.net.component/Progress/speedSize/#/PointingToDeclaration/-net/com.drake.net.component/-progress/speed-size.html +$dokka.location:com.drake.net.component/Progress/startElapsedRealtime/#/PointingToDeclaration/-net/com.drake.net.component/-progress/start-elapsed-realtime.html +$dokka.location:com.drake.net.component/Progress/toString/#/PointingToDeclaration/-net/com.drake.net.component/-progress/to-string.html +$dokka.location:com.drake.net.component/Progress/totalByteCount/#/PointingToDeclaration/-net/com.drake.net.component/-progress/total-byte-count.html +$dokka.location:com.drake.net.component/Progress/totalSize/#/PointingToDeclaration/-net/com.drake.net.component/-progress/total-size.html +$dokka.location:com.drake.net.component/Progress/useTime/#/PointingToDeclaration/-net/com.drake.net.component/-progress/use-time.html +$dokka.location:com.drake.net.component/Progress/useTimeSeconds/#/PointingToDeclaration/-net/com.drake.net.component/-progress/use-time-seconds.html +$dokka.location:com.drake.net.convert////PointingToDeclaration/-net/com.drake.net.convert/index.html +$dokka.location:com.drake.net.convert/JSONConvert///PointingToDeclaration/-net/com.drake.net.convert/-j-s-o-n-convert/index.html +$dokka.location:com.drake.net.convert/JSONConvert/JSONConvert/#kotlin.String#kotlin.String#kotlin.String/PointingToDeclaration/-net/com.drake.net.convert/-j-s-o-n-convert/-j-s-o-n-convert.html +$dokka.location:com.drake.net.convert/JSONConvert/code/#/PointingToDeclaration/-net/com.drake.net.convert/-j-s-o-n-convert/code.html +$dokka.location:com.drake.net.convert/JSONConvert/message/#/PointingToDeclaration/-net/com.drake.net.convert/-j-s-o-n-convert/message.html +$dokka.location:com.drake.net.convert/JSONConvert/onConvert/#java.lang.reflect.Type#okhttp3.Response/PointingToDeclaration/-net/com.drake.net.convert/-j-s-o-n-convert/on-convert.html +$dokka.location:com.drake.net.convert/JSONConvert/parseBody/kotlin.String#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.convert/-j-s-o-n-convert/parse-body.html +$dokka.location:com.drake.net.convert/JSONConvert/success/#/PointingToDeclaration/-net/com.drake.net.convert/-j-s-o-n-convert/success.html +$dokka.location:com.drake.net.convert/NetConverter.DEFAULT///PointingToDeclaration/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/index.html +$dokka.location:com.drake.net.convert/NetConverter.DEFAULT/onConvert/#java.lang.reflect.Type#okhttp3.Response/PointingToDeclaration/-net/com.drake.net.convert/-net-converter/-d-e-f-a-u-l-t/on-convert.html +$dokka.location:com.drake.net.convert/NetConverter///PointingToDeclaration/-net/com.drake.net.convert/-net-converter/index.html +$dokka.location:com.drake.net.convert/NetConverter/onConvert/#java.lang.reflect.Type#okhttp3.Response/PointingToDeclaration/-net/com.drake.net.convert/-net-converter/on-convert.html +$dokka.location:com.drake.net.cookie////PointingToDeclaration/-net/com.drake.net.cookie/index.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar///PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/index.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/PersistentCookieJar/#android.content.Context#kotlin.String/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/-persistent-cookie-jar.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/addAll/#okhttp3.HttpUrl#kotlin.collections.List[okhttp3.Cookie]/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/add-all.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/clear/#/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/clear.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/context/#/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/context.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/dbName/#/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/db-name.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/getAll/#okhttp3.HttpUrl/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/get-all.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/loadForRequest/#okhttp3.HttpUrl/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/load-for-request.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/remove/#okhttp3.HttpUrl#kotlin.String/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/remove.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/remove/#okhttp3.HttpUrl/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/remove.html +$dokka.location:com.drake.net.cookie/PersistentCookieJar/saveFromResponse/#okhttp3.HttpUrl#kotlin.collections.List[okhttp3.Cookie]/PointingToDeclaration/-net/com.drake.net.cookie/-persistent-cookie-jar/save-from-response.html +$dokka.location:com.drake.net.exception////PointingToDeclaration/-net/com.drake.net.exception/index.html +$dokka.location:com.drake.net.exception//NetCancellationException/kotlinx.coroutines.CoroutineScope#kotlin.String?/PointingToDeclaration/-net/com.drake.net.exception/-net-cancellation-exception.html +$dokka.location:com.drake.net.exception/ConvertException///PointingToDeclaration/-net/com.drake.net.exception/-convert-exception/index.html +$dokka.location:com.drake.net.exception/ConvertException/ConvertException/#okhttp3.Response#kotlin.String?#kotlin.Throwable?#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.exception/-convert-exception/-convert-exception.html +$dokka.location:com.drake.net.exception/ConvertException/tag/#/PointingToDeclaration/-net/com.drake.net.exception/-convert-exception/tag.html +$dokka.location:com.drake.net.exception/DownloadFileException///PointingToDeclaration/-net/com.drake.net.exception/-download-file-exception/index.html +$dokka.location:com.drake.net.exception/DownloadFileException/DownloadFileException/#okhttp3.Response#kotlin.String?#kotlin.Throwable?#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.exception/-download-file-exception/-download-file-exception.html +$dokka.location:com.drake.net.exception/DownloadFileException/tag/#/PointingToDeclaration/-net/com.drake.net.exception/-download-file-exception/tag.html +$dokka.location:com.drake.net.exception/HttpFailureException///PointingToDeclaration/-net/com.drake.net.exception/-http-failure-exception/index.html +$dokka.location:com.drake.net.exception/HttpFailureException/HttpFailureException/#okhttp3.Request#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-http-failure-exception/-http-failure-exception.html +$dokka.location:com.drake.net.exception/HttpResponseException///PointingToDeclaration/-net/com.drake.net.exception/-http-response-exception/index.html +$dokka.location:com.drake.net.exception/HttpResponseException/HttpResponseException/#okhttp3.Response#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-http-response-exception/-http-response-exception.html +$dokka.location:com.drake.net.exception/HttpResponseException/response/#/PointingToDeclaration/-net/com.drake.net.exception/-http-response-exception/response.html +$dokka.location:com.drake.net.exception/NetCancellationException///PointingToDeclaration/-net/com.drake.net.exception/-net-cancellation-exception/index.html +$dokka.location:com.drake.net.exception/NetCancellationException/NetCancellationException/#kotlinx.coroutines.CoroutineScope#kotlin.String?/PointingToDeclaration/-net/com.drake.net.exception/-net-cancellation-exception/-net-cancellation-exception.html +$dokka.location:com.drake.net.exception/NetConnectException///PointingToDeclaration/-net/com.drake.net.exception/-net-connect-exception/index.html +$dokka.location:com.drake.net.exception/NetConnectException/NetConnectException/#okhttp3.Request#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-net-connect-exception/-net-connect-exception.html +$dokka.location:com.drake.net.exception/NetException///PointingToDeclaration/-net/com.drake.net.exception/-net-exception/index.html +$dokka.location:com.drake.net.exception/NetException/NetException/#okhttp3.Request#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-net-exception/-net-exception.html +$dokka.location:com.drake.net.exception/NetException/getLocalizedMessage/#/PointingToDeclaration/-net/com.drake.net.exception/-net-exception/get-localized-message.html +$dokka.location:com.drake.net.exception/NetException/occurred/#/PointingToDeclaration/-net/com.drake.net.exception/-net-exception/occurred.html +$dokka.location:com.drake.net.exception/NetException/request/#/PointingToDeclaration/-net/com.drake.net.exception/-net-exception/request.html +$dokka.location:com.drake.net.exception/NetSocketTimeoutException///PointingToDeclaration/-net/com.drake.net.exception/-net-socket-timeout-exception/index.html +$dokka.location:com.drake.net.exception/NetSocketTimeoutException/NetSocketTimeoutException/#okhttp3.Request#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-net-socket-timeout-exception/-net-socket-timeout-exception.html +$dokka.location:com.drake.net.exception/NetUnknownHostException///PointingToDeclaration/-net/com.drake.net.exception/-net-unknown-host-exception/index.html +$dokka.location:com.drake.net.exception/NetUnknownHostException/NetUnknownHostException/#okhttp3.Request#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-net-unknown-host-exception/-net-unknown-host-exception.html +$dokka.location:com.drake.net.exception/NetworkingException///PointingToDeclaration/-net/com.drake.net.exception/-networking-exception/index.html +$dokka.location:com.drake.net.exception/NetworkingException/NetworkingException/#okhttp3.Request#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-networking-exception/-networking-exception.html +$dokka.location:com.drake.net.exception/NoCacheException///PointingToDeclaration/-net/com.drake.net.exception/-no-cache-exception/index.html +$dokka.location:com.drake.net.exception/NoCacheException/NoCacheException/#okhttp3.Request#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-no-cache-exception/-no-cache-exception.html +$dokka.location:com.drake.net.exception/NoCacheException/getLocalizedMessage/#/PointingToDeclaration/-net/com.drake.net.exception/-no-cache-exception/get-localized-message.html +$dokka.location:com.drake.net.exception/RequestParamsException///PointingToDeclaration/-net/com.drake.net.exception/-request-params-exception/index.html +$dokka.location:com.drake.net.exception/RequestParamsException/RequestParamsException/#okhttp3.Response#kotlin.String?#kotlin.Throwable?#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.exception/-request-params-exception/-request-params-exception.html +$dokka.location:com.drake.net.exception/RequestParamsException/tag/#/PointingToDeclaration/-net/com.drake.net.exception/-request-params-exception/tag.html +$dokka.location:com.drake.net.exception/ResponseException///PointingToDeclaration/-net/com.drake.net.exception/-response-exception/index.html +$dokka.location:com.drake.net.exception/ResponseException/ResponseException/#okhttp3.Response#kotlin.String?#kotlin.Throwable?#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.exception/-response-exception/-response-exception.html +$dokka.location:com.drake.net.exception/ResponseException/tag/#/PointingToDeclaration/-net/com.drake.net.exception/-response-exception/tag.html +$dokka.location:com.drake.net.exception/ServerResponseException///PointingToDeclaration/-net/com.drake.net.exception/-server-response-exception/index.html +$dokka.location:com.drake.net.exception/ServerResponseException/ServerResponseException/#okhttp3.Response#kotlin.String?#kotlin.Throwable?#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.exception/-server-response-exception/-server-response-exception.html +$dokka.location:com.drake.net.exception/ServerResponseException/tag/#/PointingToDeclaration/-net/com.drake.net.exception/-server-response-exception/tag.html +$dokka.location:com.drake.net.exception/URLParseException///PointingToDeclaration/-net/com.drake.net.exception/-u-r-l-parse-exception/index.html +$dokka.location:com.drake.net.exception/URLParseException/URLParseException/#kotlin.String?#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.exception/-u-r-l-parse-exception/-u-r-l-parse-exception.html +$dokka.location:com.drake.net.exception/URLParseException/getLocalizedMessage/#/PointingToDeclaration/-net/com.drake.net.exception/-u-r-l-parse-exception/get-localized-message.html +$dokka.location:com.drake.net.exception/URLParseException/occurred/#/PointingToDeclaration/-net/com.drake.net.exception/-u-r-l-parse-exception/occurred.html +$dokka.location:com.drake.net.interceptor////PointingToDeclaration/-net/com.drake.net.interceptor/index.html +$dokka.location:com.drake.net.interceptor/LogRecordInterceptor///PointingToDeclaration/-net/com.drake.net.interceptor/-log-record-interceptor/index.html +$dokka.location:com.drake.net.interceptor/LogRecordInterceptor/LogRecordInterceptor/#kotlin.Boolean#kotlin.Long#kotlin.Long/PointingToDeclaration/-net/com.drake.net.interceptor/-log-record-interceptor/-log-record-interceptor.html +$dokka.location:com.drake.net.interceptor/LogRecordInterceptor/enabled/#/PointingToDeclaration/-net/com.drake.net.interceptor/-log-record-interceptor/enabled.html +$dokka.location:com.drake.net.interceptor/LogRecordInterceptor/intercept/#okhttp3.Interceptor.Chain/PointingToDeclaration/-net/com.drake.net.interceptor/-log-record-interceptor/intercept.html +$dokka.location:com.drake.net.interceptor/LogRecordInterceptor/requestByteCount/#/PointingToDeclaration/-net/com.drake.net.interceptor/-log-record-interceptor/request-byte-count.html +$dokka.location:com.drake.net.interceptor/LogRecordInterceptor/responseByteCount/#/PointingToDeclaration/-net/com.drake.net.interceptor/-log-record-interceptor/response-byte-count.html +$dokka.location:com.drake.net.interceptor/NetOkHttpInterceptor///PointingToDeclaration/-net/com.drake.net.interceptor/-net-ok-http-interceptor/index.html +$dokka.location:com.drake.net.interceptor/NetOkHttpInterceptor/intercept/#okhttp3.Interceptor.Chain/PointingToDeclaration/-net/com.drake.net.interceptor/-net-ok-http-interceptor/intercept.html +$dokka.location:com.drake.net.interceptor/RequestInterceptor///PointingToDeclaration/-net/com.drake.net.interceptor/-request-interceptor/index.html +$dokka.location:com.drake.net.interceptor/RequestInterceptor/interceptor/#com.drake.net.request.BaseRequest/PointingToDeclaration/-net/com.drake.net.interceptor/-request-interceptor/interceptor.html +$dokka.location:com.drake.net.interceptor/RetryInterceptor///PointingToDeclaration/-net/com.drake.net.interceptor/-retry-interceptor/index.html +$dokka.location:com.drake.net.interceptor/RetryInterceptor/RetryInterceptor/#kotlin.Int/PointingToDeclaration/-net/com.drake.net.interceptor/-retry-interceptor/-retry-interceptor.html +$dokka.location:com.drake.net.interceptor/RetryInterceptor/intercept/#okhttp3.Interceptor.Chain/PointingToDeclaration/-net/com.drake.net.interceptor/-retry-interceptor/intercept.html +$dokka.location:com.drake.net.interceptor/RetryInterceptor/retryCount/#/PointingToDeclaration/-net/com.drake.net.interceptor/-retry-interceptor/retry-count.html +$dokka.location:com.drake.net.interfaces////PointingToDeclaration/-net/com.drake.net.interfaces/index.html +$dokka.location:com.drake.net.interfaces/NetDialogFactory.DEFAULT///PointingToDeclaration/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/index.html +$dokka.location:com.drake.net.interfaces/NetDialogFactory.DEFAULT/onCreate/#androidx.fragment.app.FragmentActivity/PointingToDeclaration/-net/com.drake.net.interfaces/-net-dialog-factory/-d-e-f-a-u-l-t/on-create.html +$dokka.location:com.drake.net.interfaces/NetDialogFactory///PointingToDeclaration/-net/com.drake.net.interfaces/-net-dialog-factory/index.html +$dokka.location:com.drake.net.interfaces/NetDialogFactory/onCreate/#androidx.fragment.app.FragmentActivity/PointingToDeclaration/-net/com.drake.net.interfaces/-net-dialog-factory/on-create.html +$dokka.location:com.drake.net.interfaces/NetErrorHandler.DEFAULT///PointingToDeclaration/-net/com.drake.net.interfaces/-net-error-handler/-d-e-f-a-u-l-t/index.html +$dokka.location:com.drake.net.interfaces/NetErrorHandler///PointingToDeclaration/-net/com.drake.net.interfaces/-net-error-handler/index.html +$dokka.location:com.drake.net.interfaces/NetErrorHandler/onError/#kotlin.Throwable/PointingToDeclaration/-net/com.drake.net.interfaces/-net-error-handler/on-error.html +$dokka.location:com.drake.net.interfaces/NetErrorHandler/onStateError/#kotlin.Throwable#android.view.View/PointingToDeclaration/-net/com.drake.net.interfaces/-net-error-handler/on-state-error.html +$dokka.location:com.drake.net.interfaces/ProgressListener///PointingToDeclaration/-net/com.drake.net.interfaces/-progress-listener/index.html +$dokka.location:com.drake.net.interfaces/ProgressListener/ProgressListener/#kotlin.Long/PointingToDeclaration/-net/com.drake.net.interfaces/-progress-listener/-progress-listener.html +$dokka.location:com.drake.net.interfaces/ProgressListener/elapsedTime/#/PointingToDeclaration/-net/com.drake.net.interfaces/-progress-listener/elapsed-time.html +$dokka.location:com.drake.net.interfaces/ProgressListener/interval/#/PointingToDeclaration/-net/com.drake.net.interfaces/-progress-listener/interval.html +$dokka.location:com.drake.net.interfaces/ProgressListener/intervalByteCount/#/PointingToDeclaration/-net/com.drake.net.interfaces/-progress-listener/interval-byte-count.html +$dokka.location:com.drake.net.interfaces/ProgressListener/onProgress/#com.drake.net.component.Progress/PointingToDeclaration/-net/com.drake.net.interfaces/-progress-listener/on-progress.html +$dokka.location:com.drake.net.log////PointingToDeclaration/-net/com.drake.net.log/index.html +$dokka.location:com.drake.net.log/LogRecorder///PointingToDeclaration/-net/com.drake.net.log/-log-recorder/index.html +$dokka.location:com.drake.net.log/LogRecorder/enabled/#/PointingToDeclaration/-net/com.drake.net.log/-log-recorder/enabled.html +$dokka.location:com.drake.net.log/LogRecorder/generateId/#/PointingToDeclaration/-net/com.drake.net.log/-log-recorder/generate-id.html +$dokka.location:com.drake.net.log/LogRecorder/recordException/#kotlin.String#kotlin.Long#kotlin.Int?#kotlin.String?#kotlin.String?/PointingToDeclaration/-net/com.drake.net.log/-log-recorder/record-exception.html +$dokka.location:com.drake.net.log/LogRecorder/recordRequest/#kotlin.String#kotlin.String#kotlin.String#kotlin.collections.Map[kotlin.String,kotlin.collections.List[kotlin.String]]#kotlin.String?/PointingToDeclaration/-net/com.drake.net.log/-log-recorder/record-request.html +$dokka.location:com.drake.net.log/LogRecorder/recordResponse/#kotlin.String#kotlin.Long#kotlin.Int#kotlin.collections.Map[kotlin.String,kotlin.collections.List[kotlin.String]]#kotlin.String?/PointingToDeclaration/-net/com.drake.net.log/-log-recorder/record-response.html +$dokka.location:com.drake.net.log/MessageType.REQUEST_BODY///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-b-o-d-y/index.html +$dokka.location:com.drake.net.log/MessageType.REQUEST_END///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-e-n-d/index.html +$dokka.location:com.drake.net.log/MessageType.REQUEST_HEADER///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-h-e-a-d-e-r/index.html +$dokka.location:com.drake.net.log/MessageType.REQUEST_METHOD///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-m-e-t-h-o-d/index.html +$dokka.location:com.drake.net.log/MessageType.REQUEST_TIME///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-t-i-m-e/index.html +$dokka.location:com.drake.net.log/MessageType.REQUEST_URL///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-q-u-e-s-t_-u-r-l/index.html +$dokka.location:com.drake.net.log/MessageType.RESPONSE_BODY///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-b-o-d-y/index.html +$dokka.location:com.drake.net.log/MessageType.RESPONSE_END///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-n-d/index.html +$dokka.location:com.drake.net.log/MessageType.RESPONSE_ERROR///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-e-r-r-o-r/index.html +$dokka.location:com.drake.net.log/MessageType.RESPONSE_HEADER///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-h-e-a-d-e-r/index.html +$dokka.location:com.drake.net.log/MessageType.RESPONSE_STATUS///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-s-t-a-t-u-s/index.html +$dokka.location:com.drake.net.log/MessageType.RESPONSE_TIME///PointingToDeclaration/-net/com.drake.net.log/-message-type/-r-e-s-p-o-n-s-e_-t-i-m-e/index.html +$dokka.location:com.drake.net.log/MessageType.UNKNOWN///PointingToDeclaration/-net/com.drake.net.log/-message-type/-u-n-k-n-o-w-n/index.html +$dokka.location:com.drake.net.log/MessageType///PointingToDeclaration/-net/com.drake.net.log/-message-type/index.html +$dokka.location:com.drake.net.log/MessageType/type/#/PointingToDeclaration/-net/com.drake.net.log/-message-type/type.html +$dokka.location:com.drake.net.okhttp////PointingToDeclaration/-net/com.drake.net.okhttp/index.html +$dokka.location:com.drake.net.okhttp//setConverter/okhttp3.OkHttpClient.Builder#com.drake.net.convert.NetConverter/PointingToDeclaration/-net/com.drake.net.okhttp/set-converter.html +$dokka.location:com.drake.net.okhttp//setDebug/okhttp3.OkHttpClient.Builder#kotlin.Boolean#kotlin.String/PointingToDeclaration/-net/com.drake.net.okhttp/set-debug.html +$dokka.location:com.drake.net.okhttp//setDialogFactory/okhttp3.OkHttpClient.Builder#com.drake.net.interfaces.NetDialogFactory/PointingToDeclaration/-net/com.drake.net.okhttp/set-dialog-factory.html +$dokka.location:com.drake.net.okhttp//setErrorHandler/okhttp3.OkHttpClient.Builder#com.drake.net.interfaces.NetErrorHandler/PointingToDeclaration/-net/com.drake.net.okhttp/set-error-handler.html +$dokka.location:com.drake.net.okhttp//setRequestInterceptor/okhttp3.OkHttpClient.Builder#com.drake.net.interceptor.RequestInterceptor/PointingToDeclaration/-net/com.drake.net.okhttp/set-request-interceptor.html +$dokka.location:com.drake.net.okhttp//setSSLCertificate/okhttp3.OkHttpClient.Builder#javax.net.ssl.X509TrustManager?#java.io.InputStream?#kotlin.String?/PointingToDeclaration/-net/com.drake.net.okhttp/set-s-s-l-certificate.html +$dokka.location:com.drake.net.okhttp//setSSLCertificate/okhttp3.OkHttpClient.Builder#kotlin.Array[java.io.InputStream]#java.io.InputStream?#kotlin.String?/PointingToDeclaration/-net/com.drake.net.okhttp/set-s-s-l-certificate.html +$dokka.location:com.drake.net.okhttp//toNetOkhttp/okhttp3.OkHttpClient#/PointingToDeclaration/-net/com.drake.net.okhttp/to-net-okhttp.html +$dokka.location:com.drake.net.okhttp//toNetOkhttp/okhttp3.OkHttpClient.Builder#/PointingToDeclaration/-net/com.drake.net.okhttp/to-net-okhttp.html +$dokka.location:com.drake.net.okhttp//trustSSLCertificate/okhttp3.OkHttpClient.Builder#/PointingToDeclaration/-net/com.drake.net.okhttp/trust-s-s-l-certificate.html +$dokka.location:com.drake.net.reflect/$Gson$Preconditions///PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-preconditions/index.html +$dokka.location:com.drake.net.reflect/$Gson$Preconditions/checkArgument/#boolean/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-preconditions/check-argument.html +$dokka.location:com.drake.net.reflect/$Gson$Preconditions/checkNotNull/#T/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-preconditions/check-not-null.html +$dokka.location:com.drake.net.reflect/$Gson$Types///PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/index.html +$dokka.location:com.drake.net.reflect/$Gson$Types/arrayOf/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/array-of.html +$dokka.location:com.drake.net.reflect/$Gson$Types/canonicalize/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/canonicalize.html +$dokka.location:com.drake.net.reflect/$Gson$Types/equals/#java.lang.reflect.Type#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/equals.html +$dokka.location:com.drake.net.reflect/$Gson$Types/getArrayComponentType/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/get-array-component-type.html +$dokka.location:com.drake.net.reflect/$Gson$Types/getCollectionElementType/#java.lang.reflect.Type#java.lang.Class/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/get-collection-element-type.html +$dokka.location:com.drake.net.reflect/$Gson$Types/getMapKeyAndValueTypes/#java.lang.reflect.Type#java.lang.Class/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/get-map-key-and-value-types.html +$dokka.location:com.drake.net.reflect/$Gson$Types/getRawType/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/get-raw-type.html +$dokka.location:com.drake.net.reflect/$Gson$Types/newParameterizedTypeWithOwner/#java.lang.reflect.Type#java.lang.reflect.Type#java.lang.reflect.Type.../PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/new-parameterized-type-with-owner.html +$dokka.location:com.drake.net.reflect/$Gson$Types/resolve/#java.lang.reflect.Type#java.lang.Class#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/resolve.html +$dokka.location:com.drake.net.reflect/$Gson$Types/subtypeOf/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/subtype-of.html +$dokka.location:com.drake.net.reflect/$Gson$Types/supertypeOf/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/supertype-of.html +$dokka.location:com.drake.net.reflect/$Gson$Types/typeToString/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/$-gson$-types/type-to-string.html +$dokka.location:com.drake.net.reflect////PointingToDeclaration/-net/com.drake.net.reflect/index.html +$dokka.location:com.drake.net.reflect//typeTokenOf/#/PointingToDeclaration/-net/com.drake.net.reflect/type-token-of.html +$dokka.location:com.drake.net.reflect/TypeToken///PointingToDeclaration/-net/com.drake.net.reflect/-type-token/index.html +$dokka.location:com.drake.net.reflect/TypeToken/equals/#java.lang.Object/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/equals.html +$dokka.location:com.drake.net.reflect/TypeToken/get/#java.lang.Class/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/get.html +$dokka.location:com.drake.net.reflect/TypeToken/get/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/get.html +$dokka.location:com.drake.net.reflect/TypeToken/getArray/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/get-array.html +$dokka.location:com.drake.net.reflect/TypeToken/getParameterized/#java.lang.reflect.Type#java.lang.reflect.Type.../PointingToDeclaration/-net/com.drake.net.reflect/-type-token/get-parameterized.html +$dokka.location:com.drake.net.reflect/TypeToken/hashCode/#/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/hash-code.html +$dokka.location:com.drake.net.reflect/TypeToken/rawType/#/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/raw-type.html +$dokka.location:com.drake.net.reflect/TypeToken/toString/#/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/to-string.html +$dokka.location:com.drake.net.reflect/TypeToken/type/#/PointingToDeclaration/-net/com.drake.net.reflect/-type-token/type.html +$dokka.location:com.drake.net.request////PointingToDeclaration/-net/com.drake.net.request/index.html +$dokka.location:com.drake.net.request//converter/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/converter.html +$dokka.location:com.drake.net.request//downloadConflictRename/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/download-conflict-rename.html +$dokka.location:com.drake.net.request//downloadFileDir/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/download-file-dir.html +$dokka.location:com.drake.net.request//downloadFileName/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/download-file-name.html +$dokka.location:com.drake.net.request//downloadFileNameDecode/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/download-file-name-decode.html +$dokka.location:com.drake.net.request//downloadListeners/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/download-listeners.html +$dokka.location:com.drake.net.request//downloadListeners/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/download-listeners.html +$dokka.location:com.drake.net.request//downloadMd5Verify/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/download-md5-verify.html +$dokka.location:com.drake.net.request//downloadTempFile/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/download-temp-file.html +$dokka.location:com.drake.net.request//extra/okhttp3.Request#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/extra.html +$dokka.location:com.drake.net.request//extras/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/extras.html +$dokka.location:com.drake.net.request//extras/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/extras.html +$dokka.location:com.drake.net.request//group/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/group.html +$dokka.location:com.drake.net.request//group/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/group.html +$dokka.location:com.drake.net.request//headers/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/headers.html +$dokka.location:com.drake.net.request//id/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/id.html +$dokka.location:com.drake.net.request//id/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/id.html +$dokka.location:com.drake.net.request//kType/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/k-type.html +$dokka.location:com.drake.net.request//kType/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/k-type.html +$dokka.location:com.drake.net.request//setConverter/okhttp3.Request.Builder#com.drake.net.convert.NetConverter/PointingToDeclaration/-net/com.drake.net.request/set-converter.html +$dokka.location:com.drake.net.request//setExtra/okhttp3.Request.Builder#kotlin.String#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.request/set-extra.html +$dokka.location:com.drake.net.request//tagOf/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/tag-of.html +$dokka.location:com.drake.net.request//tagOf/okhttp3.Request#TypeParam(bounds=[kotlin.Any?])?/PointingToDeclaration/-net/com.drake.net.request/tag-of.html +$dokka.location:com.drake.net.request//tagOf/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/tag-of.html +$dokka.location:com.drake.net.request//tagOf/okhttp3.Request.Builder#TypeParam(bounds=[kotlin.Any?])?/PointingToDeclaration/-net/com.drake.net.request/tag-of.html +$dokka.location:com.drake.net.request//tags/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/tags.html +$dokka.location:com.drake.net.request//tags/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/tags.html +$dokka.location:com.drake.net.request//uploadListeners/okhttp3.Request#/PointingToDeclaration/-net/com.drake.net.request/upload-listeners.html +$dokka.location:com.drake.net.request//uploadListeners/okhttp3.Request.Builder#/PointingToDeclaration/-net/com.drake.net.request/upload-listeners.html +$dokka.location:com.drake.net.request/BaseRequest///PointingToDeclaration/-net/com.drake.net.request/-base-request/index.html +$dokka.location:com.drake.net.request/BaseRequest/BaseRequest/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/-base-request.html +$dokka.location:com.drake.net.request/BaseRequest/addDownloadListener/#com.drake.net.interfaces.ProgressListener/PointingToDeclaration/-net/com.drake.net.request/-base-request/add-download-listener.html +$dokka.location:com.drake.net.request/BaseRequest/addHeader/#kotlin.String#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/-base-request/add-header.html +$dokka.location:com.drake.net.request/BaseRequest/addQuery/#kotlin.String#kotlin.Boolean?/PointingToDeclaration/-net/com.drake.net.request/-base-request/add-query.html +$dokka.location:com.drake.net.request/BaseRequest/addQuery/#kotlin.String#kotlin.Number?/PointingToDeclaration/-net/com.drake.net.request/-base-request/add-query.html +$dokka.location:com.drake.net.request/BaseRequest/addQuery/#kotlin.String#kotlin.String?#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-base-request/add-query.html +$dokka.location:com.drake.net.request/BaseRequest/buildRequest/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/build-request.html +$dokka.location:com.drake.net.request/BaseRequest/converter/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/converter.html +$dokka.location:com.drake.net.request/BaseRequest/enqueue/#okhttp3.Callback/PointingToDeclaration/-net/com.drake.net.request/-base-request/enqueue.html +$dokka.location:com.drake.net.request/BaseRequest/execute/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/execute.html +$dokka.location:com.drake.net.request/BaseRequest/execute/#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.request/-base-request/execute.html +$dokka.location:com.drake.net.request/BaseRequest/headers/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/headers.html +$dokka.location:com.drake.net.request/BaseRequest/httpUrl/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/http-url.html +$dokka.location:com.drake.net.request/BaseRequest/method/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/method.html +$dokka.location:com.drake.net.request/BaseRequest/okHttpClient/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/ok-http-client.html +$dokka.location:com.drake.net.request/BaseRequest/okHttpRequest/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/ok-http-request.html +$dokka.location:com.drake.net.request/BaseRequest/param/#kotlin.String#kotlin.Boolean?/PointingToDeclaration/-net/com.drake.net.request/-base-request/param.html +$dokka.location:com.drake.net.request/BaseRequest/param/#kotlin.String#kotlin.Number?/PointingToDeclaration/-net/com.drake.net.request/-base-request/param.html +$dokka.location:com.drake.net.request/BaseRequest/param/#kotlin.String#kotlin.String?#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-base-request/param.html +$dokka.location:com.drake.net.request/BaseRequest/param/#kotlin.String#kotlin.String?/PointingToDeclaration/-net/com.drake.net.request/-base-request/param.html +$dokka.location:com.drake.net.request/BaseRequest/removeHeader/#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/-base-request/remove-header.html +$dokka.location:com.drake.net.request/BaseRequest/setCacheControl/#okhttp3.CacheControl/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-cache-control.html +$dokka.location:com.drake.net.request/BaseRequest/setCacheKey/#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-cache-key.html +$dokka.location:com.drake.net.request/BaseRequest/setCacheMode/#com.drake.net.cache.CacheMode/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-cache-mode.html +$dokka.location:com.drake.net.request/BaseRequest/setCacheValidTime/#kotlin.Long#java.util.concurrent.TimeUnit/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-cache-valid-time.html +$dokka.location:com.drake.net.request/BaseRequest/setClient/#kotlin.Function1[okhttp3.OkHttpClient.Builder,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-client.html +$dokka.location:com.drake.net.request/BaseRequest/setDownloadDir/#java.io.File/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-download-dir.html +$dokka.location:com.drake.net.request/BaseRequest/setDownloadDir/#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-download-dir.html +$dokka.location:com.drake.net.request/BaseRequest/setDownloadFileName/#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-download-file-name.html +$dokka.location:com.drake.net.request/BaseRequest/setDownloadFileNameConflict/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-download-file-name-conflict.html +$dokka.location:com.drake.net.request/BaseRequest/setDownloadFileNameDecode/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-download-file-name-decode.html +$dokka.location:com.drake.net.request/BaseRequest/setDownloadMd5Verify/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-download-md5-verify.html +$dokka.location:com.drake.net.request/BaseRequest/setDownloadTempFile/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-download-temp-file.html +$dokka.location:com.drake.net.request/BaseRequest/setExtra/#kotlin.String#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-extra.html +$dokka.location:com.drake.net.request/BaseRequest/setGroup/#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-group.html +$dokka.location:com.drake.net.request/BaseRequest/setHeader/#kotlin.String#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-header.html +$dokka.location:com.drake.net.request/BaseRequest/setHeaders/#okhttp3.Headers/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-headers.html +$dokka.location:com.drake.net.request/BaseRequest/setId/#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-id.html +$dokka.location:com.drake.net.request/BaseRequest/setKType/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-k-type.html +$dokka.location:com.drake.net.request/BaseRequest/setPath/#kotlin.String?/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-path.html +$dokka.location:com.drake.net.request/BaseRequest/setQuery/#kotlin.String#kotlin.Boolean?/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-query.html +$dokka.location:com.drake.net.request/BaseRequest/setQuery/#kotlin.String#kotlin.Number?/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-query.html +$dokka.location:com.drake.net.request/BaseRequest/setQuery/#kotlin.String#kotlin.String?#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-query.html +$dokka.location:com.drake.net.request/BaseRequest/setUrl/#java.net.URL/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-url.html +$dokka.location:com.drake.net.request/BaseRequest/setUrl/#kotlin.String/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-url.html +$dokka.location:com.drake.net.request/BaseRequest/setUrl/#okhttp3.HttpUrl/PointingToDeclaration/-net/com.drake.net.request/-base-request/set-url.html +$dokka.location:com.drake.net.request/BaseRequest/tag/#java.lang.Class[TypeParam(bounds=[kotlin.Any?])]#TypeParam(bounds=[kotlin.Any?])?/PointingToDeclaration/-net/com.drake.net.request/-base-request/tag.html +$dokka.location:com.drake.net.request/BaseRequest/tag/#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.request/-base-request/tag.html +$dokka.location:com.drake.net.request/BaseRequest/tagOf/#TypeParam(bounds=[kotlin.Any?])?/PointingToDeclaration/-net/com.drake.net.request/-base-request/tag-of.html +$dokka.location:com.drake.net.request/BaseRequest/toResult/#/PointingToDeclaration/-net/com.drake.net.request/-base-request/to-result.html +$dokka.location:com.drake.net.request/BodyRequest///PointingToDeclaration/-net/com.drake.net.request/-body-request/index.html +$dokka.location:com.drake.net.request/BodyRequest/BodyRequest/#/PointingToDeclaration/-net/com.drake.net.request/-body-request/-body-request.html +$dokka.location:com.drake.net.request/BodyRequest/addUploadListener/#com.drake.net.interfaces.ProgressListener/PointingToDeclaration/-net/com.drake.net.request/-body-request/add-upload-listener.html +$dokka.location:com.drake.net.request/BodyRequest/body/#/PointingToDeclaration/-net/com.drake.net.request/-body-request/body.html +$dokka.location:com.drake.net.request/BodyRequest/buildRequest/#/PointingToDeclaration/-net/com.drake.net.request/-body-request/build-request.html +$dokka.location:com.drake.net.request/BodyRequest/formBody/#/PointingToDeclaration/-net/com.drake.net.request/-body-request/form-body.html +$dokka.location:com.drake.net.request/BodyRequest/json/#kotlin.Array[kotlin.Pair[kotlin.String,kotlin.Any?]]/PointingToDeclaration/-net/com.drake.net.request/-body-request/json.html +$dokka.location:com.drake.net.request/BodyRequest/json/#kotlin.String?/PointingToDeclaration/-net/com.drake.net.request/-body-request/json.html +$dokka.location:com.drake.net.request/BodyRequest/json/#kotlin.collections.Map[kotlin.String,kotlin.Any?]?/PointingToDeclaration/-net/com.drake.net.request/-body-request/json.html +$dokka.location:com.drake.net.request/BodyRequest/json/#org.json.JSONArray?/PointingToDeclaration/-net/com.drake.net.request/-body-request/json.html +$dokka.location:com.drake.net.request/BodyRequest/json/#org.json.JSONObject?/PointingToDeclaration/-net/com.drake.net.request/-body-request/json.html +$dokka.location:com.drake.net.request/BodyRequest/mediaType/#/PointingToDeclaration/-net/com.drake.net.request/-body-request/media-type.html +$dokka.location:com.drake.net.request/BodyRequest/method/#/PointingToDeclaration/-net/com.drake.net.request/-body-request/method.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#android.net.Uri?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#java.io.File?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#kotlin.Boolean?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#kotlin.ByteArray?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#kotlin.Number?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#kotlin.String?#java.io.File?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#kotlin.String?#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#kotlin.String?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#kotlin.collections.List[java.io.File?]?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#okhttp3.RequestBody?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#kotlin.String#okio.ByteString?/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/param/#okhttp3.MultipartBody.Part/PointingToDeclaration/-net/com.drake.net.request/-body-request/param.html +$dokka.location:com.drake.net.request/BodyRequest/partBody/#/PointingToDeclaration/-net/com.drake.net.request/-body-request/part-body.html +$dokka.location:com.drake.net.request/MediaConst///PointingToDeclaration/-net/com.drake.net.request/-media-const/index.html +$dokka.location:com.drake.net.request/MediaConst/FORM/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-f-o-r-m.html +$dokka.location:com.drake.net.request/MediaConst/GIF/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-g-i-f.html +$dokka.location:com.drake.net.request/MediaConst/HTML/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-h-t-m-l.html +$dokka.location:com.drake.net.request/MediaConst/IMG/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-i-m-g.html +$dokka.location:com.drake.net.request/MediaConst/JPEG/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-j-p-e-g.html +$dokka.location:com.drake.net.request/MediaConst/JSON/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-j-s-o-n.html +$dokka.location:com.drake.net.request/MediaConst/MP4/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-m-p4.html +$dokka.location:com.drake.net.request/MediaConst/OCTET_STREAM/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-o-c-t-e-t_-s-t-r-e-a-m.html +$dokka.location:com.drake.net.request/MediaConst/PNG/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-p-n-g.html +$dokka.location:com.drake.net.request/MediaConst/TXT/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-t-x-t.html +$dokka.location:com.drake.net.request/MediaConst/URLENCODED/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-u-r-l-e-n-c-o-d-e-d.html +$dokka.location:com.drake.net.request/MediaConst/XML/#/PointingToDeclaration/-net/com.drake.net.request/-media-const/-x-m-l.html +$dokka.location:com.drake.net.request/Method.DELETE///PointingToDeclaration/-net/com.drake.net.request/-method/-d-e-l-e-t-e/index.html +$dokka.location:com.drake.net.request/Method.GET///PointingToDeclaration/-net/com.drake.net.request/-method/-g-e-t/index.html +$dokka.location:com.drake.net.request/Method.HEAD///PointingToDeclaration/-net/com.drake.net.request/-method/-h-e-a-d/index.html +$dokka.location:com.drake.net.request/Method.OPTIONS///PointingToDeclaration/-net/com.drake.net.request/-method/-o-p-t-i-o-n-s/index.html +$dokka.location:com.drake.net.request/Method.PATCH///PointingToDeclaration/-net/com.drake.net.request/-method/-p-a-t-c-h/index.html +$dokka.location:com.drake.net.request/Method.POST///PointingToDeclaration/-net/com.drake.net.request/-method/-p-o-s-t/index.html +$dokka.location:com.drake.net.request/Method.PUT///PointingToDeclaration/-net/com.drake.net.request/-method/-p-u-t/index.html +$dokka.location:com.drake.net.request/Method.TRACE///PointingToDeclaration/-net/com.drake.net.request/-method/-t-r-a-c-e/index.html +$dokka.location:com.drake.net.request/Method///PointingToDeclaration/-net/com.drake.net.request/-method/index.html +$dokka.location:com.drake.net.request/UrlRequest///PointingToDeclaration/-net/com.drake.net.request/-url-request/index.html +$dokka.location:com.drake.net.request/UrlRequest/UrlRequest/#/PointingToDeclaration/-net/com.drake.net.request/-url-request/-url-request.html +$dokka.location:com.drake.net.request/UrlRequest/param/#kotlin.String#kotlin.Boolean?/PointingToDeclaration/-net/com.drake.net.request/-url-request/param.html +$dokka.location:com.drake.net.request/UrlRequest/param/#kotlin.String#kotlin.Number?/PointingToDeclaration/-net/com.drake.net.request/-url-request/param.html +$dokka.location:com.drake.net.request/UrlRequest/param/#kotlin.String#kotlin.String?#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.request/-url-request/param.html +$dokka.location:com.drake.net.request/UrlRequest/param/#kotlin.String#kotlin.String?/PointingToDeclaration/-net/com.drake.net.request/-url-request/param.html +$dokka.location:com.drake.net.response////PointingToDeclaration/-net/com.drake.net.response/index.html +$dokka.location:com.drake.net.response//convert/okhttp3.Response#/PointingToDeclaration/-net/com.drake.net.response/convert.html +$dokka.location:com.drake.net.response//convert/okhttp3.Response#java.lang.reflect.Type/PointingToDeclaration/-net/com.drake.net.response/convert.html +$dokka.location:com.drake.net.response//file/okhttp3.Response#/PointingToDeclaration/-net/com.drake.net.response/file.html +$dokka.location:com.drake.net.response//fileName/okhttp3.Response#/PointingToDeclaration/-net/com.drake.net.response/file-name.html +$dokka.location:com.drake.net.scope////PointingToDeclaration/-net/com.drake.net.scope/index.html +$dokka.location:com.drake.net.scope/AndroidScope///PointingToDeclaration/-net/com.drake.net.scope/-android-scope/index.html +$dokka.location:com.drake.net.scope/AndroidScope/AndroidScope/#androidx.lifecycle.LifecycleOwner?#androidx.lifecycle.Lifecycle.Event#kotlinx.coroutines.CoroutineDispatcher/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/-android-scope.html +$dokka.location:com.drake.net.scope/AndroidScope/cancel/#CancellationException?/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/cancel.html +$dokka.location:com.drake.net.scope/AndroidScope/cancel/#kotlin.String#kotlin.Throwable?/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/cancel.html +$dokka.location:com.drake.net.scope/AndroidScope/catch/#kotlin.Function2[com.drake.net.scope.AndroidScope,kotlin.Throwable,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/catch.html +$dokka.location:com.drake.net.scope/AndroidScope/close/#/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/close.html +$dokka.location:com.drake.net.scope/AndroidScope/coroutineContext/#/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/coroutine-context.html +$dokka.location:com.drake.net.scope/AndroidScope/dispatcher/#/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/dispatcher.html +$dokka.location:com.drake.net.scope/AndroidScope/finally/#kotlin.Function2[com.drake.net.scope.AndroidScope,kotlin.Throwable?,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/finally.html +$dokka.location:com.drake.net.scope/AndroidScope/handleError/#kotlin.Throwable/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/handle-error.html +$dokka.location:com.drake.net.scope/AndroidScope/launch/#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/launch.html +$dokka.location:com.drake.net.scope/AndroidScope/scopeGroup/#/PointingToDeclaration/-net/com.drake.net.scope/-android-scope/scope-group.html +$dokka.location:com.drake.net.scope/DialogCoroutineScope///PointingToDeclaration/-net/com.drake.net.scope/-dialog-coroutine-scope/index.html +$dokka.location:com.drake.net.scope/DialogCoroutineScope/DialogCoroutineScope/#androidx.fragment.app.FragmentActivity#android.app.Dialog?#kotlin.Boolean?#kotlinx.coroutines.CoroutineDispatcher/PointingToDeclaration/-net/com.drake.net.scope/-dialog-coroutine-scope/-dialog-coroutine-scope.html +$dokka.location:com.drake.net.scope/DialogCoroutineScope/activity/#/PointingToDeclaration/-net/com.drake.net.scope/-dialog-coroutine-scope/activity.html +$dokka.location:com.drake.net.scope/DialogCoroutineScope/cancelable/#/PointingToDeclaration/-net/com.drake.net.scope/-dialog-coroutine-scope/cancelable.html +$dokka.location:com.drake.net.scope/DialogCoroutineScope/dialog/#/PointingToDeclaration/-net/com.drake.net.scope/-dialog-coroutine-scope/dialog.html +$dokka.location:com.drake.net.scope/NetCoroutineScope///PointingToDeclaration/-net/com.drake.net.scope/-net-coroutine-scope/index.html +$dokka.location:com.drake.net.scope/NetCoroutineScope/NetCoroutineScope/#androidx.lifecycle.LifecycleOwner?#androidx.lifecycle.Lifecycle.Event#kotlinx.coroutines.CoroutineDispatcher/PointingToDeclaration/-net/com.drake.net.scope/-net-coroutine-scope/-net-coroutine-scope.html +$dokka.location:com.drake.net.scope/NetCoroutineScope/cancel/#CancellationException?/PointingToDeclaration/-net/com.drake.net.scope/-net-coroutine-scope/cancel.html +$dokka.location:com.drake.net.scope/NetCoroutineScope/handleError/#kotlin.Throwable/PointingToDeclaration/-net/com.drake.net.scope/-net-coroutine-scope/handle-error.html +$dokka.location:com.drake.net.scope/NetCoroutineScope/launch/#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.scope/-net-coroutine-scope/launch.html +$dokka.location:com.drake.net.scope/NetCoroutineScope/preview/#kotlin.Boolean#kotlin.Boolean#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.scope/-net-coroutine-scope/preview.html +$dokka.location:com.drake.net.scope/PageCoroutineScope///PointingToDeclaration/-net/com.drake.net.scope/-page-coroutine-scope/index.html +$dokka.location:com.drake.net.scope/PageCoroutineScope/PageCoroutineScope/#com.drake.brv.PageRefreshLayout#kotlinx.coroutines.CoroutineDispatcher/PointingToDeclaration/-net/com.drake.net.scope/-page-coroutine-scope/-page-coroutine-scope.html +$dokka.location:com.drake.net.scope/PageCoroutineScope/handleError/#kotlin.Throwable/PointingToDeclaration/-net/com.drake.net.scope/-page-coroutine-scope/handle-error.html +$dokka.location:com.drake.net.scope/PageCoroutineScope/index/#/PointingToDeclaration/-net/com.drake.net.scope/-page-coroutine-scope/--index--.html +$dokka.location:com.drake.net.scope/PageCoroutineScope/page/#/PointingToDeclaration/-net/com.drake.net.scope/-page-coroutine-scope/page.html +$dokka.location:com.drake.net.scope/StateCoroutineScope///PointingToDeclaration/-net/com.drake.net.scope/-state-coroutine-scope/index.html +$dokka.location:com.drake.net.scope/StateCoroutineScope/StateCoroutineScope/#com.drake.statelayout.StateLayout#kotlinx.coroutines.CoroutineDispatcher/PointingToDeclaration/-net/com.drake.net.scope/-state-coroutine-scope/-state-coroutine-scope.html +$dokka.location:com.drake.net.scope/StateCoroutineScope/handleError/#kotlin.Throwable/PointingToDeclaration/-net/com.drake.net.scope/-state-coroutine-scope/handle-error.html +$dokka.location:com.drake.net.scope/StateCoroutineScope/state/#/PointingToDeclaration/-net/com.drake.net.scope/-state-coroutine-scope/state.html +$dokka.location:com.drake.net.scope/ViewCoroutineScope///PointingToDeclaration/-net/com.drake.net.scope/-view-coroutine-scope/index.html +$dokka.location:com.drake.net.scope/ViewCoroutineScope/ViewCoroutineScope/#android.view.View#kotlinx.coroutines.CoroutineDispatcher/PointingToDeclaration/-net/com.drake.net.scope/-view-coroutine-scope/-view-coroutine-scope.html +$dokka.location:com.drake.net.scope/ViewCoroutineScope/view/#/PointingToDeclaration/-net/com.drake.net.scope/-view-coroutine-scope/view.html +$dokka.location:com.drake.net.tag////PointingToDeclaration/-net/com.drake.net.tag/index.html +$dokka.location:com.drake.net.tag/NetTag.CacheKey///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-cache-key/index.html +$dokka.location:com.drake.net.tag/NetTag.CacheKey/CacheKey/#kotlin.String/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-cache-key/-cache-key.html +$dokka.location:com.drake.net.tag/NetTag.CacheKey/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-cache-key/value.html +$dokka.location:com.drake.net.tag/NetTag.CacheValidTime///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-cache-valid-time/index.html +$dokka.location:com.drake.net.tag/NetTag.CacheValidTime/CacheValidTime/#kotlin.Long/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-cache-valid-time/-cache-valid-time.html +$dokka.location:com.drake.net.tag/NetTag.CacheValidTime/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-cache-valid-time/value.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileConflictRename///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/index.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileConflictRename/DownloadFileConflictRename/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/-download-file-conflict-rename.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileConflictRename/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-conflict-rename/value.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileDir///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-dir/index.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileDir/DownloadFileDir/#java.io.File/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-dir/-download-file-dir.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileDir/DownloadFileDir/#kotlin.String/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-dir/-download-file-dir.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileDir/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-dir/value.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileMD5Verify///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/index.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileMD5Verify/DownloadFileMD5Verify/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/-download-file-m-d5-verify.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileMD5Verify/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-m-d5-verify/value.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileName///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-name/index.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileName/DownloadFileName/#kotlin.String/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-name/-download-file-name.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileName/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-name/value.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileNameDecode///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/index.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileNameDecode/DownloadFileNameDecode/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/-download-file-name-decode.html +$dokka.location:com.drake.net.tag/NetTag.DownloadFileNameDecode/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-file-name-decode/value.html +$dokka.location:com.drake.net.tag/NetTag.DownloadListeners///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-listeners/index.html +$dokka.location:com.drake.net.tag/NetTag.DownloadListeners/DownloadListeners/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-listeners/-download-listeners.html +$dokka.location:com.drake.net.tag/NetTag.DownloadTempFile///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-temp-file/index.html +$dokka.location:com.drake.net.tag/NetTag.DownloadTempFile/DownloadTempFile/#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-temp-file/-download-temp-file.html +$dokka.location:com.drake.net.tag/NetTag.DownloadTempFile/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-download-temp-file/value.html +$dokka.location:com.drake.net.tag/NetTag.Extras///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-extras/index.html +$dokka.location:com.drake.net.tag/NetTag.Extras/Extras/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-extras/-extras.html +$dokka.location:com.drake.net.tag/NetTag.RequestGroup///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-group/index.html +$dokka.location:com.drake.net.tag/NetTag.RequestGroup/RequestGroup/#kotlin.Any/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-group/-request-group.html +$dokka.location:com.drake.net.tag/NetTag.RequestGroup/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-group/value.html +$dokka.location:com.drake.net.tag/NetTag.RequestId///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-id/index.html +$dokka.location:com.drake.net.tag/NetTag.RequestId/RequestId/#kotlin.Any/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-id/-request-id.html +$dokka.location:com.drake.net.tag/NetTag.RequestId/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-id/value.html +$dokka.location:com.drake.net.tag/NetTag.RequestKType///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-k-type/index.html +$dokka.location:com.drake.net.tag/NetTag.RequestKType/RequestKType/#kotlin.reflect.KType/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-k-type/-request-k-type.html +$dokka.location:com.drake.net.tag/NetTag.RequestKType/value/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-request-k-type/value.html +$dokka.location:com.drake.net.tag/NetTag.UploadListeners///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-upload-listeners/index.html +$dokka.location:com.drake.net.tag/NetTag.UploadListeners/UploadListeners/#/PointingToDeclaration/-net/com.drake.net.tag/-net-tag/-upload-listeners/-upload-listeners.html +$dokka.location:com.drake.net.tag/NetTag///PointingToDeclaration/-net/com.drake.net.tag/-net-tag/index.html +$dokka.location:com.drake.net.time////PointingToDeclaration/-net/com.drake.net.time/index.html +$dokka.location:com.drake.net.time/Interval///PointingToDeclaration/-net/com.drake.net.time/-interval/index.html +$dokka.location:com.drake.net.time/Interval/Interval/#kotlin.Long#java.util.concurrent.TimeUnit#kotlin.Long/PointingToDeclaration/-net/com.drake.net.time/-interval/-interval.html +$dokka.location:com.drake.net.time/Interval/Interval/#kotlin.Long#kotlin.Long#java.util.concurrent.TimeUnit#kotlin.Long#kotlin.Long/PointingToDeclaration/-net/com.drake.net.time/-interval/-interval.html +$dokka.location:com.drake.net.time/Interval/cancel/#/PointingToDeclaration/-net/com.drake.net.time/-interval/cancel.html +$dokka.location:com.drake.net.time/Interval/close/#/PointingToDeclaration/-net/com.drake.net.time/-interval/close.html +$dokka.location:com.drake.net.time/Interval/count/#/PointingToDeclaration/-net/com.drake.net.time/-interval/count.html +$dokka.location:com.drake.net.time/Interval/end/#/PointingToDeclaration/-net/com.drake.net.time/-interval/end.html +$dokka.location:com.drake.net.time/Interval/finish/#kotlin.Function2[com.drake.net.time.Interval,kotlin.Long,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.time/-interval/finish.html +$dokka.location:com.drake.net.time/Interval/life/#androidx.fragment.app.Fragment#androidx.lifecycle.Lifecycle.Event/PointingToDeclaration/-net/com.drake.net.time/-interval/life.html +$dokka.location:com.drake.net.time/Interval/life/#androidx.lifecycle.LifecycleOwner#androidx.lifecycle.Lifecycle.Event/PointingToDeclaration/-net/com.drake.net.time/-interval/life.html +$dokka.location:com.drake.net.time/Interval/onlyResumed/#androidx.lifecycle.LifecycleOwner/PointingToDeclaration/-net/com.drake.net.time/-interval/only-resumed.html +$dokka.location:com.drake.net.time/Interval/pause/#/PointingToDeclaration/-net/com.drake.net.time/-interval/pause.html +$dokka.location:com.drake.net.time/Interval/reset/#/PointingToDeclaration/-net/com.drake.net.time/-interval/reset.html +$dokka.location:com.drake.net.time/Interval/resume/#/PointingToDeclaration/-net/com.drake.net.time/-interval/resume.html +$dokka.location:com.drake.net.time/Interval/start/#/PointingToDeclaration/-net/com.drake.net.time/-interval/start.html +$dokka.location:com.drake.net.time/Interval/state/#/PointingToDeclaration/-net/com.drake.net.time/-interval/state.html +$dokka.location:com.drake.net.time/Interval/stop/#/PointingToDeclaration/-net/com.drake.net.time/-interval/stop.html +$dokka.location:com.drake.net.time/Interval/subscribe/#kotlin.Function2[com.drake.net.time.Interval,kotlin.Long,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.time/-interval/subscribe.html +$dokka.location:com.drake.net.time/Interval/switch/#/PointingToDeclaration/-net/com.drake.net.time/-interval/switch.html +$dokka.location:com.drake.net.time/IntervalStatus.STATE_ACTIVE///PointingToDeclaration/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-a-c-t-i-v-e/index.html +$dokka.location:com.drake.net.time/IntervalStatus.STATE_IDLE///PointingToDeclaration/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-i-d-l-e/index.html +$dokka.location:com.drake.net.time/IntervalStatus.STATE_PAUSE///PointingToDeclaration/-net/com.drake.net.time/-interval-status/-s-t-a-t-e_-p-a-u-s-e/index.html +$dokka.location:com.drake.net.time/IntervalStatus///PointingToDeclaration/-net/com.drake.net.time/-interval-status/index.html +$dokka.location:com.drake.net.transform////PointingToDeclaration/-net/com.drake.net.transform/index.html +$dokka.location:com.drake.net.transform//transform/kotlinx.coroutines.Deferred[TypeParam(bounds=[kotlin.Any?])]#kotlin.Function1[TypeParam(bounds=[kotlin.Any?]),TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration/-net/com.drake.net.transform/transform.html +$dokka.location:com.drake.net.transform/DeferredTransform///PointingToDeclaration/-net/com.drake.net.transform/-deferred-transform/index.html +$dokka.location:com.drake.net.transform/DeferredTransform/DeferredTransform/#kotlinx.coroutines.Deferred[TypeParam(bounds=[kotlin.Any?])]#kotlin.Function1[TypeParam(bounds=[kotlin.Any?]),TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration/-net/com.drake.net.transform/-deferred-transform/-deferred-transform.html +$dokka.location:com.drake.net.transform/DeferredTransform/block/#/PointingToDeclaration/-net/com.drake.net.transform/-deferred-transform/block.html +$dokka.location:com.drake.net.transform/DeferredTransform/deferred/#/PointingToDeclaration/-net/com.drake.net.transform/-deferred-transform/deferred.html +$dokka.location:com.drake.net.utils////PointingToDeclaration/-net/com.drake.net.utils/index.html +$dokka.location:com.drake.net.utils//debounce/android.widget.EditText#kotlin.Long/PointingToDeclaration/-net/com.drake.net.utils/debounce.html +$dokka.location:com.drake.net.utils//fastest/#kotlin.collections.List[com.drake.net.transform.DeferredTransform[TypeParam(bounds=[kotlin.Any?]),TypeParam(bounds=[kotlin.Any?])]]?#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.utils/fastest.html +$dokka.location:com.drake.net.utils//fastest/#kotlin.collections.List[kotlinx.coroutines.Deferred[TypeParam(bounds=[kotlin.Any?])]]#kotlin.Any?/PointingToDeclaration/-net/com.drake.net.utils/fastest.html +$dokka.location:com.drake.net.utils//fileName/android.net.Uri#/PointingToDeclaration/-net/com.drake.net.utils/file-name.html +$dokka.location:com.drake.net.utils//isNetworking/android.content.Context#/PointingToDeclaration/-net/com.drake.net.utils/is-networking.html +$dokka.location:com.drake.net.utils//launchIn/kotlinx.coroutines.flow.Flow[TypeParam(bounds=[kotlin.Any?])]#androidx.lifecycle.LifecycleOwner?#androidx.lifecycle.Lifecycle.Event#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction2[kotlinx.coroutines.CoroutineScope,TypeParam(bounds=[kotlin.Any?]),kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/launch-in.html +$dokka.location:com.drake.net.utils//md5/java.io.File#kotlin.Boolean/PointingToDeclaration/-net/com.drake.net.utils/md5.html +$dokka.location:com.drake.net.utils//mediaType/android.net.Uri#/PointingToDeclaration/-net/com.drake.net.utils/media-type.html +$dokka.location:com.drake.net.utils//mediaType/java.io.File#/PointingToDeclaration/-net/com.drake.net.utils/media-type.html +$dokka.location:com.drake.net.utils//runMain/#kotlin.Function0[kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/run-main.html +$dokka.location:com.drake.net.utils//scope/#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope.html +$dokka.location:com.drake.net.utils//scope/com.drake.brv.PageRefreshLayout#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope.html +$dokka.location:com.drake.net.utils//scope/com.drake.statelayout.StateLayout#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope.html +$dokka.location:com.drake.net.utils//scopeDialog/androidx.fragment.app.Fragment#android.app.Dialog?#kotlin.Boolean#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-dialog.html +$dokka.location:com.drake.net.utils//scopeDialog/androidx.fragment.app.FragmentActivity#android.app.Dialog?#kotlin.Boolean#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-dialog.html +$dokka.location:com.drake.net.utils//scopeLife/androidx.fragment.app.Fragment#androidx.lifecycle.Lifecycle.Event#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-life.html +$dokka.location:com.drake.net.utils//scopeLife/androidx.lifecycle.LifecycleOwner#androidx.lifecycle.Lifecycle.Event#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-life.html +$dokka.location:com.drake.net.utils//scopeNet/#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-net.html +$dokka.location:com.drake.net.utils//scopeNetLife/android.view.View#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-net-life.html +$dokka.location:com.drake.net.utils//scopeNetLife/androidx.fragment.app.Fragment#androidx.lifecycle.Lifecycle.Event#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-net-life.html +$dokka.location:com.drake.net.utils//scopeNetLife/androidx.lifecycle.LifecycleOwner#androidx.lifecycle.Lifecycle.Event#kotlinx.coroutines.CoroutineDispatcher#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net.utils/scope-net-life.html +$dokka.location:com.drake.net.utils//toRequestBody/android.net.Uri#/PointingToDeclaration/-net/com.drake.net.utils/to-request-body.html +$dokka.location:com.drake.net.utils//toRequestBody/java.io.File#okhttp3.MediaType?/PointingToDeclaration/-net/com.drake.net.utils/to-request-body.html +$dokka.location:com.drake.net.utils//withDefault/#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration/-net/com.drake.net.utils/with-default.html +$dokka.location:com.drake.net.utils//withIO/#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration/-net/com.drake.net.utils/with-i-o.html +$dokka.location:com.drake.net.utils//withMain/#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration/-net/com.drake.net.utils/with-main.html +$dokka.location:com.drake.net.utils//withUnconfined/#kotlin.coroutines.SuspendFunction1[kotlinx.coroutines.CoroutineScope,TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration/-net/com.drake.net.utils/with-unconfined.html +$dokka.location:com.drake.net.utils/Https///PointingToDeclaration/-net/com.drake.net.utils/-https/index.html +$dokka.location:com.drake.net.utils/Https/UnSafeHostnameVerifier/#/PointingToDeclaration/-net/com.drake.net.utils/-https/-un-safe-hostname-verifier.html +$dokka.location:com.drake.net.utils/Https/UnSafeTrustManager/#/PointingToDeclaration/-net/com.drake.net.utils/-https/-un-safe-trust-manager.html +$dokka.location:com.drake.net.utils/TipUtils///PointingToDeclaration/-net/com.drake.net.utils/-tip-utils/index.html +$dokka.location:com.drake.net.utils/TipUtils/toast/#kotlin.String?/PointingToDeclaration/-net/com.drake.net.utils/-tip-utils/toast.html +$dokka.location:com.drake.net////PointingToDeclaration/-net/com.drake.net/index.html +$dokka.location:com.drake.net//Delete/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-delete.html +$dokka.location:com.drake.net//Get/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-get.html +$dokka.location:com.drake.net//Head/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-head.html +$dokka.location:com.drake.net//Options/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-options.html +$dokka.location:com.drake.net//Patch/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-patch.html +$dokka.location:com.drake.net//Post/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-post.html +$dokka.location:com.drake.net//Put/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-put.html +$dokka.location:com.drake.net//Trace/kotlinx.coroutines.CoroutineScope#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-trace.html +$dokka.location:com.drake.net/Net///PointingToDeclaration/-net/com.drake.net/-net/index.html +$dokka.location:com.drake.net/Net/addDownloadListener/#kotlin.Any#com.drake.net.interfaces.ProgressListener/PointingToDeclaration/-net/com.drake.net/-net/add-download-listener.html +$dokka.location:com.drake.net/Net/addUploadListener/#kotlin.Any#com.drake.net.interfaces.ProgressListener/PointingToDeclaration/-net/com.drake.net/-net/add-upload-listener.html +$dokka.location:com.drake.net/Net/cancelAll/#/PointingToDeclaration/-net/com.drake.net/-net/cancel-all.html +$dokka.location:com.drake.net/Net/cancelGroup/#kotlin.Any?/PointingToDeclaration/-net/com.drake.net/-net/cancel-group.html +$dokka.location:com.drake.net/Net/cancelId/#kotlin.Any?/PointingToDeclaration/-net/com.drake.net/-net/cancel-id.html +$dokka.location:com.drake.net/Net/debug/#kotlin.Any/PointingToDeclaration/-net/com.drake.net/-net/debug.html +$dokka.location:com.drake.net/Net/delete/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/delete.html +$dokka.location:com.drake.net/Net/get/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/get.html +$dokka.location:com.drake.net/Net/getRequestByGroup/#kotlin.Any/PointingToDeclaration/-net/com.drake.net/-net/get-request-by-group.html +$dokka.location:com.drake.net/Net/getRequestById/#kotlin.Any/PointingToDeclaration/-net/com.drake.net/-net/get-request-by-id.html +$dokka.location:com.drake.net/Net/head/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/head.html +$dokka.location:com.drake.net/Net/options/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/options.html +$dokka.location:com.drake.net/Net/patch/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/patch.html +$dokka.location:com.drake.net/Net/post/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/post.html +$dokka.location:com.drake.net/Net/put/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.BodyRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/put.html +$dokka.location:com.drake.net/Net/removeDownloadListener/#kotlin.Any#com.drake.net.interfaces.ProgressListener/PointingToDeclaration/-net/com.drake.net/-net/remove-download-listener.html +$dokka.location:com.drake.net/Net/removeUploadListener/#kotlin.Any#com.drake.net.interfaces.ProgressListener/PointingToDeclaration/-net/com.drake.net/-net/remove-upload-listener.html +$dokka.location:com.drake.net/Net/trace/#kotlin.String#kotlin.Any?#kotlin.Function1[com.drake.net.request.UrlRequest,kotlin.Unit]?/PointingToDeclaration/-net/com.drake.net/-net/trace.html +$dokka.location:com.drake.net/NetConfig///PointingToDeclaration/-net/com.drake.net/-net-config/index.html +$dokka.location:com.drake.net/NetConfig/TAG/#/PointingToDeclaration/-net/com.drake.net/-net-config/-t-a-g.html +$dokka.location:com.drake.net/NetConfig/app/#/PointingToDeclaration/-net/com.drake.net/-net-config/app.html +$dokka.location:com.drake.net/NetConfig/converter/#/PointingToDeclaration/-net/com.drake.net/-net-config/converter.html +$dokka.location:com.drake.net/NetConfig/debug/#/PointingToDeclaration/-net/com.drake.net/-net-config/debug.html +$dokka.location:com.drake.net/NetConfig/dialogFactory/#/PointingToDeclaration/-net/com.drake.net/-net-config/dialog-factory.html +$dokka.location:com.drake.net/NetConfig/errorHandler/#/PointingToDeclaration/-net/com.drake.net/-net-config/error-handler.html +$dokka.location:com.drake.net/NetConfig/host/#/PointingToDeclaration/-net/com.drake.net/-net-config/host.html +$dokka.location:com.drake.net/NetConfig/initialize/#kotlin.String#android.content.Context?#kotlin.Function1[okhttp3.OkHttpClient.Builder,kotlin.Unit]/PointingToDeclaration/-net/com.drake.net/-net-config/initialize.html +$dokka.location:com.drake.net/NetConfig/initialize/#kotlin.String#android.content.Context?#okhttp3.OkHttpClient.Builder/PointingToDeclaration/-net/com.drake.net/-net-config/initialize.html +$dokka.location:com.drake.net/NetConfig/okHttpClient/#/PointingToDeclaration/-net/com.drake.net/-net-config/ok-http-client.html +$dokka.location:com.drake.net/NetConfig/requestInterceptor/#/PointingToDeclaration/-net/com.drake.net/-net-config/request-interceptor.html +$dokka.location:com.drake.net/NetConfig/runningCalls/#/PointingToDeclaration/-net/com.drake.net/-net-config/running-calls.html +$dokka.location:okhttp3////PointingToDeclaration/-net/okhttp3/index.html +$dokka.location:okhttp3/OkHttpUtils///PointingToDeclaration/-net/okhttp3/-ok-http-utils/index.html +$dokka.location:okhttp3/OkHttpUtils/addLenient/#okhttp3.Headers.Builder#java.lang.String/PointingToDeclaration/-net/okhttp3/-ok-http-utils/add-lenient.html +$dokka.location:okhttp3/OkHttpUtils/diskLruCache/#okhttp3.Cache/PointingToDeclaration/-net/okhttp3/-ok-http-utils/disk-lru-cache.html +$dokka.location:okhttp3/OkHttpUtils/headers/#okhttp3.Request.Builder/PointingToDeclaration/-net/okhttp3/-ok-http-utils/headers.html +$dokka.location:okhttp3/OkHttpUtils/tags/#okhttp3.Request.Builder/PointingToDeclaration/-net/okhttp3/-ok-http-utils/tags.html +$dokka.location:okhttp3/OkHttpUtils/tags/#okhttp3.Request/PointingToDeclaration/-net/okhttp3/-ok-http-utils/tags.html +androidx.lifecycle +com.drake.net +com.drake.net.body +com.drake.net.cache +com.drake.net.component +com.drake.net.convert +com.drake.net.cookie +com.drake.net.exception +com.drake.net.interceptor +com.drake.net.interfaces +com.drake.net.log +com.drake.net.okhttp +com.drake.net.reflect +com.drake.net.request +com.drake.net.response +com.drake.net.scope +com.drake.net.tag +com.drake.net.time +com.drake.net.transform +com.drake.net.utils +okhttp3 + diff --git a/api/images/anchor-copy-button.svg b/api/images/anchor-copy-button.svg new file mode 100644 index 000000000..bab9d747f --- /dev/null +++ b/api/images/anchor-copy-button.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/api/images/arrow_down.svg b/api/images/arrow_down.svg new file mode 100644 index 000000000..89e7df471 --- /dev/null +++ b/api/images/arrow_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/api/images/copy-icon.svg b/api/images/copy-icon.svg new file mode 100644 index 000000000..61440f0a4 --- /dev/null +++ b/api/images/copy-icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/api/images/copy-successful-icon.svg b/api/images/copy-successful-icon.svg new file mode 100644 index 000000000..1865f739b --- /dev/null +++ b/api/images/copy-successful-icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/api/images/docs_logo.svg b/api/images/docs_logo.svg new file mode 100644 index 000000000..7c1e3ae8e --- /dev/null +++ b/api/images/docs_logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/api/images/footer-go-to-link.svg b/api/images/footer-go-to-link.svg new file mode 100644 index 000000000..0137e2231 --- /dev/null +++ b/api/images/footer-go-to-link.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/api/images/go-to-top-icon.svg b/api/images/go-to-top-icon.svg new file mode 100644 index 000000000..d987f3ead --- /dev/null +++ b/api/images/go-to-top-icon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/api/images/logo-icon.svg b/api/images/logo-icon.svg new file mode 100644 index 000000000..1b3b3670e --- /dev/null +++ b/api/images/logo-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/api/index.html b/api/index.html new file mode 100644 index 000000000..d6331a09a --- /dev/null +++ b/api/index.html @@ -0,0 +1,286 @@ + + + + Net + + +
+
+ + +
+
+
+
+
+
+ +
+

Net

+
+

Packages

+
+
+
+
+
androidx.lifecycle +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.body +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.cache +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.component +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.convert +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.cookie +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.exception +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.interceptor +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.interfaces +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.log +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.okhttp +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.reflect +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.request +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.response +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.scope +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.tag +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.time +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.transform +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
com.drake.net.utils +
Link copied to clipboard
+
+
+
+
+
+
+ +
+
+
+
okhttp3 +
Link copied to clipboard
+
+
+
+
+
+
+
+
+ +
+
+ + + diff --git a/api/navigation.html b/api/navigation.html new file mode 100644 index 000000000..4c5bf69c0 --- /dev/null +++ b/api/navigation.html @@ -0,0 +1,520 @@ +
+ + +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + + + + + + + + + + +
+ + + + + + + + + + + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+ +
+
+ +
+ + +
+ + + + + +
+ + +
+ +
+ +
+ +
+ + +
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+
+ diff --git a/api/scripts/clipboard.js b/api/scripts/clipboard.js new file mode 100644 index 000000000..b00ce246e --- /dev/null +++ b/api/scripts/clipboard.js @@ -0,0 +1,52 @@ +window.addEventListener('load', () => { + document.querySelectorAll('span.copy-icon').forEach(element => { + element.addEventListener('click', (el) => copyElementsContentToClipboard(element)); + }) + + document.querySelectorAll('span.anchor-icon').forEach(element => { + element.addEventListener('click', (el) => { + if(element.hasAttribute('pointing-to')){ + const location = hrefWithoutCurrentlyUsedAnchor() + '#' + element.getAttribute('pointing-to') + copyTextToClipboard(element, location) + } + }); + }) +}) + +const copyElementsContentToClipboard = (element) => { + const selection = window.getSelection(); + const range = document.createRange(); + range.selectNodeContents(element.parentNode.parentNode); + selection.removeAllRanges(); + selection.addRange(range); + + copyAndShowPopup(element, () => selection.removeAllRanges()) +} + +const copyTextToClipboard = (element, text) => { + var textarea = document.createElement("textarea"); + textarea.textContent = text; + textarea.style.position = "fixed"; + document.body.appendChild(textarea); + textarea.select(); + + copyAndShowPopup(element, () => document.body.removeChild(textarea)) +} + +const copyAndShowPopup = (element, after) => { + try { + document.execCommand('copy'); + element.nextElementSibling.classList.add('active-popup'); + setTimeout(() => { + element.nextElementSibling.classList.remove('active-popup'); + }, 1200); + } catch (e) { + console.error('Failed to write to clipboard:', e) + } + finally { + if(after) after() + } +} + +const hrefWithoutCurrentlyUsedAnchor = () => window.location.href.split('#')[0] + diff --git a/api/scripts/main.js b/api/scripts/main.js new file mode 100644 index 000000000..029fa9eb8 --- /dev/null +++ b/api/scripts/main.js @@ -0,0 +1,67 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=390)}([function(e,t,n){e.exports=n(264)()},function(e,t,n){"use strict";e.exports=n(239)},function(e,t,n){var r; +/*! + Copyright (c) 2017 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;to;)Q(e,n=r[o++],t[n]);return e},X=function(e){var t=F.call(this,e=x(e,!0));return!(this===W&&o(H,e)&&!o(U,e))&&(!(t||!o(this,e)||!o(H,e)||o(this,A)&&this[A][e])||t)},J=function(e,t){if(e=w(e),t=x(t,!0),e!==W||!o(H,t)||o(U,t)){var n=I(e,t);return!n||!o(H,t)||o(e,A)&&e[A][t]||(n.enumerable=!0),n}},Z=function(e){for(var t,n=z(w(e)),r=[],i=0;n.length>i;)o(H,t=n[i++])||t==A||t==c||r.push(t);return r},ee=function(e){for(var t,n=e===W,r=z(n?U:w(e)),i=[],a=0;r.length>a;)!o(H,t=r[a++])||n&&!o(W,t)||i.push(H[t]);return i};B||(l((R=function(){if(this instanceof R)throw TypeError("Symbol is not a constructor!");var e=p(arguments.length>0?arguments[0]:void 0),t=function(n){this===W&&t.call(U,n),o(this,A)&&o(this[A],e)&&(this[A][e]=!1),K(this,e,S(1,n))};return i&&G&&K(W,e,{configurable:!0,set:t}),q(e)}).prototype,"toString",(function(){return this._k})),E.f=J,C.f=Q,n(114).f=O.f=Z,n(95).f=X,T.f=ee,i&&!n(111)&&l(W,"propertyIsEnumerable",X,!0),h.f=function(e){return q(d(e))}),a(a.G+a.W+a.F*!B,{Symbol:R});for(var te="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),ne=0;te.length>ne;)d(te[ne++]);for(var re=P(d.store),oe=0;re.length>oe;)v(re[oe++]);a(a.S+a.F*!B,"Symbol",{for:function(e){return o(D,e+="")?D[e]:D[e]=R(e)},keyFor:function(e){if(!$(e))throw TypeError(e+" is not a symbol!");for(var t in D)if(D[t]===e)return t},useSetter:function(){G=!0},useSimple:function(){G=!1}}),a(a.S+a.F*!B,"Object",{create:function(e,t){return void 0===t?k(e):Y(k(e),t)},defineProperty:Q,defineProperties:Y,getOwnPropertyDescriptor:J,getOwnPropertyNames:Z,getOwnPropertySymbols:ee});var ie=u((function(){T.f(1)}));a(a.S+a.F*ie,"Object",{getOwnPropertySymbols:function(e){return T.f(_(e))}}),M&&a(a.S+a.F*(!B||u((function(){var e=R();return"[null]"!=N([e])||"{}"!=N({a:e})||"{}"!=N(Object(e))}))),"JSON",{stringify:function(e){for(var t,n,r=[e],o=1;arguments.length>o;)r.push(arguments[o++]);if(n=t=r[1],(b(t)||void 0!==e)&&!$(e))return m(t)||(t=function(e,t){if("function"==typeof n&&(t=n.call(this,e,t)),!$(t))return t}),r[1]=t,N.apply(M,r)}}),R.prototype[L]||n(59)(R.prototype,L,R.prototype.valueOf),f(R,"Symbol"),f(Math,"Math",!0),f(r.JSON,"JSON",!0)},function(e,t,n){var r=n(10);r(r.S+r.F*!n(30),"Object",{defineProperty:n(39).f})},function(e,t,n){"use strict";n(257);var r=n(27),o=n(135),i=n(30),a=/./.toString,l=function(e){n(42)(RegExp.prototype,"toString",e,!0)};n(31)((function(){return"/a/b"!=a.call({source:"a",flags:"b"})}))?l((function(){var e=r(this);return"/".concat(e.source,"/","flags"in e?e.flags:!i&&e instanceof RegExp?o.call(e):void 0)})):"toString"!=a.name&&l((function(){return a.call(this)}))},function(e,t,n){var r=Date.prototype,o=r.toString,i=r.getTime;new Date(NaN)+""!="Invalid Date"&&n(42)(r,"toString",(function(){var e=i.call(this);return e==e?o.call(this):"Invalid Date"}))},function(e,t,n){n(182)("asyncIterator")},function(e,t,n){var r=n(32),o=n(79),i=n(59),a=n(42),l=n(80),c=function(e,t,n){var u,s,f,p,d=e&c.F,h=e&c.G,v=e&c.S,g=e&c.P,m=e&c.B,y=h?r:v?r[t]||(r[t]={}):(r[t]||{}).prototype,b=h?o:o[t]||(o[t]={}),_=b.prototype||(b.prototype={});for(u in h&&(n=t),n)f=((s=!d&&y&&void 0!==y[u])?y:n)[u],p=m&&s?l(f,r):g&&"function"==typeof f?l(Function.call,f):f,y&&a(y,u,f,e&c.U),b[u]!=f&&i(b,u,p),g&&_[u]!=f&&(_[u]=f)};r.core=o,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,t,n){for(var r=n(12),o=n(70),i=n(42),a=n(32),l=n(59),c=n(96),u=n(25),s=u("iterator"),f=u("toStringTag"),p=c.Array,d={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},h=o(d),v=0;v=e.length?(this._t=void 0,o(1)):o(0,"keys"==t?n:"values"==t?e[n]:[n,e[n]])}),"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},function(e,t,n){var r=n(10);r(r.S,"Object",{create:n(83)})},function(e,t,n){var r=n(10),o=n(83),i=n(81),a=n(27),l=n(29),c=n(31),u=n(184),s=(n(32).Reflect||{}).construct,f=c((function(){function e(){}return!(s((function(){}),[],e)instanceof e)})),p=!c((function(){s((function(){}))}));r(r.S+r.F*(f||p),"Reflect",{construct:function(e,t){i(e),a(t);var n=arguments.length<3?e:i(arguments[2]);if(p&&!f)return s(e,t,n);if(e==n){switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3])}var r=[null];return r.push.apply(r,t),new(u.apply(e,r))}var c=n.prototype,d=o(l(c)?c:Object.prototype),h=Function.apply.call(e,d,t);return l(h)?h:d}})},function(e,t,n){var r=n(10);r(r.S,"Object",{setPrototypeOf:n(180).set})},function(e,t,n){var r=n(54),o=n(70);n(252)("keys",(function(){return function(e){return o(r(e))}}))},function(e,t,n){"use strict";var r=n(10),o=n(130)(!1),i=[].indexOf,a=!!i&&1/[1].indexOf(1,-0)<0;r(r.P+r.F*(a||!n(72)(i)),"Array",{indexOf:function(e){return a?i.apply(this,arguments)||0:o(this,e,arguments[1])}})},function(e,t,n){var r=n(26),o=n(266);"string"==typeof(o=o.__esModule?o.default:o)&&(o=[[e.i,o,""]]);var i={insert:"head",singleton:!1};r(o,i);e.exports=o.locals||{}},function(e,t,n){var r=n(10);r(r.S+r.F,"Object",{assign:n(185)})},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t,n){"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=function(e,t){var n=e[1]||"",r=e[3];if(!r)return n;if(t&&"function"==typeof btoa){var o=(a=r,l=btoa(unescape(encodeURIComponent(JSON.stringify(a)))),c="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(l),"/*# ".concat(c," */")),i=r.sources.map((function(e){return"/*# sourceURL=".concat(r.sourceRoot||"").concat(e," */")}));return[n].concat(i).concat([o]).join("\n")}var a,l,c;return[n].join("\n")}(t,e);return t[2]?"@media ".concat(t[2]," {").concat(n,"}"):n})).join("")},t.i=function(e,n,r){"string"==typeof e&&(e=[[null,e,""]]);var o={};if(r)for(var i=0;i=t.length?{value:void 0,done:!0}:(e=r(t,n),this._i+=e.length,{value:e,done:!1})}))},function(e,t,n){var r=n(35),o=n(28),i=n(98),a=n(74),l=n(75),c=function(e,t,n){var u,s,f,p=e&c.F,d=e&c.G,h=e&c.S,v=e&c.P,g=e&c.B,m=e&c.W,y=d?o:o[t]||(o[t]={}),b=y.prototype,_=d?r:h?r[t]:(r[t]||{}).prototype;for(u in d&&(n=t),n)(s=!p&&_&&void 0!==_[u])&&l(y,u)||(f=s?_[u]:n[u],y[u]=d&&"function"!=typeof _[u]?n[u]:g&&s?i(f,r):m&&_[u]==f?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(f):v&&"function"==typeof f?i(Function.call,f):f,v&&((y.virtual||(y.virtual={}))[u]=f,e&c.R&&b&&!b[u]&&a(b,u,f)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,t,n){var r=n(26),o=n(332);"string"==typeof(o=o.__esModule?o.default:o)&&(o=[[e.i,o,""]]);var i={insert:"head",singleton:!1};r(o,i);e.exports=o.locals||{}},function(e,t,n){var r=n(113),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t,n){var r=n(71);e.exports=function(e){return Object(r(e))}},function(e,t,n){"use strict";var r=n(10),o=n(62)(1);r(r.P+r.F*!n(72)([].map,!0),"Array",{map:function(e){return o(this,e,arguments[1])}})},function(e,t,n){var r=n(64);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){e.exports=!n(85)((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},function(e,t,n){"use strict";var r=n(80),o=n(10),i=n(54),a=n(189),l=n(190),c=n(53),u=n(174),s=n(191);o(o.S+o.F*!n(192)((function(e){Array.from(e)})),"Array",{from:function(e){var t,n,o,f,p=i(e),d="function"==typeof this?this:Array,h=arguments.length,v=h>1?arguments[1]:void 0,g=void 0!==v,m=0,y=s(p);if(g&&(v=r(v,h>2?arguments[2]:void 0,2)),null==y||d==Array&&l(y))for(n=new d(t=c(p.length));t>m;m++)u(n,m,g?v(p[m],m):p[m]);else for(f=y.call(p),n=new d;!(o=f.next()).done;m++)u(n,m,g?a(f,v,[o.value,m],!0):o.value);return n.length=m,n}})},function(e,t,n){var r=n(39),o=n(91);e.exports=n(30)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(112),o=n(71);e.exports=function(e){return r(o(e))}},function(e,t,n){"use strict";var r=n(10),o=n(62)(0),i=n(72)([].forEach,!0);r(r.P+r.F*!i,"Array",{forEach:function(e){return o(this,e,arguments[1])}})},function(e,t,n){var r=n(80),o=n(112),i=n(54),a=n(53),l=n(259);e.exports=function(e,t){var n=1==e,c=2==e,u=3==e,s=4==e,f=6==e,p=5==e||f,d=t||l;return function(t,l,h){for(var v,g,m=i(t),y=o(m),b=r(l,h,3),_=a(y.length),w=0,x=n?d(t,_):c?d(t,0):void 0;_>w;w++)if((p||w in y)&&(g=b(v=y[w],w,m),e))if(n)x[w]=g;else if(g)switch(e){case 3:return!0;case 5:return v;case 6:return w;case 2:x.push(v)}else if(s)return!1;return f?-1:u||s?s:x}}},function(e,t,n){var r=n(56),o=n(200),i=n(147),a=Object.defineProperty;t.f=n(57)?Object.defineProperty:function(e,t,n){if(r(e),t=i(t,!0),r(n),o)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){e.exports={default:n(282),__esModule:!0}},function(e,t,n){"use strict";t.__esModule=!0;var r=a(n(304)),o=a(n(308)),i=a(n(205));function a(e){return e&&e.__esModule?e:{default:e}}t.default=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+(void 0===t?"undefined":(0,i.default)(t)));e.prototype=(0,o.default)(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(r.default?(0,r.default)(e,t):e.__proto__=t)}},function(e,t,n){(function(e,r){var o; +/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */(function(){var i="Expected a function",a="__lodash_placeholder__",l=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],c="[object Arguments]",u="[object Array]",s="[object Boolean]",f="[object Date]",p="[object Error]",d="[object Function]",h="[object GeneratorFunction]",v="[object Map]",g="[object Number]",m="[object Object]",y="[object RegExp]",b="[object Set]",_="[object String]",w="[object Symbol]",x="[object WeakMap]",S="[object ArrayBuffer]",k="[object DataView]",O="[object Float32Array]",E="[object Float64Array]",T="[object Int8Array]",C="[object Int16Array]",P="[object Int32Array]",I="[object Uint8Array]",j="[object Uint16Array]",z="[object Uint32Array]",R=/\b__p \+= '';/g,M=/\b(__p \+=) '' \+/g,N=/(__e\(.*?\)|\b__t\)) \+\n'';/g,A=/&(?:amp|lt|gt|quot|#39);/g,L=/[&<>"']/g,F=RegExp(A.source),D=RegExp(L.source),H=/<%-([\s\S]+?)%>/g,U=/<%([\s\S]+?)%>/g,W=/<%=([\s\S]+?)%>/g,B=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,V=/^\w*$/,G=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,K=/[\\^$.*+?()[\]{}|]/g,q=RegExp(K.source),$=/^\s+|\s+$/g,Q=/^\s+/,Y=/\s+$/,X=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,J=/\{\n\/\* \[wrapped with (.+)\] \*/,Z=/,? & /,ee=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,te=/\\(\\)?/g,ne=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,re=/\w*$/,oe=/^[-+]0x[0-9a-f]+$/i,ie=/^0b[01]+$/i,ae=/^\[object .+?Constructor\]$/,le=/^0o[0-7]+$/i,ce=/^(?:0|[1-9]\d*)$/,ue=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,se=/($^)/,fe=/['\n\r\u2028\u2029\\]/g,pe="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",de="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",he="[\\ud800-\\udfff]",ve="["+de+"]",ge="["+pe+"]",me="\\d+",ye="[\\u2700-\\u27bf]",be="[a-z\\xdf-\\xf6\\xf8-\\xff]",_e="[^\\ud800-\\udfff"+de+me+"\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",we="\\ud83c[\\udffb-\\udfff]",xe="[^\\ud800-\\udfff]",Se="(?:\\ud83c[\\udde6-\\uddff]){2}",ke="[\\ud800-\\udbff][\\udc00-\\udfff]",Oe="[A-Z\\xc0-\\xd6\\xd8-\\xde]",Ee="(?:"+be+"|"+_e+")",Te="(?:"+Oe+"|"+_e+")",Ce="(?:"+ge+"|"+we+")"+"?",Pe="[\\ufe0e\\ufe0f]?"+Ce+("(?:\\u200d(?:"+[xe,Se,ke].join("|")+")[\\ufe0e\\ufe0f]?"+Ce+")*"),Ie="(?:"+[ye,Se,ke].join("|")+")"+Pe,je="(?:"+[xe+ge+"?",ge,Se,ke,he].join("|")+")",ze=RegExp("['’]","g"),Re=RegExp(ge,"g"),Me=RegExp(we+"(?="+we+")|"+je+Pe,"g"),Ne=RegExp([Oe+"?"+be+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[ve,Oe,"$"].join("|")+")",Te+"+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[ve,Oe+Ee,"$"].join("|")+")",Oe+"?"+Ee+"+(?:['’](?:d|ll|m|re|s|t|ve))?",Oe+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",me,Ie].join("|"),"g"),Ae=RegExp("[\\u200d\\ud800-\\udfff"+pe+"\\ufe0e\\ufe0f]"),Le=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Fe=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],De=-1,He={};He[O]=He[E]=He[T]=He[C]=He[P]=He[I]=He["[object Uint8ClampedArray]"]=He[j]=He[z]=!0,He[c]=He[u]=He[S]=He[s]=He[k]=He[f]=He[p]=He[d]=He[v]=He[g]=He[m]=He[y]=He[b]=He[_]=He[x]=!1;var Ue={};Ue[c]=Ue[u]=Ue[S]=Ue[k]=Ue[s]=Ue[f]=Ue[O]=Ue[E]=Ue[T]=Ue[C]=Ue[P]=Ue[v]=Ue[g]=Ue[m]=Ue[y]=Ue[b]=Ue[_]=Ue[w]=Ue[I]=Ue["[object Uint8ClampedArray]"]=Ue[j]=Ue[z]=!0,Ue[p]=Ue[d]=Ue[x]=!1;var We={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Be=parseFloat,Ve=parseInt,Ge="object"==typeof e&&e&&e.Object===Object&&e,Ke="object"==typeof self&&self&&self.Object===Object&&self,qe=Ge||Ke||Function("return this")(),$e=t&&!t.nodeType&&t,Qe=$e&&"object"==typeof r&&r&&!r.nodeType&&r,Ye=Qe&&Qe.exports===$e,Xe=Ye&&Ge.process,Je=function(){try{var e=Qe&&Qe.require&&Qe.require("util").types;return e||Xe&&Xe.binding&&Xe.binding("util")}catch(e){}}(),Ze=Je&&Je.isArrayBuffer,et=Je&&Je.isDate,tt=Je&&Je.isMap,nt=Je&&Je.isRegExp,rt=Je&&Je.isSet,ot=Je&&Je.isTypedArray;function it(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}function at(e,t,n,r){for(var o=-1,i=null==e?0:e.length;++o-1}function pt(e,t,n){for(var r=-1,o=null==e?0:e.length;++r-1;);return n}function Mt(e,t){for(var n=e.length;n--&&wt(t,e[n],0)>-1;);return n}function Nt(e,t){for(var n=e.length,r=0;n--;)e[n]===t&&++r;return r}var At=Et({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),Lt=Et({"&":"&","<":"<",">":">",'"':""","'":"'"});function Ft(e){return"\\"+We[e]}function Dt(e){return Ae.test(e)}function Ht(e){var t=-1,n=Array(e.size);return e.forEach((function(e,r){n[++t]=[r,e]})),n}function Ut(e,t){return function(n){return e(t(n))}}function Wt(e,t){for(var n=-1,r=e.length,o=0,i=[];++n",""":'"',"'":"'"});var $t=function e(t){var n,r=(t=null==t?qe:$t.defaults(qe.Object(),t,$t.pick(qe,Fe))).Array,o=t.Date,pe=t.Error,de=t.Function,he=t.Math,ve=t.Object,ge=t.RegExp,me=t.String,ye=t.TypeError,be=r.prototype,_e=de.prototype,we=ve.prototype,xe=t["__core-js_shared__"],Se=_e.toString,ke=we.hasOwnProperty,Oe=0,Ee=(n=/[^.]+$/.exec(xe&&xe.keys&&xe.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"",Te=we.toString,Ce=Se.call(ve),Pe=qe._,Ie=ge("^"+Se.call(ke).replace(K,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),je=Ye?t.Buffer:void 0,Me=t.Symbol,Ae=t.Uint8Array,We=je?je.allocUnsafe:void 0,Ge=Ut(ve.getPrototypeOf,ve),Ke=ve.create,$e=we.propertyIsEnumerable,Qe=be.splice,Xe=Me?Me.isConcatSpreadable:void 0,Je=Me?Me.iterator:void 0,yt=Me?Me.toStringTag:void 0,Et=function(){try{var e=ei(ve,"defineProperty");return e({},"",{}),e}catch(e){}}(),Qt=t.clearTimeout!==qe.clearTimeout&&t.clearTimeout,Yt=o&&o.now!==qe.Date.now&&o.now,Xt=t.setTimeout!==qe.setTimeout&&t.setTimeout,Jt=he.ceil,Zt=he.floor,en=ve.getOwnPropertySymbols,tn=je?je.isBuffer:void 0,nn=t.isFinite,rn=be.join,on=Ut(ve.keys,ve),an=he.max,ln=he.min,cn=o.now,un=t.parseInt,sn=he.random,fn=be.reverse,pn=ei(t,"DataView"),dn=ei(t,"Map"),hn=ei(t,"Promise"),vn=ei(t,"Set"),gn=ei(t,"WeakMap"),mn=ei(ve,"create"),yn=gn&&new gn,bn={},_n=Ti(pn),wn=Ti(dn),xn=Ti(hn),Sn=Ti(vn),kn=Ti(gn),On=Me?Me.prototype:void 0,En=On?On.valueOf:void 0,Tn=On?On.toString:void 0;function Cn(e){if(Va(e)&&!Ra(e)&&!(e instanceof zn)){if(e instanceof jn)return e;if(ke.call(e,"__wrapped__"))return Ci(e)}return new jn(e)}var Pn=function(){function e(){}return function(t){if(!Ba(t))return{};if(Ke)return Ke(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();function In(){}function jn(e,t){this.__wrapped__=e,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=void 0}function zn(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Rn(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t=t?e:t)),e}function Yn(e,t,n,r,o,i){var a,l=1&t,u=2&t,p=4&t;if(n&&(a=o?n(e,r,o,i):n(e)),void 0!==a)return a;if(!Ba(e))return e;var x=Ra(e);if(x){if(a=function(e){var t=e.length,n=new e.constructor(t);t&&"string"==typeof e[0]&&ke.call(e,"index")&&(n.index=e.index,n.input=e.input);return n}(e),!l)return yo(e,a)}else{var R=ri(e),M=R==d||R==h;if(La(e))return fo(e,l);if(R==m||R==c||M&&!o){if(a=u||M?{}:ii(e),!l)return u?function(e,t){return bo(e,ni(e),t)}(e,function(e,t){return e&&bo(t,wl(t),e)}(a,e)):function(e,t){return bo(e,ti(e),t)}(e,Kn(a,e))}else{if(!Ue[R])return o?e:{};a=function(e,t,n){var r=e.constructor;switch(t){case S:return po(e);case s:case f:return new r(+e);case k:return function(e,t){var n=t?po(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}(e,n);case O:case E:case T:case C:case P:case I:case"[object Uint8ClampedArray]":case j:case z:return ho(e,n);case v:return new r;case g:case _:return new r(e);case y:return function(e){var t=new e.constructor(e.source,re.exec(e));return t.lastIndex=e.lastIndex,t}(e);case b:return new r;case w:return o=e,En?ve(En.call(o)):{}}var o}(e,R,l)}}i||(i=new Ln);var N=i.get(e);if(N)return N;i.set(e,a),Qa(e)?e.forEach((function(r){a.add(Yn(r,t,n,r,e,i))})):Ga(e)&&e.forEach((function(r,o){a.set(o,Yn(r,t,n,o,e,i))}));var A=x?void 0:(p?u?qo:Ko:u?wl:_l)(e);return lt(A||e,(function(r,o){A&&(r=e[o=r]),Bn(a,o,Yn(r,t,n,o,e,i))})),a}function Xn(e,t,n){var r=n.length;if(null==e)return!r;for(e=ve(e);r--;){var o=n[r],i=t[o],a=e[o];if(void 0===a&&!(o in e)||!i(a))return!1}return!0}function Jn(e,t,n){if("function"!=typeof e)throw new ye(i);return _i((function(){e.apply(void 0,n)}),t)}function Zn(e,t,n,r){var o=-1,i=ft,a=!0,l=e.length,c=[],u=t.length;if(!l)return c;n&&(t=dt(t,It(n))),r?(i=pt,a=!1):t.length>=200&&(i=zt,a=!1,t=new An(t));e:for(;++o-1},Mn.prototype.set=function(e,t){var n=this.__data__,r=Vn(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this},Nn.prototype.clear=function(){this.size=0,this.__data__={hash:new Rn,map:new(dn||Mn),string:new Rn}},Nn.prototype.delete=function(e){var t=Jo(this,e).delete(e);return this.size-=t?1:0,t},Nn.prototype.get=function(e){return Jo(this,e).get(e)},Nn.prototype.has=function(e){return Jo(this,e).has(e)},Nn.prototype.set=function(e,t){var n=Jo(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this},An.prototype.add=An.prototype.push=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this},An.prototype.has=function(e){return this.__data__.has(e)},Ln.prototype.clear=function(){this.__data__=new Mn,this.size=0},Ln.prototype.delete=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n},Ln.prototype.get=function(e){return this.__data__.get(e)},Ln.prototype.has=function(e){return this.__data__.has(e)},Ln.prototype.set=function(e,t){var n=this.__data__;if(n instanceof Mn){var r=n.__data__;if(!dn||r.length<199)return r.push([e,t]),this.size=++n.size,this;n=this.__data__=new Nn(r)}return n.set(e,t),this.size=n.size,this};var er=xo(cr),tr=xo(ur,!0);function nr(e,t){var n=!0;return er(e,(function(e,r,o){return n=!!t(e,r,o)})),n}function rr(e,t,n){for(var r=-1,o=e.length;++r0&&n(l)?t>1?ir(l,t-1,n,r,o):ht(o,l):r||(o[o.length]=l)}return o}var ar=So(),lr=So(!0);function cr(e,t){return e&&ar(e,t,_l)}function ur(e,t){return e&&lr(e,t,_l)}function sr(e,t){return st(t,(function(t){return Ha(e[t])}))}function fr(e,t){for(var n=0,r=(t=lo(t,e)).length;null!=e&&nt}function vr(e,t){return null!=e&&ke.call(e,t)}function gr(e,t){return null!=e&&t in ve(e)}function mr(e,t,n){for(var o=n?pt:ft,i=e[0].length,a=e.length,l=a,c=r(a),u=1/0,s=[];l--;){var f=e[l];l&&t&&(f=dt(f,It(t))),u=ln(f.length,u),c[l]=!n&&(t||i>=120&&f.length>=120)?new An(l&&f):void 0}f=e[0];var p=-1,d=c[0];e:for(;++p=l)return c;var u=n[r];return c*("desc"==u?-1:1)}}return e.index-t.index}(e,t,n)}))}function Rr(e,t,n){for(var r=-1,o=t.length,i={};++r-1;)l!==e&&Qe.call(l,c,1),Qe.call(e,c,1);return e}function Nr(e,t){for(var n=e?t.length:0,r=n-1;n--;){var o=t[n];if(n==r||o!==i){var i=o;li(o)?Qe.call(e,o,1):Zr(e,o)}}return e}function Ar(e,t){return e+Zt(sn()*(t-e+1))}function Lr(e,t){var n="";if(!e||t<1||t>9007199254740991)return n;do{t%2&&(n+=e),(t=Zt(t/2))&&(e+=e)}while(t);return n}function Fr(e,t){return wi(vi(e,t,Kl),e+"")}function Dr(e){return Dn(Pl(e))}function Hr(e,t){var n=Pl(e);return ki(n,Qn(t,0,n.length))}function Ur(e,t,n,r){if(!Ba(e))return e;for(var o=-1,i=(t=lo(t,e)).length,a=i-1,l=e;null!=l&&++oi?0:i+t),(n=n>i?i:n)<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var a=r(i);++o>>1,a=e[i];null!==a&&!Xa(a)&&(n?a<=t:a=200){var u=t?null:Fo(e);if(u)return Bt(u);a=!1,o=zt,c=new An}else c=t?[]:l;e:for(;++r=r?e:Gr(e,t,n)}var so=Qt||function(e){return qe.clearTimeout(e)};function fo(e,t){if(t)return e.slice();var n=e.length,r=We?We(n):new e.constructor(n);return e.copy(r),r}function po(e){var t=new e.constructor(e.byteLength);return new Ae(t).set(new Ae(e)),t}function ho(e,t){var n=t?po(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}function vo(e,t){if(e!==t){var n=void 0!==e,r=null===e,o=e==e,i=Xa(e),a=void 0!==t,l=null===t,c=t==t,u=Xa(t);if(!l&&!u&&!i&&e>t||i&&a&&c&&!l&&!u||r&&a&&c||!n&&c||!o)return 1;if(!r&&!i&&!u&&e1?n[o-1]:void 0,a=o>2?n[2]:void 0;for(i=e.length>3&&"function"==typeof i?(o--,i):void 0,a&&ci(n[0],n[1],a)&&(i=o<3?void 0:i,o=1),t=ve(t);++r-1?o[i?t[a]:a]:void 0}}function Co(e){return Go((function(t){var n=t.length,r=n,o=jn.prototype.thru;for(e&&t.reverse();r--;){var a=t[r];if("function"!=typeof a)throw new ye(i);if(o&&!l&&"wrapper"==Qo(a))var l=new jn([],!0)}for(r=l?r:n;++r1&&b.reverse(),f&&ul))return!1;var u=i.get(e),s=i.get(t);if(u&&s)return u==t&&s==e;var f=-1,p=!0,d=2&n?new An:void 0;for(i.set(e,t),i.set(t,e);++f-1&&e%1==0&&e1?"& ":"")+t[r],t=t.join(n>2?", ":" "),e.replace(X,"{\n/* [wrapped with "+t+"] */\n")}(r,function(e,t){return lt(l,(function(n){var r="_."+n[0];t&n[1]&&!ft(e,r)&&e.push(r)})),e.sort()}(function(e){var t=e.match(J);return t?t[1].split(Z):[]}(r),n)))}function Si(e){var t=0,n=0;return function(){var r=cn(),o=16-(r-n);if(n=r,o>0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}function ki(e,t){var n=-1,r=e.length,o=r-1;for(t=void 0===t?r:t;++n1?e[t-1]:void 0;return n="function"==typeof n?(e.pop(),n):void 0,$i(e,n)}));function ta(e){var t=Cn(e);return t.__chain__=!0,t}function na(e,t){return t(e)}var ra=Go((function(e){var t=e.length,n=t?e[0]:0,r=this.__wrapped__,o=function(t){return $n(t,e)};return!(t>1||this.__actions__.length)&&r instanceof zn&&li(n)?((r=r.slice(n,+n+(t?1:0))).__actions__.push({func:na,args:[o],thisArg:void 0}),new jn(r,this.__chain__).thru((function(e){return t&&!e.length&&e.push(void 0),e}))):this.thru(o)}));var oa=_o((function(e,t,n){ke.call(e,n)?++e[n]:qn(e,n,1)}));var ia=To(zi),aa=To(Ri);function la(e,t){return(Ra(e)?lt:er)(e,Xo(t,3))}function ca(e,t){return(Ra(e)?ct:tr)(e,Xo(t,3))}var ua=_o((function(e,t,n){ke.call(e,n)?e[n].push(t):qn(e,n,[t])}));var sa=Fr((function(e,t,n){var o=-1,i="function"==typeof t,a=Na(e)?r(e.length):[];return er(e,(function(e){a[++o]=i?it(t,e,n):yr(e,t,n)})),a})),fa=_o((function(e,t,n){qn(e,n,t)}));function pa(e,t){return(Ra(e)?dt:Tr)(e,Xo(t,3))}var da=_o((function(e,t,n){e[n?0:1].push(t)}),(function(){return[[],[]]}));var ha=Fr((function(e,t){if(null==e)return[];var n=t.length;return n>1&&ci(e,t[0],t[1])?t=[]:n>2&&ci(t[0],t[1],t[2])&&(t=[t[0]]),zr(e,ir(t,1),[])})),va=Yt||function(){return qe.Date.now()};function ga(e,t,n){return t=n?void 0:t,Ho(e,128,void 0,void 0,void 0,void 0,t=e&&null==t?e.length:t)}function ma(e,t){var n;if("function"!=typeof t)throw new ye(i);return e=rl(e),function(){return--e>0&&(n=t.apply(this,arguments)),e<=1&&(t=void 0),n}}var ya=Fr((function(e,t,n){var r=1;if(n.length){var o=Wt(n,Yo(ya));r|=32}return Ho(e,r,t,n,o)})),ba=Fr((function(e,t,n){var r=3;if(n.length){var o=Wt(n,Yo(ba));r|=32}return Ho(t,r,e,n,o)}));function _a(e,t,n){var r,o,a,l,c,u,s=0,f=!1,p=!1,d=!0;if("function"!=typeof e)throw new ye(i);function h(t){var n=r,i=o;return r=o=void 0,s=t,l=e.apply(i,n)}function v(e){return s=e,c=_i(m,t),f?h(e):l}function g(e){var n=e-u;return void 0===u||n>=t||n<0||p&&e-s>=a}function m(){var e=va();if(g(e))return y(e);c=_i(m,function(e){var n=t-(e-u);return p?ln(n,a-(e-s)):n}(e))}function y(e){return c=void 0,d&&r?h(e):(r=o=void 0,l)}function b(){var e=va(),n=g(e);if(r=arguments,o=this,u=e,n){if(void 0===c)return v(u);if(p)return so(c),c=_i(m,t),h(u)}return void 0===c&&(c=_i(m,t)),l}return t=il(t)||0,Ba(n)&&(f=!!n.leading,a=(p="maxWait"in n)?an(il(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),b.cancel=function(){void 0!==c&&so(c),s=0,r=u=o=c=void 0},b.flush=function(){return void 0===c?l:y(va())},b}var wa=Fr((function(e,t){return Jn(e,1,t)})),xa=Fr((function(e,t,n){return Jn(e,il(t)||0,n)}));function Sa(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new ye(i);var n=function(){var r=arguments,o=t?t.apply(this,r):r[0],i=n.cache;if(i.has(o))return i.get(o);var a=e.apply(this,r);return n.cache=i.set(o,a)||i,a};return n.cache=new(Sa.Cache||Nn),n}function ka(e){if("function"!=typeof e)throw new ye(i);return function(){var t=arguments;switch(t.length){case 0:return!e.call(this);case 1:return!e.call(this,t[0]);case 2:return!e.call(this,t[0],t[1]);case 3:return!e.call(this,t[0],t[1],t[2])}return!e.apply(this,t)}}Sa.Cache=Nn;var Oa=co((function(e,t){var n=(t=1==t.length&&Ra(t[0])?dt(t[0],It(Xo())):dt(ir(t,1),It(Xo()))).length;return Fr((function(r){for(var o=-1,i=ln(r.length,n);++o=t})),za=br(function(){return arguments}())?br:function(e){return Va(e)&&ke.call(e,"callee")&&!$e.call(e,"callee")},Ra=r.isArray,Ma=Ze?It(Ze):function(e){return Va(e)&&dr(e)==S};function Na(e){return null!=e&&Wa(e.length)&&!Ha(e)}function Aa(e){return Va(e)&&Na(e)}var La=tn||ic,Fa=et?It(et):function(e){return Va(e)&&dr(e)==f};function Da(e){if(!Va(e))return!1;var t=dr(e);return t==p||"[object DOMException]"==t||"string"==typeof e.message&&"string"==typeof e.name&&!qa(e)}function Ha(e){if(!Ba(e))return!1;var t=dr(e);return t==d||t==h||"[object AsyncFunction]"==t||"[object Proxy]"==t}function Ua(e){return"number"==typeof e&&e==rl(e)}function Wa(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}function Ba(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}function Va(e){return null!=e&&"object"==typeof e}var Ga=tt?It(tt):function(e){return Va(e)&&ri(e)==v};function Ka(e){return"number"==typeof e||Va(e)&&dr(e)==g}function qa(e){if(!Va(e)||dr(e)!=m)return!1;var t=Ge(e);if(null===t)return!0;var n=ke.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&Se.call(n)==Ce}var $a=nt?It(nt):function(e){return Va(e)&&dr(e)==y};var Qa=rt?It(rt):function(e){return Va(e)&&ri(e)==b};function Ya(e){return"string"==typeof e||!Ra(e)&&Va(e)&&dr(e)==_}function Xa(e){return"symbol"==typeof e||Va(e)&&dr(e)==w}var Ja=ot?It(ot):function(e){return Va(e)&&Wa(e.length)&&!!He[dr(e)]};var Za=No(Er),el=No((function(e,t){return e<=t}));function tl(e){if(!e)return[];if(Na(e))return Ya(e)?Kt(e):yo(e);if(Je&&e[Je])return function(e){for(var t,n=[];!(t=e.next()).done;)n.push(t.value);return n}(e[Je]());var t=ri(e);return(t==v?Ht:t==b?Bt:Pl)(e)}function nl(e){return e?(e=il(e))===1/0||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}function rl(e){var t=nl(e),n=t%1;return t==t?n?t-n:t:0}function ol(e){return e?Qn(rl(e),0,4294967295):0}function il(e){if("number"==typeof e)return e;if(Xa(e))return NaN;if(Ba(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=Ba(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace($,"");var n=ie.test(e);return n||le.test(e)?Ve(e.slice(2),n?2:8):oe.test(e)?NaN:+e}function al(e){return bo(e,wl(e))}function ll(e){return null==e?"":Xr(e)}var cl=wo((function(e,t){if(pi(t)||Na(t))bo(t,_l(t),e);else for(var n in t)ke.call(t,n)&&Bn(e,n,t[n])})),ul=wo((function(e,t){bo(t,wl(t),e)})),sl=wo((function(e,t,n,r){bo(t,wl(t),e,r)})),fl=wo((function(e,t,n,r){bo(t,_l(t),e,r)})),pl=Go($n);var dl=Fr((function(e,t){e=ve(e);var n=-1,r=t.length,o=r>2?t[2]:void 0;for(o&&ci(t[0],t[1],o)&&(r=1);++n1),t})),bo(e,qo(e),n),r&&(n=Yn(n,7,Bo));for(var o=t.length;o--;)Zr(n,t[o]);return n}));var Ol=Go((function(e,t){return null==e?{}:function(e,t){return Rr(e,t,(function(t,n){return gl(e,n)}))}(e,t)}));function El(e,t){if(null==e)return{};var n=dt(qo(e),(function(e){return[e]}));return t=Xo(t),Rr(e,n,(function(e,n){return t(e,n[0])}))}var Tl=Do(_l),Cl=Do(wl);function Pl(e){return null==e?[]:jt(e,_l(e))}var Il=Oo((function(e,t,n){return t=t.toLowerCase(),e+(n?jl(t):t)}));function jl(e){return Dl(ll(e).toLowerCase())}function zl(e){return(e=ll(e))&&e.replace(ue,At).replace(Re,"")}var Rl=Oo((function(e,t,n){return e+(n?"-":"")+t.toLowerCase()})),Ml=Oo((function(e,t,n){return e+(n?" ":"")+t.toLowerCase()})),Nl=ko("toLowerCase");var Al=Oo((function(e,t,n){return e+(n?"_":"")+t.toLowerCase()}));var Ll=Oo((function(e,t,n){return e+(n?" ":"")+Dl(t)}));var Fl=Oo((function(e,t,n){return e+(n?" ":"")+t.toUpperCase()})),Dl=ko("toUpperCase");function Hl(e,t,n){return e=ll(e),void 0===(t=n?void 0:t)?function(e){return Le.test(e)}(e)?function(e){return e.match(Ne)||[]}(e):function(e){return e.match(ee)||[]}(e):e.match(t)||[]}var Ul=Fr((function(e,t){try{return it(e,void 0,t)}catch(e){return Da(e)?e:new pe(e)}})),Wl=Go((function(e,t){return lt(t,(function(t){t=Ei(t),qn(e,t,ya(e[t],e))})),e}));function Bl(e){return function(){return e}}var Vl=Co(),Gl=Co(!0);function Kl(e){return e}function ql(e){return Sr("function"==typeof e?e:Yn(e,1))}var $l=Fr((function(e,t){return function(n){return yr(n,e,t)}})),Ql=Fr((function(e,t){return function(n){return yr(e,n,t)}}));function Yl(e,t,n){var r=_l(t),o=sr(t,r);null!=n||Ba(t)&&(o.length||!r.length)||(n=t,t=e,e=this,o=sr(t,_l(t)));var i=!(Ba(n)&&"chain"in n&&!n.chain),a=Ha(e);return lt(o,(function(n){var r=t[n];e[n]=r,a&&(e.prototype[n]=function(){var t=this.__chain__;if(i||t){var n=e(this.__wrapped__),o=n.__actions__=yo(this.__actions__);return o.push({func:r,args:arguments,thisArg:e}),n.__chain__=t,n}return r.apply(e,ht([this.value()],arguments))})})),e}function Xl(){}var Jl=zo(dt),Zl=zo(ut),ec=zo(mt);function tc(e){return ui(e)?Ot(Ei(e)):function(e){return function(t){return fr(t,e)}}(e)}var nc=Mo(),rc=Mo(!0);function oc(){return[]}function ic(){return!1}var ac=jo((function(e,t){return e+t}),0),lc=Lo("ceil"),cc=jo((function(e,t){return e/t}),1),uc=Lo("floor");var sc,fc=jo((function(e,t){return e*t}),1),pc=Lo("round"),dc=jo((function(e,t){return e-t}),0);return Cn.after=function(e,t){if("function"!=typeof t)throw new ye(i);return e=rl(e),function(){if(--e<1)return t.apply(this,arguments)}},Cn.ary=ga,Cn.assign=cl,Cn.assignIn=ul,Cn.assignInWith=sl,Cn.assignWith=fl,Cn.at=pl,Cn.before=ma,Cn.bind=ya,Cn.bindAll=Wl,Cn.bindKey=ba,Cn.castArray=function(){if(!arguments.length)return[];var e=arguments[0];return Ra(e)?e:[e]},Cn.chain=ta,Cn.chunk=function(e,t,n){t=(n?ci(e,t,n):void 0===t)?1:an(rl(t),0);var o=null==e?0:e.length;if(!o||t<1)return[];for(var i=0,a=0,l=r(Jt(o/t));io?0:o+n),(r=void 0===r||r>o?o:rl(r))<0&&(r+=o),r=n>r?0:ol(r);n>>0)?(e=ll(e))&&("string"==typeof t||null!=t&&!$a(t))&&!(t=Xr(t))&&Dt(e)?uo(Kt(e),0,n):e.split(t,n):[]},Cn.spread=function(e,t){if("function"!=typeof e)throw new ye(i);return t=null==t?0:an(rl(t),0),Fr((function(n){var r=n[t],o=uo(n,0,t);return r&&ht(o,r),it(e,this,o)}))},Cn.tail=function(e){var t=null==e?0:e.length;return t?Gr(e,1,t):[]},Cn.take=function(e,t,n){return e&&e.length?Gr(e,0,(t=n||void 0===t?1:rl(t))<0?0:t):[]},Cn.takeRight=function(e,t,n){var r=null==e?0:e.length;return r?Gr(e,(t=r-(t=n||void 0===t?1:rl(t)))<0?0:t,r):[]},Cn.takeRightWhile=function(e,t){return e&&e.length?to(e,Xo(t,3),!1,!0):[]},Cn.takeWhile=function(e,t){return e&&e.length?to(e,Xo(t,3)):[]},Cn.tap=function(e,t){return t(e),e},Cn.throttle=function(e,t,n){var r=!0,o=!0;if("function"!=typeof e)throw new ye(i);return Ba(n)&&(r="leading"in n?!!n.leading:r,o="trailing"in n?!!n.trailing:o),_a(e,t,{leading:r,maxWait:t,trailing:o})},Cn.thru=na,Cn.toArray=tl,Cn.toPairs=Tl,Cn.toPairsIn=Cl,Cn.toPath=function(e){return Ra(e)?dt(e,Ei):Xa(e)?[e]:yo(Oi(ll(e)))},Cn.toPlainObject=al,Cn.transform=function(e,t,n){var r=Ra(e),o=r||La(e)||Ja(e);if(t=Xo(t,4),null==n){var i=e&&e.constructor;n=o?r?new i:[]:Ba(e)&&Ha(i)?Pn(Ge(e)):{}}return(o?lt:cr)(e,(function(e,r,o){return t(n,e,r,o)})),n},Cn.unary=function(e){return ga(e,1)},Cn.union=Vi,Cn.unionBy=Gi,Cn.unionWith=Ki,Cn.uniq=function(e){return e&&e.length?Jr(e):[]},Cn.uniqBy=function(e,t){return e&&e.length?Jr(e,Xo(t,2)):[]},Cn.uniqWith=function(e,t){return t="function"==typeof t?t:void 0,e&&e.length?Jr(e,void 0,t):[]},Cn.unset=function(e,t){return null==e||Zr(e,t)},Cn.unzip=qi,Cn.unzipWith=$i,Cn.update=function(e,t,n){return null==e?e:eo(e,t,ao(n))},Cn.updateWith=function(e,t,n,r){return r="function"==typeof r?r:void 0,null==e?e:eo(e,t,ao(n),r)},Cn.values=Pl,Cn.valuesIn=function(e){return null==e?[]:jt(e,wl(e))},Cn.without=Qi,Cn.words=Hl,Cn.wrap=function(e,t){return Ea(ao(t),e)},Cn.xor=Yi,Cn.xorBy=Xi,Cn.xorWith=Ji,Cn.zip=Zi,Cn.zipObject=function(e,t){return oo(e||[],t||[],Bn)},Cn.zipObjectDeep=function(e,t){return oo(e||[],t||[],Ur)},Cn.zipWith=ea,Cn.entries=Tl,Cn.entriesIn=Cl,Cn.extend=ul,Cn.extendWith=sl,Yl(Cn,Cn),Cn.add=ac,Cn.attempt=Ul,Cn.camelCase=Il,Cn.capitalize=jl,Cn.ceil=lc,Cn.clamp=function(e,t,n){return void 0===n&&(n=t,t=void 0),void 0!==n&&(n=(n=il(n))==n?n:0),void 0!==t&&(t=(t=il(t))==t?t:0),Qn(il(e),t,n)},Cn.clone=function(e){return Yn(e,4)},Cn.cloneDeep=function(e){return Yn(e,5)},Cn.cloneDeepWith=function(e,t){return Yn(e,5,t="function"==typeof t?t:void 0)},Cn.cloneWith=function(e,t){return Yn(e,4,t="function"==typeof t?t:void 0)},Cn.conformsTo=function(e,t){return null==t||Xn(e,t,_l(t))},Cn.deburr=zl,Cn.defaultTo=function(e,t){return null==e||e!=e?t:e},Cn.divide=cc,Cn.endsWith=function(e,t,n){e=ll(e),t=Xr(t);var r=e.length,o=n=void 0===n?r:Qn(rl(n),0,r);return(n-=t.length)>=0&&e.slice(n,o)==t},Cn.eq=Pa,Cn.escape=function(e){return(e=ll(e))&&D.test(e)?e.replace(L,Lt):e},Cn.escapeRegExp=function(e){return(e=ll(e))&&q.test(e)?e.replace(K,"\\$&"):e},Cn.every=function(e,t,n){var r=Ra(e)?ut:nr;return n&&ci(e,t,n)&&(t=void 0),r(e,Xo(t,3))},Cn.find=ia,Cn.findIndex=zi,Cn.findKey=function(e,t){return bt(e,Xo(t,3),cr)},Cn.findLast=aa,Cn.findLastIndex=Ri,Cn.findLastKey=function(e,t){return bt(e,Xo(t,3),ur)},Cn.floor=uc,Cn.forEach=la,Cn.forEachRight=ca,Cn.forIn=function(e,t){return null==e?e:ar(e,Xo(t,3),wl)},Cn.forInRight=function(e,t){return null==e?e:lr(e,Xo(t,3),wl)},Cn.forOwn=function(e,t){return e&&cr(e,Xo(t,3))},Cn.forOwnRight=function(e,t){return e&&ur(e,Xo(t,3))},Cn.get=vl,Cn.gt=Ia,Cn.gte=ja,Cn.has=function(e,t){return null!=e&&oi(e,t,vr)},Cn.hasIn=gl,Cn.head=Ni,Cn.identity=Kl,Cn.includes=function(e,t,n,r){e=Na(e)?e:Pl(e),n=n&&!r?rl(n):0;var o=e.length;return n<0&&(n=an(o+n,0)),Ya(e)?n<=o&&e.indexOf(t,n)>-1:!!o&&wt(e,t,n)>-1},Cn.indexOf=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var o=null==n?0:rl(n);return o<0&&(o=an(r+o,0)),wt(e,t,o)},Cn.inRange=function(e,t,n){return t=nl(t),void 0===n?(n=t,t=0):n=nl(n),function(e,t,n){return e>=ln(t,n)&&e=-9007199254740991&&e<=9007199254740991},Cn.isSet=Qa,Cn.isString=Ya,Cn.isSymbol=Xa,Cn.isTypedArray=Ja,Cn.isUndefined=function(e){return void 0===e},Cn.isWeakMap=function(e){return Va(e)&&ri(e)==x},Cn.isWeakSet=function(e){return Va(e)&&"[object WeakSet]"==dr(e)},Cn.join=function(e,t){return null==e?"":rn.call(e,t)},Cn.kebabCase=Rl,Cn.last=Di,Cn.lastIndexOf=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var o=r;return void 0!==n&&(o=(o=rl(n))<0?an(r+o,0):ln(o,r-1)),t==t?function(e,t,n){for(var r=n+1;r--;)if(e[r]===t)return r;return r}(e,t,o):_t(e,St,o,!0)},Cn.lowerCase=Ml,Cn.lowerFirst=Nl,Cn.lt=Za,Cn.lte=el,Cn.max=function(e){return e&&e.length?rr(e,Kl,hr):void 0},Cn.maxBy=function(e,t){return e&&e.length?rr(e,Xo(t,2),hr):void 0},Cn.mean=function(e){return kt(e,Kl)},Cn.meanBy=function(e,t){return kt(e,Xo(t,2))},Cn.min=function(e){return e&&e.length?rr(e,Kl,Er):void 0},Cn.minBy=function(e,t){return e&&e.length?rr(e,Xo(t,2),Er):void 0},Cn.stubArray=oc,Cn.stubFalse=ic,Cn.stubObject=function(){return{}},Cn.stubString=function(){return""},Cn.stubTrue=function(){return!0},Cn.multiply=fc,Cn.nth=function(e,t){return e&&e.length?jr(e,rl(t)):void 0},Cn.noConflict=function(){return qe._===this&&(qe._=Pe),this},Cn.noop=Xl,Cn.now=va,Cn.pad=function(e,t,n){e=ll(e);var r=(t=rl(t))?Gt(e):0;if(!t||r>=t)return e;var o=(t-r)/2;return Ro(Zt(o),n)+e+Ro(Jt(o),n)},Cn.padEnd=function(e,t,n){e=ll(e);var r=(t=rl(t))?Gt(e):0;return t&&rt){var r=e;e=t,t=r}if(n||e%1||t%1){var o=sn();return ln(e+o*(t-e+Be("1e-"+((o+"").length-1))),t)}return Ar(e,t)},Cn.reduce=function(e,t,n){var r=Ra(e)?vt:Tt,o=arguments.length<3;return r(e,Xo(t,4),n,o,er)},Cn.reduceRight=function(e,t,n){var r=Ra(e)?gt:Tt,o=arguments.length<3;return r(e,Xo(t,4),n,o,tr)},Cn.repeat=function(e,t,n){return t=(n?ci(e,t,n):void 0===t)?1:rl(t),Lr(ll(e),t)},Cn.replace=function(){var e=arguments,t=ll(e[0]);return e.length<3?t:t.replace(e[1],e[2])},Cn.result=function(e,t,n){var r=-1,o=(t=lo(t,e)).length;for(o||(o=1,e=void 0);++r9007199254740991)return[];var n=4294967295,r=ln(e,4294967295);e-=4294967295;for(var o=Pt(r,t=Xo(t));++n=i)return e;var l=n-Gt(r);if(l<1)return r;var c=a?uo(a,0,l).join(""):e.slice(0,l);if(void 0===o)return c+r;if(a&&(l+=c.length-l),$a(o)){if(e.slice(l).search(o)){var u,s=c;for(o.global||(o=ge(o.source,ll(re.exec(o))+"g")),o.lastIndex=0;u=o.exec(s);)var f=u.index;c=c.slice(0,void 0===f?l:f)}}else if(e.indexOf(Xr(o),l)!=l){var p=c.lastIndexOf(o);p>-1&&(c=c.slice(0,p))}return c+r},Cn.unescape=function(e){return(e=ll(e))&&F.test(e)?e.replace(A,qt):e},Cn.uniqueId=function(e){var t=++Oe;return ll(e)+t},Cn.upperCase=Fl,Cn.upperFirst=Dl,Cn.each=la,Cn.eachRight=ca,Cn.first=Ni,Yl(Cn,(sc={},cr(Cn,(function(e,t){ke.call(Cn.prototype,t)||(sc[t]=e)})),sc),{chain:!1}),Cn.VERSION="4.17.19",lt(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(e){Cn[e].placeholder=Cn})),lt(["drop","take"],(function(e,t){zn.prototype[e]=function(n){n=void 0===n?1:an(rl(n),0);var r=this.__filtered__&&!t?new zn(this):this.clone();return r.__filtered__?r.__takeCount__=ln(n,r.__takeCount__):r.__views__.push({size:ln(n,4294967295),type:e+(r.__dir__<0?"Right":"")}),r},zn.prototype[e+"Right"]=function(t){return this.reverse()[e](t).reverse()}})),lt(["filter","map","takeWhile"],(function(e,t){var n=t+1,r=1==n||3==n;zn.prototype[e]=function(e){var t=this.clone();return t.__iteratees__.push({iteratee:Xo(e,3),type:n}),t.__filtered__=t.__filtered__||r,t}})),lt(["head","last"],(function(e,t){var n="take"+(t?"Right":"");zn.prototype[e]=function(){return this[n](1).value()[0]}})),lt(["initial","tail"],(function(e,t){var n="drop"+(t?"":"Right");zn.prototype[e]=function(){return this.__filtered__?new zn(this):this[n](1)}})),zn.prototype.compact=function(){return this.filter(Kl)},zn.prototype.find=function(e){return this.filter(e).head()},zn.prototype.findLast=function(e){return this.reverse().find(e)},zn.prototype.invokeMap=Fr((function(e,t){return"function"==typeof e?new zn(this):this.map((function(n){return yr(n,e,t)}))})),zn.prototype.reject=function(e){return this.filter(ka(Xo(e)))},zn.prototype.slice=function(e,t){e=rl(e);var n=this;return n.__filtered__&&(e>0||t<0)?new zn(n):(e<0?n=n.takeRight(-e):e&&(n=n.drop(e)),void 0!==t&&(n=(t=rl(t))<0?n.dropRight(-t):n.take(t-e)),n)},zn.prototype.takeRightWhile=function(e){return this.reverse().takeWhile(e).reverse()},zn.prototype.toArray=function(){return this.take(4294967295)},cr(zn.prototype,(function(e,t){var n=/^(?:filter|find|map|reject)|While$/.test(t),r=/^(?:head|last)$/.test(t),o=Cn[r?"take"+("last"==t?"Right":""):t],i=r||/^find/.test(t);o&&(Cn.prototype[t]=function(){var t=this.__wrapped__,a=r?[1]:arguments,l=t instanceof zn,c=a[0],u=l||Ra(t),s=function(e){var t=o.apply(Cn,ht([e],a));return r&&f?t[0]:t};u&&n&&"function"==typeof c&&1!=c.length&&(l=u=!1);var f=this.__chain__,p=!!this.__actions__.length,d=i&&!f,h=l&&!p;if(!i&&u){t=h?t:new zn(this);var v=e.apply(t,a);return v.__actions__.push({func:na,args:[s],thisArg:void 0}),new jn(v,f)}return d&&h?e.apply(this,a):(v=this.thru(s),d?r?v.value()[0]:v.value():v)})})),lt(["pop","push","shift","sort","splice","unshift"],(function(e){var t=be[e],n=/^(?:push|sort|unshift)$/.test(e)?"tap":"thru",r=/^(?:pop|shift)$/.test(e);Cn.prototype[e]=function(){var e=arguments;if(r&&!this.__chain__){var o=this.value();return t.apply(Ra(o)?o:[],e)}return this[n]((function(n){return t.apply(Ra(n)?n:[],e)}))}})),cr(zn.prototype,(function(e,t){var n=Cn[t];if(n){var r=n.name+"";ke.call(bn,r)||(bn[r]=[]),bn[r].push({name:t,func:n})}})),bn[Po(void 0,2).name]=[{name:"wrapper",func:void 0}],zn.prototype.clone=function(){var e=new zn(this.__wrapped__);return e.__actions__=yo(this.__actions__),e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=yo(this.__iteratees__),e.__takeCount__=this.__takeCount__,e.__views__=yo(this.__views__),e},zn.prototype.reverse=function(){if(this.__filtered__){var e=new zn(this);e.__dir__=-1,e.__filtered__=!0}else(e=this.clone()).__dir__*=-1;return e},zn.prototype.value=function(){var e=this.__wrapped__.value(),t=this.__dir__,n=Ra(e),r=t<0,o=n?e.length:0,i=function(e,t,n){var r=-1,o=n.length;for(;++r=this.__values__.length;return{done:e,value:e?void 0:this.__values__[this.__index__++]}},Cn.prototype.plant=function(e){for(var t,n=this;n instanceof In;){var r=Ci(n);r.__index__=0,r.__values__=void 0,t?o.__wrapped__=r:t=r;var o=r;n=n.__wrapped__}return o.__wrapped__=e,t},Cn.prototype.reverse=function(){var e=this.__wrapped__;if(e instanceof zn){var t=e;return this.__actions__.length&&(t=new zn(this)),(t=t.reverse()).__actions__.push({func:na,args:[Bi],thisArg:void 0}),new jn(t,this.__chain__)}return this.thru(Bi)},Cn.prototype.toJSON=Cn.prototype.valueOf=Cn.prototype.value=function(){return no(this.__wrapped__,this.__actions__)},Cn.prototype.first=Cn.prototype.head,Je&&(Cn.prototype[Je]=function(){return this}),Cn}();qe._=$t,void 0===(o=function(){return $t}.call(t,n,t,r))||(r.exports=o)}).call(this)}).call(this,n(108),n(243)(e))},function(e,t,n){var r=n(26),o=n(335);"string"==typeof(o=o.__esModule?o.default:o)&&(o=[[e.i,o,""]]);var i={insert:"head",singleton:!1};r(o,i);e.exports=o.locals||{}},function(e,t,n){var r=n(26),o=n(376);"string"==typeof(o=o.__esModule?o.default:o)&&(o=[[e.i,o,""]]);var i={insert:"head",singleton:!1};r(o,i);e.exports=o.locals||{}},function(e,t,n){var r=n(173),o=n(132);e.exports=Object.keys||function(e){return r(e,o)}},function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){"use strict";var r=n(31);e.exports=function(e,t){return!!e&&r((function(){t?e.call(null,(function(){}),1):e.call(null)}))}},function(e,t,n){"use strict";var r=n(27),o=n(54),i=n(53),a=n(113),l=n(138),c=n(139),u=Math.max,s=Math.min,f=Math.floor,p=/\$([$&`']|\d\d?|<[^>]*>)/g,d=/\$([$&`']|\d\d?)/g;n(140)("replace",2,(function(e,t,n,h){return[function(r,o){var i=e(this),a=null==r?void 0:r[t];return void 0!==a?a.call(r,i,o):n.call(String(i),r,o)},function(e,t){var o=h(n,e,this,t);if(o.done)return o.value;var f=r(e),p=String(this),d="function"==typeof t;d||(t=String(t));var g=f.global;if(g){var m=f.unicode;f.lastIndex=0}for(var y=[];;){var b=c(f,p);if(null===b)break;if(y.push(b),!g)break;""===String(b[0])&&(f.lastIndex=l(p,i(f.lastIndex),m))}for(var _,w="",x=0,S=0;S=x&&(w+=p.slice(x,O)+I,x=O+k.length)}return w+p.slice(x)}];function v(e,t,r,i,a,l){var c=r+e.length,u=i.length,s=d;return void 0!==a&&(a=o(a),s=p),n.call(l,s,(function(n,o){var l;switch(o.charAt(0)){case"$":return"$";case"&":return e;case"`":return t.slice(0,r);case"'":return t.slice(c);case"<":l=a[o.slice(1,-1)];break;default:var s=+o;if(0===s)return n;if(s>u){var p=f(s/10);return 0===p?n:p<=u?void 0===i[p-1]?o.charAt(1):i[p-1]+o.charAt(1):n}l=i[s-1]}return void 0===l?"":l}))}}))},function(e,t,n){var r=n(63),o=n(121);e.exports=n(57)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(202),o=n(148);e.exports=function(e){return r(o(e))}},function(e,t,n){(function(t){function n(e){try{if(!t.localStorage)return!1}catch(e){return!1}var n=t.localStorage[e];return null!=n&&"true"===String(n).toLowerCase()}e.exports=function(e,t){if(n("noDeprecation"))return e;var r=!1;return function(){if(!r){if(n("throwDeprecation"))throw new Error(t);n("traceDeprecation")?console.trace(t):console.warn(t),r=!0}return e.apply(this,arguments)}}}).call(this,n(108))},function(e,t,n){var r=n(10);r(r.S+r.F*!n(30),"Object",{defineProperties:n(172)})},function(e,t){var n=e.exports={version:"2.6.11"};"number"==typeof __e&&(__e=n)},function(e,t,n){var r=n(81);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,o){return e.call(t,n,r,o)}}return function(){return e.apply(t,arguments)}}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t,n){var r=n(10),o=n(249),i=n(60),a=n(94),l=n(174);r(r.S,"Object",{getOwnPropertyDescriptors:function(e){for(var t,n,r=i(e),c=a.f,u=o(r),s={},f=0;u.length>f;)void 0!==(n=c(r,t=u[f++]))&&l(s,t,n);return s}})},function(e,t,n){var r=n(27),o=n(172),i=n(132),a=n(131)("IE_PROTO"),l=function(){},c=function(){var e,t=n(171)("iframe"),r=i.length;for(t.style.display="none",n(251).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自动加载框

+ +

Net支持发起请求开始时显示加载框, 请求结束时隐藏加载框(无论成败)

+

自动显示

+
scopeDialog {
+    tvFragment.text = Post<String>("dialog") {
+        param("username", "用户名") // 请求参数
+        param("pwd", "123456")
+    }.await()
+}
+
+


+

默认是原生加载框(MaterialDesign Dialog), 可自定义

+

+

单例自定义

+

指定当前请求加载框

+
val dialog = BubbleDialog(requireActivity(), "加载中")
+
+scopeDialog(dialog) {
+    binding.tvFragment.text = Post<String>("dialog") {
+        param("username", "用户名")
+        param("pwd", "123456")
+    }.await()
+}
+
+

+
+

菊花加载对话框

+

示例使用的iOS风格对话框: BubbleDialog

+
+

全局自定义

+

初始化时指定加载对话框构造器NetDialogFactory

+
NetConfig.initialize(Api.HOST, this) {
+        setDialogFactory {
+            ProgressDialog(it).apply {
+                setMessage("我是全局自定义的加载对话框...")
+            }
+        }
+}
+
+

如仅修改加载对话框文本, 在项目values目录的strings.xml添加以下

+
<!--对话框-->
+<string name="net_dialog_msg">加载中</string>
+
+
+

自定义的加载框不是Dialog

+

由于scopeDialog只能指定Dialog类型, 因此只能手动实现Dialog接口

+

仅要求复写 DialogCoroutineScope 内调用的Dialog方法

+
+

生命周期

+

使用scopeDialog发起请求后, 分为三个生命周期

+ + + + + + + + + + + + + + + + + + + + + +
加载框状态作用域
显示执行scopeDialog时显示加载框
隐藏作用域内任务结束时隐藏加载框
手动取消取消作用域内所有网络请求
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/auto-pull.html b/auto-pull.html new file mode 100644 index 000000000..bfdc0ac0d --- /dev/null +++ b/auto-pull.html @@ -0,0 +1,1271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 自动分页加载 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自动分页加载

+ +

首先请阅读上章节 自动下拉刷新, 已提及内容不再重复

+

自动分页

+

提供addData()来简化分页, 开发者可以借鉴实现

+
page.onRefresh {
+    scope {
+        val data = Get<ListModel>("list") {
+            param("page", index)
+        }.await().data
+        addData(data.list) {
+            index < data.total
+        }
+    }
+}.autoRefresh()
+
+

索引自增

+

index 每次上拉加载自动++1, 刷新列表重置为PageRefreshLayout.startIndex

+

有更多页

+

根据hasMore返回结果是否关闭上拉加载, isEmpty决定是否显示空数据缺省页

+
fun addData(
+    data: List<Any?>?,
+    adapter: BindingAdapter? = null,
+    isEmpty: () -> Boolean = { data.isNullOrEmpty() },
+    hasMore: BindingAdapter.() -> Boolean = { true }
+)
+
+


+1. PageRefreshLayout 下拉刷新/上拉加载

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/auto-refresh.html b/auto-refresh.html new file mode 100644 index 000000000..5b9d815d4 --- /dev/null +++ b/auto-refresh.html @@ -0,0 +1,1320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 自动下拉刷新 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自动下拉刷新

+ +
+

模块化依赖

+

如果自己处理下拉刷新可跳过本章, Net可以仅仅作为简单的网络框架存在

+
+


+Net可依赖三方库 BRV 实现自动处理下拉刷新

+

+
implementation 'com.github.liangjingkanji:BRV:+' // 使用固定版本号替换+符号
+
+

PageRefreshLayout

+
<com.drake.brv.PageRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/page"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.fragment.PushRefreshFragment">
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/rv_push"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+</com.drake.brv.PageRefreshLayout>
+
+

创建列表

+
rv_push.linear().setup {
+    addType<String>(R.layout.item_list)
+}
+
+

网络请求

+
    +
  1. 请求开始, 显示下拉刷新动画
  2. +
  3. 请求成功, 显示内容缺省页
  4. +
  5. 请求失败, 显示错误缺省页
  6. +
+
page.onRefresh {
+    scope {
+        // 请求到数据设置到RecyclerView
+        rv_push.models = Get<ListModel>("list").await().data.list
+    }
+}.autoRefresh()
+
+

生命周期

+ + + + + + + + + + + + + + + + + +
生命周期描述
开始showLoading/autoRefresh触发onRefresh, 开始请求
结束PageRefreshLayout被销毁, 请求自动取消
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/auto-state.html b/auto-state.html new file mode 100644 index 000000000..b3fd4aa4e --- /dev/null +++ b/auto-state.html @@ -0,0 +1,1331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 自动缺省页 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自动缺省页

+ +
+

模块化依赖

+

如果自己处理缺省页可跳过本章, Net可以仅仅作为简单的网络框架存在

+
+


+Net可依赖三方库实现自动缺省页, 以下二选一依赖

+
    +
  1. 依赖 StateLayout
    +
    implementation 'com.github.liangjingkanji:StateLayout:+' // 使用固定版本号替换+符号
    +
  2. +
  3. 依赖 BRV (因为BRV包含StateLayout)
    +
    implementation 'com.github.liangjingkanji:BRV:+' // 使用固定版本号替换+符号
    +
  4. +
+

初始化

+

在Application中初始化缺省页

+
StateConfig.apply {
+    emptyLayout = R.layout.layout_empty
+    loadingLayout = R.layout.layout_loading
+    errorLayout = R.layout.layout_error
+}
+
+

创建

+

使用StateLayout包裹的内容即内容(content)

+
<com.drake.statelayout.StateLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:id="@+id/state"
+    android:layout_height="match_parent"
+    tools:context=".ui.fragment.StateLayoutFragment">
+
+    <TextView
+        android:id="@+id/tvFragment"
+        android:padding="32dp"
+        android:textStyle="bold"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:text="内容" />
+
+</com.drake.statelayout.StateLayout>
+
+

网络请求

+
    +
  1. 请求开始, 显示加载中缺省页
  2. +
  3. 请求成功, 显示内容缺省页
  4. +
  5. 请求失败, 显示错误缺省页
  6. +
+

state.onRefresh {
+    scope {
+        tvFragment.text = Get<String>("api").await()
+    }
+}.showLoading()
+
+

+

生命周期

+ + + + + + + + + + + + + + + + + +
生命周期描述
开始showLoading触发onRefresh, 开始请求
结束缺省页被销毁, 请求自动取消
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/cache.html b/cache.html new file mode 100644 index 000000000..280ba6512 --- /dev/null +++ b/cache.html @@ -0,0 +1,1438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 缓存 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+ +
+
+ + + +
+
+ + + + + + + +

缓存

+ +

缓存优势

+
    +
  1. 页面秒开
  2. +
  3. 减少服务器压力
  4. +
  5. 无网络可用
  6. +
+

Net缓存特点

+
    +
  1. 缓存任何请求方式
  2. +
  3. 缓存任何数据, File/图片/JSON/ProtoBuf等
  4. +
  5. 限制最大缓存空间
  6. +
  7. 使用DiskLruCache实现, 删除最近最少使用
  8. +
+

配置缓存

+

不配置Cache是不会启用缓存的 +

NetConfig.initialize(Api.HOST, this) {
+    // Net支持Http缓存协议和强制缓存模式
+    // 当超过maxSize最大值会根据最近最少使用算法清除缓存来限制缓存大小
+    cache(Cache(cacheDir, 1024 * 1024 * 128))
+}
+

+
+

判断响应来自缓存

+

如果Response.cacheResponse不为null的时, 代表Response来自本地缓存

+
+

Http缓存协议

+

OkHttp默认的Http缓存协议控制, 要求以下条件

+
    +
  • Get请求方式
  • +
  • 缓存使用Url为key, 因此Url改变会读不到缓存
  • +
  • 响应头控制缓存: Cache-Control
  • +
+


+通过setCacheControl可以控制Http缓存协议(原理是添加请求头)

+
scopeNetLife {
+    Post<String>("api") {
+        setCacheControl(CacheControl.FORCE_CACHE) // 强制使用缓存
+        // setCacheControl(CacheControl.FORCE_NETWORK) // 强制使用网络
+        // setCacheControl(CacheControl.Builder().noStore().noCache().build()) // 完全禁止读取/写入缓存
+    }.await()
+}
+
+

如果无法实现Http标准缓存协议, 或要缓存Get以外的请求方法, 可以使用强制缓存模式来由客户端控制缓存

+

强制缓存模式

+

无论请求是否存在Http标准缓存协议, 当你设置强制缓存模式时其会无视Http标准缓存协议

+
scopeNetLife {
+    binding.tvFragment.text =
+        Post<String>("api") {
+            setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
+        }.await()
+}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
强制缓存模式描述
READ只读取缓存, 读不到NoCacheException
WRITE只请求网络, 强制写入缓存
READ_THEN_REQUEST先从缓存读取,如果失败再从网络读取, 强制写入缓存
REQUEST_THEN_READ先从网络读取,如果失败再从缓存读取, 强制写入缓存
+

自定缓存Key

+

强制缓存模式有效, 缓存Key默认是请求方式+URL后产生的sha1值

+

如果要缓存区别请求参数, 请自定义缓存key

+
scopeNetLife {
+    binding.tvFragment.text =
+        Post<String>("api") {
+            setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
+            setCacheKey("请求热门信息" + params) // 具体值都行
+        }.await()
+}
+
+

缓存有效期

+
    +
  1. 强制缓存模式有效, 标准Http缓存协议遵守协议本身的有效期
  2. +
  3. 缓存有效期过期只是让缓存无效, 不会立即删除
    根据(最近最少使用)原则在缓存空间达到配置值时删除(即使缓存有效期未到)
  4. +
+
scopeNetLife {
+    binding.tvFragment.text =
+        Post<String>("api") {
+            setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
+            setCacheValidTime(1, TimeUnit.DAYS) // 缓存仅一天内有效
+        }.await()
+}
+
+

预览(缓存+网络)

+

预览又可以理解为回退请求, 一般用于秒开首页或者回退加载数据

+
scopeNetLife {
+    // 然后执行这里(网络请求)
+    binding.tvFragment.text = Get<String>("api") {
+        setCacheMode(CacheMode.WRITE)
+    }.await()
+    Log.d("日志", "网络请求")
+}.preview(true) {
+    // 先执行这里(仅读缓存), 任何异常都视为读取缓存失败
+    binding.tvFragment.text = Get<String>("api") {
+        setCacheMode(CacheMode.READ)
+    }.await()
+    Log.d("日志", "读取缓存")
+}
+
+
+

这和加载两次有什么区别?

+

区别是preview可以控制以下行为

+
    +
  1. breakError 读取缓存成功后不再处理错误信息, 默认false
  2. +
  3. breakLoading 读取缓存成功后结束加载动画, 默认true
  4. +
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/callback.html b/callback.html new file mode 100644 index 000000000..87aa238e9 --- /dev/null +++ b/callback.html @@ -0,0 +1,1184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Callback - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Callback

+ +

Net支持OkHttp的原有的队列请求Callback

+
+

不推荐

+

Callback属于接口回调, 其代码冗余, 且无法支持并发请求

+
+
Net.post("api").enqueue(object : Callback {
+    override fun onFailure(call: Call, e: IOException) {
+    }
+
+    override fun onResponse(call: Call, response: Response) {
+        // 此处为子线程
+        val body = response.body?.string() ?: "无数据"
+        runMain {
+            // 此处为主线程
+            binding.tvFragment.text = body
+        }
+    }
+})
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/cancel.html b/cancel.html new file mode 100644 index 000000000..45690f761 --- /dev/null +++ b/cancel.html @@ -0,0 +1,1282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 取消请求 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

取消请求

+ +

部分场景需要手动取消请求, 例如取消下载

+
downloadScope = scopeNetLife {
+    // 下载文件
+    val file = Get<File>("download").await()
+}
+
+downloadScope.cancel() // 取消下载
+
+

任意位置取消

+

发起请求时指定Id

+
scopeNetLife {
+    tvFragment.text = Get<String>("api"){
+        setId("请求用户信息")
+    }.await()
+}
+
+
+
+
+
Net.cancelId("请求用户信息")
+
+
+
+
Net.cancelGroup("请求分组名称")
+
+
+
+
+

Group和Id区别

+ + + + + + + + + + + + + + + + + +
函数描述
id请求唯一Id, 实际上重复也行, 但是取消请求时遍历到指定Id就会结束遍历
group允许多个请求使用相同group, 在取消请求时会遍历所有分组的请求
+
+

作用域结束请求自动取消

+

scopeXX()作用域中发起请求时会默认使用当前协程错误处理器作为Group +

setGroup(coroutineContext[CoroutineExceptionHandler])
+
+在作用域结束时 会cancelGroup, 所以如果你手动指定分组会导致无法自动取消

+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/config.html b/config.html new file mode 100644 index 000000000..d7655875e --- /dev/null +++ b/config.html @@ -0,0 +1,1380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 全局配置 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

全局配置

+ +

全局配置应在Application.onCreate中配置

+

初始配置

+

两种方式初始配置, 不初始化也能直接使用

+
+
+
+
NetConfig.initialize(Api.HOST, this) {
+    // 超时配置, 默认是10秒, 设置太长时间会导致用户等待过久
+    connectTimeout(30, TimeUnit.SECONDS)
+    readTimeout(30, TimeUnit.SECONDS)
+    writeTimeout(30, TimeUnit.SECONDS)
+    setDebug(BuildConfig.DEBUG)
+    setConverter(SerializationConverter())
+}
+
+
+
+
val okHttpClientBuilder = OkHttpClient.Builder()
+    .setDebug(BuildConfig.DEBUG)
+    .setConverter(SerializationConverter())
+    .addInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))
+NetConfig.initialize(Api.HOST, this, okHttpClientBuilder)
+
+
+
+
+
+

强制初始化

+

如果是多进程项目(例如Xposed)必须初始化, 因为多进程无法自动指定Context

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
可配置选项描述
setDebug开启日志
setSSLCertificate配置Https证书
trustSSLCertificate信任所有Https证书
setConverter转换器, 将请求结果转为任何类型
setRequestInterceptor请求拦截器, 全局请求头/请求参数
setErrorHandler全局错误处理
setDialogFactory全局对话框
+
+

修改配置

+

NetConfig存储所有全局配置变量, 可以后续修改, 且大部分支持单例指定配置

+
+

重试次数

+

可以添加RetryInterceptor拦截器即可实现失败以后会重试指定次数

+

默认情况下设置超时时间即可, OkHttp内部也有重试机制

+
NetConfig.initialize(Api.HOST, this) {
+    // ... 其他配置
+    addInterceptor(RetryInterceptor(3)) // 如果全部失败会重试三次
+}
+
+
+

长时间阻碍用户交互

+

OkHttp内部也有重试机制, 如果还添加重试拦截器可能导致请求时间过长, 长时间阻碍用户交互

+
+

多域名

+

概念源于Retrofit(称为BaseUrl), 因为Retrofit无法二次修改请求Host, 但Net支持随时修改

+

以下介绍三种修改方式

+
+
+
+
NetConfig.host = Api.HOST_2
+
+
+
+

指定Path(例如/api/index)会自动和NetConfig.host拼接组成Url, 但指定以http/https开头的全路径则直接作为请求Url +

scopeNetLife {
+    val data = Get<String>("https://github.com/path").await()
+}
+

+
+
+

请求时指定tag, 然后拦截器中根据tag判断修改host, 拦截器能修改所有请求/响应信息

+
scopeNetLife {
+    val data = Get<String>("/api/index", "User").await() // User即为tag
+}
+// 拦截器修改请求URL不做介绍
+
+
+
+
+

网络安全配置

+

Net自动启用网络配置文件, 默认支持Http请求, 可自定义

+
network_security_config.xml
<network-security-config>
+    <base-config cleartextTrafficPermitted="true" />
+</network-security-config>
+
+
+

无法打包Apk

+

当开发者自定义使用非同名network_security_config时网络配置文件时会无法打包Apk

+

请添加tools:replace +

AndroidManifest.xml
<application
+    tools:replace="android:networkSecurityConfig">
+

+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/converter-customize.html b/converter-customize.html new file mode 100644 index 000000000..ad6a5fd34 --- /dev/null +++ b/converter-customize.html @@ -0,0 +1,1373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 自定义转换器 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自定义转换器

+ +

Net自定义转换器可支持任何数据类型, 甚至Bitmap

+
+

泛型和转换器关系

+
    +
  1. 如果Post<Model>, 那么NetConverter.onConvert返回值必须为Model
  2. +
  3. 如果Post<Model?>, 允许NetConverter.onConvert返回值为null
  4. +
  5. 其他情况请抛出异常
  6. +
+
+
scopeNetLife {
+    val userList = Get<List<UserModel>>("list") {
+        converter = GsonConverter()
+    }.await()
+}
+
+

Net由于低耦合原则不自带任何序列化框架

+

设置转换器

+
+
+
+
NetConfig.initialize(Api.HOST, this) {
+    setConverter(SerializationConverter())
+}
+
+
+
+
scopeNetLife {
+   tvFragment.text = Get<String>("api"){
+        converter = SerializationConverter()
+   }.await()
+}
+
+
+
+
+

常见转换器

+

实现JSONConverterparseBody方法使用自定义序列化框架解析

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
序列化框架示例代码描述
kotlin-serializationSerializationConverterKotlin官方序列化框架
kotlin-serializationProtobufConverterKotlin官方序列化框架
gsonGsonConverter谷歌序列化框架
fastJsonFastJsonConverter阿里巴巴序列化框架
moshiMoshiConverterSquare序列化框架
+

自定义转换器

+

实现NetConverter返回自定义请求结果

+
+转换器实现非常简单 +
NetConverter.kt
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
interface NetConverter {
+
+    @Throws(Throwable::class)
+    fun <R> onConvert(succeed: Type, response: Response): R?
+
+    companion object DEFAULT : NetConverter {
+        /**
+         * 返回结果应当等于泛型对象, 可空
+         * @param succeed 请求要求返回的泛型类型
+         * @param response 请求响应对象
+         */
+        override fun <R> onConvert(succeed: Type, response: Response): R? {
+            return when {
+                succeed === String::class.java && response.isSuccessful -> response.body?.string() as R
+                succeed === ByteString::class.java && response.isSuccessful -> response.body?.byteString() as R
+                succeed is GenericArrayType && succeed.genericComponentType === Byte::class.java && response.isSuccessful -> response.body?.bytes() as R
+                succeed === File::class.java && response.isSuccessful -> response.file() as R
+                succeed === Response::class.java -> response as R
+                else -> throw ConvertException(response, "An exception occurred while converting the NetConverter.DEFAULT")
+            }
+        }
+    }
+}
+
+
+

转换器中可以根据需加上解密数据, token失效跳转登录, 限制多端登录等逻辑

+
    +
  1. 日志信息输出, 请阅读日志记录器
  2. +
  3. 转换器中抛出异常被全局错误处理捕获, 请阅读全局错误处理
  4. +
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/converter-struct.html b/converter-struct.html new file mode 100644 index 000000000..abb2e17ba --- /dev/null +++ b/converter-struct.html @@ -0,0 +1,1386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 自定义结构解析 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自定义结构解析

+ +

上一章节介绍如何序列化框架解析JSON, 而本章是介绍如何定义映射数据类

+

JSON

+

解析接口返回的完整JSON

+
+
+
+
{
+    "code":0,
+    "msg":"请求成功",
+    "data": {
+        "name": "彭于晏",
+        "age": 27,
+        "height": 180
+    }
+}
+
+
+
+
data class UserModel (
+    var code:Int,
+    var msg:String,
+    var data:Data,
+) {
+    data class Data(var name: String, var age: Int, var height: Int)
+}
+
+
+
+
scopeNetLife {
+    val data = Get<UserModel>("api").await().data
+}
+
+
+
+
+
+以上设计不合理 +

正常情况下Http状态码200时只返回有效数据 +

{
+    "name": "彭于晏",
+    "age": 27,
+    "height": 180
+}
+
+任何非正常流程返回200状态码, 例如400(错误请求)/401(认证失败) +
{
+    "code":412302,
+    "msg":"密码错误",
+}
+
+只要认为需要解析结构体情况下, 都应属于正常流程

+
+

剔除无效字段

+

以下演示仅解析data字段返回有效数据

+

此数据类只需要包含data值

+
data class UserModel(var name: String, var age: Int, var height: Int)
+
+

转换器只解析data字段

+
class GsonConvert : JSONConvert(code = "code", message = "msg", success = "200") {
+    private val gson = GsonBuilder().serializeNulls().create()
+
+    override fun <S> String.parseBody(succeed: Type): S? {
+        val data = JSONObject(this).getString("data")
+        return gson.fromJson(data, succeed)
+    }
+}
+
+

请求直接返回

+
scopeNetLife {
+    val data = Get<UserModel>("api").await()
+}
+
+

不规范数据

+

推荐在转换器中解析之前处理好数据

+
    +
  1. +

    字段值为"null"而不是null, 或者json在字符串中 +

     {
    +   "data": "{ "title": "name" }"
    +   "msg": "null"
    + }
    +
    +
    替换为规范内容
    json = bodyString.replace("\"{", "{")
    +json = bodyString.replace("}\"", "}")
    +json = bodyString.replace("\"null\"", "null")
    +

    +
  2. +
  3. +

    服务器成功时不返回数据或者返回null +

    if (response.body == null || bodyString == "null") {
    +    "{}".bodyString.parseBody<R>(succeed)
    +}
    +

    +
  4. +
  5. +

    字段值为null, 使用 kotlin-serialization 自动使用字段默认值 +

    {
    +    "msg": null
    +}
    +

    +
  6. +
  7. 字段无引号或字段名为数字, 使用 kotlin-serialization 可以禁用JSON规范限制 +
    数字使用map解析
     {
    +   "data": {
    +     23: 32
    +   }
    + }
    +
    +
    禁用JSON规范限制
    val jsonDecoder = Json {
    +    // ...
    +    isLenient = true
    +}
    +
  8. +
+

泛型数据类

+

某些地区很多开发者习惯这么使用, 因为他们接口返回无关字段, 但是技术不够无法自定义转换器来简化取值

+

所以他们选择更复杂的方式: 使用泛型来简化

+
open class BaseResult<T> {
+    var code: Int = 0
+    var msg: String = ""
+    var data: T? = null
+}
+
+class Result(var name: String) : BaseResult<Result>()
+
+
+

用加法解决问题的人,总有人愿意用乘法给你答案

+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/converter.html b/converter.html new file mode 100644 index 000000000..970474e13 --- /dev/null +++ b/converter.html @@ -0,0 +1,1262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 转换器 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Net支持请求返回的数据类型取决于你的转换器实现

+

Get<任何对象>("path").await()

+

默认转换器支持返回以下数据类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
String字符串
ByteArray字节数组
ByteString更多功能的字符串对象
File文件对象, 这种情况其实应当称为下载文件
Response所有响应信息(响应体/响应头/请求信息等)
+

使用示例

+
scopeNetLife {
+    Get<Response>("api").await().headers("响应头名称") // 返回响应头
+}
+
+
+转换器实现非常简单 +
NetConverter.kt
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
interface NetConverter {
+
+    @Throws(Throwable::class)
+    fun <R> onConvert(succeed: Type, response: Response): R?
+
+    companion object DEFAULT : NetConverter {
+        /**
+         * 返回结果应当等于泛型对象, 可空
+         * @param succeed 请求要求返回的泛型类型
+         * @param response 请求响应对象
+         */
+        override fun <R> onConvert(succeed: Type, response: Response): R? {
+            return when {
+                succeed === String::class.java && response.isSuccessful -> response.body?.string() as R
+                succeed === ByteString::class.java && response.isSuccessful -> response.body?.byteString() as R
+                succeed is GenericArrayType && succeed.genericComponentType === Byte::class.java && response.isSuccessful -> response.body?.bytes() as R
+                succeed === File::class.java && response.isSuccessful -> response.file() as R
+                succeed === Response::class.java -> response as R
+                else -> throw ConvertException(response, "An exception occurred while converting the NetConverter.DEFAULT")
+            }
+        }
+    }
+}
+
+
+

假设不支持你需要的数据类型, 例如JSON/ProtoBuf/Bitmap等请自定义转换器

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/cookie.html b/cookie.html new file mode 100644 index 000000000..c76a791be --- /dev/null +++ b/cookie.html @@ -0,0 +1,1205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Cookie - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Cookie

+ +

使用OkHttp的CookieJar, Net提供持久化CookiePersistentCookieJar

+
NetConfig.initialize(Api.HOST, this) {
+    // 添加持久化Cookie
+    cookieJar(PersistentCookieJar(this@App))
+}
+
+

可以手动增删Cookie

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PersistentCookieJar描述
addAll添加Cookie
getAll获取某个域名的所有Cookie
remove删除某个域名下所有或者指定名称的Cookie
clear删除客户端全部Cookie
+

可通过客户端获取到已配置cookieJar +

(NetConfig.okHttpClient.cookieJar as? PersistentCookieJar)?.clear()
+

+
+

隔绝Cookies共享

+

PersistentCookieJar指定不同dbName阻止不同的客户端共享Cookies

+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/coroutine-request.html b/coroutine-request.html new file mode 100644 index 000000000..12fdfcf1c --- /dev/null +++ b/coroutine-request.html @@ -0,0 +1,1189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 协程请求 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

协程请求

+ +

Net的协程作用域会自动处理协程生命周期

+

在上章节已经介绍如何发起并发网络请求, 这里演示同时(并发)请求一万次, 然后取消全部

+
val job = scopeNetLife {
+    repeat(10000) {
+        // 这里将返回的数据显示在TextView上
+        launch {
+            tvFragment.text = Get<String>(Api.PATH).await()
+        }
+    }
+}
+
+

等待五秒后取消请求 +

thread {
+    Thread.sleep(5000) // 等待五秒
+    job.cancel()
+}
+

+


+

Net主要使用协程请求, 但也支持其他方式发起请求

+ + + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/css/extra.css b/css/extra.css new file mode 100644 index 000000000..a3ccf56a6 --- /dev/null +++ b/css/extra.css @@ -0,0 +1,53 @@ +@font-face{ + font-family: 'Iosevka Curly'; + src: local('Iosevka Curly Medium'), + url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/iosevka-curly/iosevka-curly-medium.woff2') format('woff2'); + font-display: swap; + font-weight: normal; + font-style: normal; +} +@font-face{ + font-family: 'Iosevka Curly'; + src: local('Iosevka Curly Bold'), + url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/iosevka-curly/iosevka-curly-bold.woff2') format('woff2'); + font-display: swap; + font-weight: bold; + font-style: normal; +} +@font-face{ + font-family: 'HYYouYuan'; + src: local('HYYouYuan-55W'), + url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/HYYouYuan/HYYouYuan-55W.ttf') format('truetype'); + font-display: swap; + font-weight: normal; + font-style: normal; +} +@font-face{ + font-family: 'HYYouYuan'; + src: local('HYYouYuan-75W'), + url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/HYYouYuan/HYYouYuan-75W.ttf') format('truetype'); + font-display: swap; + font-weight: bold; + font-style: normal; +} + +* { + -webkit-font-feature-settings: "liga" on, "calt" on; + -webkit-font-smoothing: subpixel-antialiased; + -moz-osx-font-smoothing: auto; + text-rendering: optimizeLegibility; + font-family: "Iosevka Curly", HYYouYuan !important; +} + +code, +.md-nav, +.md-typeset code, +.md-typeset { + font-size: 14px !important; +} + +.highlight span.filename, +.md-typeset .admonition-title, +.md-typeset summary { + font-weight: normal; +} \ No newline at end of file diff --git a/debounce.html b/debounce.html new file mode 100644 index 000000000..af851603c --- /dev/null +++ b/debounce.html @@ -0,0 +1,1193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 搜索节流 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

搜索节流

+ +
+

节流

+

在一定时间间隔内,只执行最后一次请求, 忽略其他多余的请求

+
+

搜索输入框一般都是输入完关键词后自动开始搜索

+

这个过程涉及到

+
    +
  1. 每次变化都搜索会导致服务器压力, 应在停止输入满足一定时间后自动搜索
  2. +
  3. 当产生新的搜索请求后应取消旧请求, 以防止旧数据覆盖新数据
  4. +
  5. 当输入内容没有变化(例复制粘贴重复内容到搜索框)不会发起搜索请求
  6. +
+


+

+


+
var scope: CoroutineScope? = null
+
+// distinctUntilChanged 表示过滤掉重复结果
+binding.etInput.debounce().distinctUntilChanged().launchIn(this) {
+    scope?.cancel() // 发起新的请求前取消旧的请求, 避免旧数据覆盖新数据
+    scope = scopeNetLife { // 保存旧的请求到一个变量中
+        binding.tvFragment.text = "请求中"
+        binding.tvFragment.text = Get<String>(Api.TIME).await()
+    }
+}
+
+

指定参数设置节流阀超时时间 +

fun EditText.debounce(timeoutMillis: Long = 800)
+

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/download-file.html b/download-file.html new file mode 100644 index 000000000..d628352b0 --- /dev/null +++ b/download-file.html @@ -0,0 +1,1306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 下载文件 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

下载文件

+ +

泛型改为File即可

+
scopeNetLife {
+    val file = Get<File>("download").await()
+}
+
+

下载选项

+

丰富的下载定制方案, 并且在不断更新

+
scopeNetLife {
+    val file =
+        Get<File>("https://github.com/liangjingkanji/Net/releases/latest/download/net-sample.apk") {
+            setDownloadFileName("net.apk")
+            setDownloadDir(requireContext().filesDir)
+            setDownloadMd5Verify()
+        }.await()
+}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
配置选项描述
addDownloadListener下载进度监听器
setDownloadFileName下载文件名
setDownloadDir下载目录
setDownloadMd5Verify下载文件MD5校验
setDownloadFileNameConflict下载文件同名冲突解决
setDownloadFileNameDecode文件名Url解码中文
setDownloadTempFile临时文件名
+

重复下载

+

防止重复下载有以下方式

+ + + + + + + + + + + + + + + + + + + + + +
函数描述
文件判断判断本地是否存在同名文件
缓存模式开启缓存, 占用设备两份空间(缓存/下载成功文件都占空间)
MD5校验服务器返回Content-MD5, 客户端开启setDownloadMd5Verify
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/error-global.html b/error-global.html new file mode 100644 index 000000000..3aa00fced --- /dev/null +++ b/error-global.html @@ -0,0 +1,1217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 全局捕获 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

全局捕获

+ +

可实现NetErrorHandler接口来监听全局错误处理

+
+
+
+
class NetworkingErrorHandler : NetErrorHandler {
+    override fun onError(e: Throwable) {
+    // .... 其他错误
+        if (e is ResponseException && e.tag == 401) { // 判断异常为token失效
+           // 打开登录界面或者弹登录失效对话框
+        }
+    }
+}
+
+
+
+
NetConfig.initialize(Api.HOST, this) {
+    setErrorHandler(NetworkingErrorHandler))
+}
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + +
NetErrorHandler使用场景触发位置
onError吐司错误信息scopeNetLife/scopeDialog
onStateError要求错误显示在缺省页PageRefreshLayout.scope/StateLayout.scope
+
+

以下情况全局错误处理无效

+
    +
  1. 异步任务作用域(scope/scopeLife)发生的错误
  2. +
  3. 使用单例错误处理处理的错误
  4. +
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/error-single.html b/error-single.html new file mode 100644 index 000000000..bded975f7 --- /dev/null +++ b/error-single.html @@ -0,0 +1,1284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 单例捕获 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

单例捕获

+ +

捕获当前请求/作用域错误, 将不会再被全局错误处理

+

捕获请求

+

一个请求发生错误会取消当前作用域内所有请求, 但单独捕获后不会再影响其他请求

+

例如 +

scopeNetLife {
+    Get<String>("api").await() // 失败
+    Get<String>("api2").await() // 上面失败, 此处也不会执行
+}
+

+

捕获第一个协程避免终止后续执行 +

scopeNetLife {
+    try {
+        Get<String>("api").await() // 失败
+    } catch(e:Exception) {
+    }
+    Get<String>("api2").await() // 上面失败, 此处继续执行
+}
+
+当然如果创建不同的作用域分别请求那是互不影响的 +
scopeNetLife {
+    Get<String>("api").await() // 失败
+}
+scopeNetLife {
+    Get<String>("api2").await() // 上面失败, 此处完全不受影响
+}
+

+


+

捕获作用域

+
scope {
+    val data = Get<String>("http://www.thisiserror.com/").await()
+}.catch {
+    // 协程内发生错误回调, it为异常对象
+}.finally {
+    // 协程执行完毕回调(不论成败), it为异常对象
+}
+
+ + + + + + + + + + + + + + + + + +
函数区别
catch发生错误后回调, 取消不回调
不会再执行全局错误处理, 可使用handleError再次传递给全局
finally执行完毕回调(不论成败), 取消作用域时itCancellationException
执行全局错误处理
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/error-throws.html b/error-throws.html new file mode 100644 index 000000000..eb0f50832 --- /dev/null +++ b/error-throws.html @@ -0,0 +1,1355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 自定义异常抛出 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自定义异常抛出

+ +

以下为Net内部抛出的异常对象

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
异常描述
NetException未知的网络异常, 一般情况应当继承他来创建自定义的网络异常
HttpFailureExceptionHttp请求错误, Http请求失败(onFailure)
HttpResponseExceptionHttp请求成功后发生的错误, Http请求成功但发生异常(onResponse)
URLParseException地址错误
NetUnknownHostException域名错误
NetSocketTimeoutException连接超时
NetConnectException连接网络失败, 设备未开启网络
NetworkingException当前网络不可用, Net并未实现
DownloadFileException下载文件异常
ConvertException解析错误, NetConvert中发生的未捕获异常都算解析错误
RequestParamsException请求参数错误 400 - 499 范围内错误码
ServerResponseException服务器错误 500 - 599 范围内错误码
ResponseException错误码异常, 一般应用于后端返回的错误码和其定义的成功码不匹配
NullPointerException空指针, 一般是在作用域内操作一个空的对象
+
+

NetworkingException

+

由于谷歌限制Net无法判断网络是否可用, 请开发者自己抛出

+
+

自定义异常

+

在转换器(NetConverter)或拦截器(Interceptor)中抛出任何异常 +该异常对象都会被单例或全局错误处理接收, 可用于判断异常信息做特殊处理 +(例如Token失效则跳转到登录页面)

+
+

转换发生异常

+

NetConverter中的所有异常除非是NetException子类否则都将被ConvertException包裹
+即捕获的是ConvertException, cause才为实际抛出异常

+
+

异常传递字段

+

Net自带异常会有类型为Any的字段tag, 可用传递对象用于判断错误处理

+

例如ResponseException常用于作为请求服务器成功但后端业务错误, 然后tag为传递的错误码

+

示例代码

+
+
+
+
class SerializationConverter(
+    val success: String = "0",
+    val code: String = "code",
+    val message: String = "msg"
+) : NetConverter {
+
+    override fun <R> onConvert(succeed: Type, response: Response): R? {
+        try {
+            return NetConverter.onConvert<R>(succeed, response)
+        } catch (e: ConvertException) {
+            val code = response.code
+            when {
+                code in 200..299 -> { // 请求成功
+                // ... 假设Token失效. 后端返回业务错误码 srvCode = 401
+                    throw ResponseException(response, errorMessage, tag = srvCode) // 将业务错误码作为tag传递
+                }
+                code in 400..499 -> throw RequestParamsException(response, code.toString()) // 请求参数错误
+                code >= 500 -> throw ServerResponseException(response, code.toString()) // 服务器异常错误
+                else -> throw ConvertException(response)
+            }
+        }
+    }
+}
+
+
+
+
class NetworkingErrorHandler : NetErrorHandler {
+    override fun onError(e: Throwable) {
+    // .... 其他错误
+        if (e is ResponseException && e.tag == 401) { // 判断异常为token失效
+           // 打开登录界面或者弹登录失效对话框
+        }
+    }
+}
+
+
+
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/error-tip.html b/error-tip.html new file mode 100644 index 000000000..a92453eb7 --- /dev/null +++ b/error-tip.html @@ -0,0 +1,1290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 自定义错误提示 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

自定义错误提示

+ +
+

网络错误提示

+

网络请求发生错误一定要提示给用户, 并且是可读语义句

+
+

修改默认吐司错误文本或国际化参考以下方式

+

创建多语言

+

错误提示文本被定义在strings.xml, 在项目中创建同名name可复写Net定义的文本

+

国际化语言则需创建多语言values, 例如英语是values-en下创建strings.xml

+
+错误文本 +
    <!--网络请求异常-->
+    <string name="net_connect_error">连接网络失败</string>
+    <string name="net_url_error">请求资源地址错误</string>
+    <string name="net_host_error">无法找到指定服务器主机</string>
+    <string name="net_connect_timeout_error">连接服务器超时,%s</string>
+    <string name="net_download_error">下载过程发生错误</string>
+    <string name="net_no_cache_error">读取缓存失败</string>
+    <string name="net_parse_error">解析数据时发生异常</string>
+    <string name="request_failure">请求失败</string>
+    <string name="net_request_error">请求参数错误</string>
+    <string name="net_server_error">服务响应错误</string>
+    <string name="net_null_error">发生空异常</string>
+    <string name="net_error">未知网络错误</string>
+    <string name="net_other_error">未知错误</string>
+    <string name="no_error_message">无错误信息</string>
+
+    <!--对话框-->
+    <string name="net_dialog_msg">加载中</string>
+
+
+

创建NetErrorHandler

+

使用自定义全局错误处理可完全修改, 可不提示错误或附上错误信息

+
+全局错误处理 +
fun onError(e: Throwable) {
+    val message = when (e) {
+        is UnknownHostException -> NetConfig.app.getString(R.string.net_host_error)
+        is URLParseException -> NetConfig.app.getString(R.string.net_url_error)
+        is NetConnectException -> NetConfig.app.getString(R.string.net_connect_error)
+        is NetSocketTimeoutException -> NetConfig.app.getString(
+            R.string.net_connect_timeout_error,
+            e.message
+        )
+        is DownloadFileException -> NetConfig.app.getString(R.string.net_download_error)
+        is ConvertException -> NetConfig.app.getString(R.string.net_parse_error)
+        is RequestParamsException -> NetConfig.app.getString(R.string.net_request_error)
+        is ServerResponseException -> NetConfig.app.getString(R.string.net_server_error)
+        is NullPointerException -> NetConfig.app.getString(R.string.net_null_error)
+        is NoCacheException -> NetConfig.app.getString(R.string.net_no_cache_error)
+        is ResponseException -> e.message
+        is HttpFailureException -> NetConfig.app.getString(R.string.request_failure)
+        is NetException -> NetConfig.app.getString(R.string.net_error)
+        else -> NetConfig.app.getString(R.string.net_other_error)
+    }
+
+    Net.debug(e)
+    TipUtils.toast(message)
+}
+
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/error.html b/error.html new file mode 100644 index 000000000..202f21672 --- /dev/null +++ b/error.html @@ -0,0 +1,1208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 错误处理 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

错误处理

+ +

Net有完善的错误处理机制, 具备捕获异常/取消请求/错误提示/追踪链路

+
+

收集网络日志

+

在Net作用域内发生的异常都会被全局错误处理捕获, 可以将其筛选上传日志

+
+


+以下位置抛出异常会被捕获

+ + + + + + + + + + + + + + + + + + + + + +
函数描述
作用域scopeXX代码块中
拦截器Interceptor/RequestInterceptor
转换器NetConverter
+

如果捕获到错误默认会执行以下操作

+
    +
  1. Logcat输出异常堆栈信息, 自定义异常抛出
  2. +
  3. Toast显示错误文本, 自定义错误提示
  4. +
+


+
+

捕获不到异常

+

如果请求未执行await(), 那么即使发生错误也不会被捕获到

+
+


+自定义请阅读全局错误处理

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/fastest.html b/fastest.html new file mode 100644 index 000000000..4cca742b8 --- /dev/null +++ b/fastest.html @@ -0,0 +1,1313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 最快请求结果 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

最快请求结果

+ +

多个请求并发执行

+
    +
  1. 当某个请求成功时, 剩余请求将被自动取消
  2. +
  3. 全部错误时则会抛出最后一个请求错误作为结果
  4. +
+
+

异常信息

+

先失败的请求错误会被忽略, 但LogCat依然会输出异常

+
+

示例 +

scopeNetLife {
+
+    // 同时发起四个网络请求
+    val deferred = Get<String>("api0") // 错误接口
+    val deferred1 = Get<String>("api1") // 错误接口
+    val deferred2 = Get<String>("api")
+    val deferred3 = Post<String>("api")
+
+    // 只返回最快的请求结果
+    tvFragment.text = fastest(deferred, deferred1, deferred2, deferred3)
+}
+

+

取消剩余

+

上面的示例不会在获取到结果后取消剩余请求, 需设置同一请求分组才可以

+
scopeNetLife {
+    // 同时发起四个网络请求
+    val deferred2 = Get<String>("api") { setGroup("初始化") }
+    val deferred3 = Post<String>("api") { setGroup("初始化") }
+    val deferred = Get<String>("api0") { setGroup("初始化") } // 错误接口
+    val deferred1 = Get<String>("api1") { setGroup("初始化") } // 错误接口
+
+    // 只返回最快的请求结果
+    tvFragment.text = fastest(listOf(deferred, deferred1, deferred2, deferred3), "初始化")
+}
+
+

类型不一致

+

当需要返回结果, 但多接口返回数据类型不同, 使用transform转换为同一类型结果

+
scopeNetLife {
+
+    val fastest = Post<String>("api").transform {
+        Log.d("日志", "Post") // 如果该接口最快则会回调这里
+        it // 这里可以返回其他数据结果
+    }
+
+    val fastest2 = Get<String>("api").transform {
+        Log.d("日志", "Get") // 如果该接口最快则会回调这里
+        it
+    }
+
+    tvFragment.text = fastest(fastest, fastest2)
+}
+
+
+

只有最快返回结果的网络请求(或异步任务)的transform回调才会被执行到

+
+

捕获错误

+
scopeNetLife {
+    val task = Get<String>("api2")
+    val task1 = Get<String>("api2")
+    val task2 = Get<String>("api2")
+
+    val data = try {
+        fastest(listOf(task, task1, task2))
+    // 当task/task1/task2全部错误后才并发执行backupTask/backupTask1
+    } catch (e: Exception) {
+        val backupTask = Get<String>("api2")
+        val backupTask1 = Get<String>("api")
+        fastest(listOf(backupTask, backupTask1))
+    }
+}
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/https.html b/https.html new file mode 100644 index 000000000..9a69fd422 --- /dev/null +++ b/https.html @@ -0,0 +1,1295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Https证书 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Https证书

+ +

Net可快速配置Https证书, 或者使用OkHttp的方式

+

使用CA证书

+

Https如果使用的CA证书, 不需要任何配置可以直接访问

+
scopeNetLife {
+    tvFragment.text = Get<String>(Api.PATH).await()
+}
+
+

信任所有证书

+

信任所有证书可以解决无法访问私有证书的Https地址问题

+
+
+
+
NetConfig.initialize(Api.HOST, this){
+    trustSSLCertificate() // 信任所有证书
+}
+
+
+
+
scopeNetLife {
+    Get<String>(Api.PATH){
+      setClient {
+          trustSSLCertificate()
+      }
+    }.await()
+}
+
+
+
+
+

导入证书

+

私有证书可以放到任何位置, 只要读取到InputStream流对象即可

+
+
+
+
NetConfig.initialize(Api.HOST, this) {
+    val privateCertificate = resources.assets.open("https.certificate")
+    setSSLCertificate(privateCertificate)
+}
+
+
+
+
scopeNetLife {
+    Get<String>(Api.PATH) {
+        setClient {
+            val privateCertificate = resources.assets.open("https.certificate") // 这里的证书是放到应用的资产目录下
+            setSSLCertificate(privateCertificate)
+        }
+    }.await()
+}
+
+
+
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/img/book-open.svg b/img/book-open.svg new file mode 100644 index 000000000..b0cbc997c --- /dev/null +++ b/img/book-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/code-preview.png b/img/code-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..b6fd23b9930be0d509b7d603214f33ebc409a628 GIT binary patch literal 26782 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�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 literal 0 HcmV?d00001 diff --git a/img/discussesions.svg b/img/discussesions.svg new file mode 100644 index 000000000..eca257dee --- /dev/null +++ b/img/discussesions.svg @@ -0,0 +1,25 @@ + + + 编组备份 + + + + + + + 讨论 + + + Discussions + + + + + \ No newline at end of file diff --git a/img/issues.svg b/img/issues.svg new file mode 100644 index 000000000..38eabc8ad --- /dev/null +++ b/img/issues.svg @@ -0,0 +1,29 @@ + + + 编组 + + + + + + + 常见问题 + + + + + + Issues + + + + + + \ No newline at end of file diff --git a/img/logo.gif b/img/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..fb83d5d6b75742e029b74f131acafdda827254c0 GIT binary patch literal 57457 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%0D}PFq3wQ-BXS}|O9U#gqMrI>2?5O3w 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 literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 000000000..7ac294b12 --- /dev/null +++ b/index.html @@ -0,0 +1,1321 @@ + + + + + + + + + + + + + + + + + + + + + + + + Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

使用

+ +

Net是基于OkHttp/协程的非侵入式框架(可使用所有Api), 可升级OkHttp版本保持网络安全

+


+

STAR/分享可以让更多人参与到本开源项目

+


+
+

前言

+
    +
  • 未实现功能可以搜索"OkHttp如何XX"来扩展
  • +
  • 阅读示例/源码来学习如何封装
  • +
  • 如果觉得文档看不懂那肯定是作者问题, 请反馈给作者或者自我修订
  • +
+
+

使用

+


+发起网络请求的三个步骤

+
    +
  1. 创建作用域
  2. +
  3. 发起请求动作
  4. +
  5. 等待数据返回
  6. +
+
+
+
+
scopeNetLife {
+    // 大括号内属于作用域
+    val data = Get<String>(Api.USER).await() // 发起GET请求并返回`String`
+}
+
+
+
+
scopeNetLife {
+    // B将等待A请求返回结果后发起请求
+    val userInfo = Get<UserInfo>(Api.USER).await() // A
+
+    val config = Get<Config>(Api.CONFIG){ // B
+        param("userId", userInfo.id) // 将上个请求结果作为参数
+    }.await()
+}
+
+
+
+
scopeNetLife {
+    // 两个请求同时发起
+    val getUserInfoAsync = Get<UserInfo>(Api.USER)
+    val getConfigAsync = Get<Config>(Api.CONFIG)
+
+    val userInfo = getUserInfoAsync.await() // 等待数据返回
+    val config = getConfigAsync.await()
+}
+
+
+
+
+
    +
  1. 多个网络请求在同一个作用域内可以统一管理
  2. +
  3. 如果多个网络请求之间毫无关联, 可以创建多个作用域来请求
  4. +
+
+

强制初始化

+

多进程或Xposed项目要求先初始化

+
+

自动识别Url或者Path请求

+
scopeNetLife {
+    val userInfo = Get<String>("/net").await()
+    val config = Get<String>("https://github.com/liangjingkanji/net").await()
+}
+
+

返回结果

+

返回结果支持的数据类型(即Post等函数的泛型)由转换器决定, 默认支持以下类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
String字符串
ByteArray字节数组
ByteString内部定义的一种字符串对象
Response最基础的响应
File文件对象, 这种情况其实应当称为下载文件
+
scopeNetLife {
+    val file = Get<File>(Api.FILE).await()
+}
+
+

详细查看转换器, 非以上类型要求自定义转换器

+
+

下载Apk +下载源码 +示例代码 +界面演示

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/interceptor.html b/interceptor.html new file mode 100644 index 000000000..903b21922 --- /dev/null +++ b/interceptor.html @@ -0,0 +1,1277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 拦截器 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

拦截器

+ +

根据使用场景选择

+
    +
  1. Interceptor: 支持三方OkHttp拦截器组件, 允许修改请求/响应信息, 可以转发请求
  2. +
  3. RequestInterceptor: Net独有的轻量级拦截器, 允许修改全局请求头/请求参数, 无法转发请求 +
  4. +
+
+

禁止随意封装

+

不应为全局参数/加密等封装请求方法, 应自定义拦截器/转换器来实现, 常见拦截器示例

+
+

拦截器

+

添加拦截器

+
NetConfig.initialize(Api.HOST, this) {
+    addInterceptor(RefreshTokenInterceptor())
+}
+
+

演示客户端自动刷新token的拦截器

+
/**
+ * 演示如何自动刷新token令牌
+ */
+class RefreshTokenInterceptor : Interceptor {
+    override fun intercept(chain: Interceptor.Chain): Response {
+        val request = chain.request()
+        val response = chain.proceed(request) // 如果token失效
+
+        return synchronized(RefreshTokenInterceptor::class.java) {
+            if (response.code == 401 && UserConfig.isLogin && !request.url.pathSegments.contains("token")) {
+                val json = Net.get("token").execute<String>() // 同步刷新token
+                UserConfig.token = JSONObject(json).optString("token")
+                chain.proceed(request)
+            } else {
+                response
+            }
+        }
+    }
+}
+
+

请求拦截器

+

轻量级拦截器(RequestInterceptor), 其Api更适合添加全局请求头/参数

+
NetConfig.initialize(Api.HOST, this) {
+    setRequestInterceptor(object : RequestInterceptor {
+        override fun interceptor(request: BaseRequest) {
+            request.param("client", "Net")
+            request.setHeader("token", "123456")
+        }
+    })
+}
+
+

可以看出setRequestInterceptor仅支持一个, addInterceptor支持多个拦截器

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/interval.html b/interval.html new file mode 100644 index 000000000..92d4dd59d --- /dev/null +++ b/interval.html @@ -0,0 +1,1257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 轮询器/倒计时 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

轮询器/倒计时

+ +

Net自带轮询器(计时器), 包含以下特性

+
    +
  • 正计时
  • +
  • 倒计时
  • +
  • 指定次数
  • +
  • 支持开始/停止/暂停/继续/重置/切换开关
  • +
  • 仅页面显示时计时
  • +
  • 页面销毁自动取消
  • +
+


+
+
+
+
interval = Interval(100, 1, TimeUnit.SECONDS).life(this) // 自定义计数器个数的轮询器
+
+
+
+
 interval = Interval(1, TimeUnit.SECONDS) // 每秒回调一次, 不会自动结束
+
+
+
+
// 倒计时轮询器, 当[start]]比[end]值大, 且end不等于-1时, 即为倒计时
+interval = Interval(1, 1, TimeUnit.SECONDS, 5).life(this)
+
+
+
+
+

监听轮询器 +

interval.subscribe {
+    tvFragment.text = it.toString()
+}.finish {
+    tvFragment.text = "计时完成" // 最后一位数时同时回调 subscribe/finish
+}.start()
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Interval描述
start开始轮询器
stop停止
cancel取消, 区别于stop, 此函数执行后并不会回调finish
pause暂停
resume继续
reset重置
switch切换开关
subscribe每次计时都会执行该回调
finish当计时器完成时执行该回调, 执行stop后也会回调
life指定生命周期自动取消轮询器
onlyResumed当界面不可见时暂停, 当界面可见时继续
+
+

后台运行

+

由于系统限制, 本工具无法保证后台运行

+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/issues.html b/issues.html new file mode 100644 index 000000000..7707c5f51 --- /dev/null +++ b/issues.html @@ -0,0 +1,1243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 常见问题 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

常见问题

+ +

Net最大的特点在于完美支持OkHttp的所有功能组件, 而OkHttp是Android主流网络解决方案

+

所以如果存在Net没有实现的功能可以谷歌搜索"OkHttp如何实现XX", 然后可以很容易在Net中使用

+

低版本兼容

+

如果你是在 Android 5 (API level 21) +以上开发建议使用最新版本: Net
+如果要求低至 Android 4.4 (API level 19) +请使用兼容版本: Net-okhttp3

+

如果需更低版本支持建议拉取仓库修改minSdkVersion后编译成aar使用

+

开发者交流

+ + + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/kotlin-serialization.html b/kotlin-serialization.html new file mode 100644 index 000000000..12d9f0959 --- /dev/null +++ b/kotlin-serialization.html @@ -0,0 +1,1414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Kotlin-Serialization - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

Kotlin-Serialization

+ +
    +
  1. 从Net3开始支持使用 Kotlin-Serialization (以下简称ks)
  2. +
  3. 更多了解请阅读: Kotlin最强解析库 - kotlin-serialization
  4. +
+

特点

+
    +
  • 官方库
  • +
  • 动态数据类型解析
  • +
  • 自定义序列化器
  • +
  • 支持ProtoBuf/JSON等数据结构序列化
  • +
  • 非空覆盖(即JSON字段为null则使用变量默认值)
  • +
  • 启用宽松模式, JSON和数据类结构无需一致
  • +
  • 解析任何类型(Map/List/Pair...)
  • +
+
+

强制注解

+

ks的数据类都要求使用注解@Serializable(除非自定义解析), 父类和子类都需要

+
+
+

生成默认值

+

使用插件生成数据Model, 支持自动生成默认值和注解

+

生成默认值可避免后端返回异常数据导致解析崩溃, 以及反复编写判空代码

+
+

依赖

+

Project build.gradle

+
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
+// 和Kotlin插件同一个版本号即可
+
+

Model build.gradle

+
apply plugin: "kotlin-kapt"
+apply plugin: 'kotlinx-serialization'
+implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0"
+
+

配置转换器

+

这里使用示例代码中 SerializationConvert 作为演示

+
+
+
+
NetConfig.initialize(Api.HOST, this) {
+    setConverter(SerializationConvert())
+    // ... 其他配置
+}
+
+
+
+
val userList = Get<List<UserModel>>("list") {
+    converter = SerializationConvert() // 单例转换器, 此时会忽略全局转换器
+}.await()
+
+
+
+
+

使用

+
scopeNetLife {
+    val userList = Get<List<UserModel>>("list") {
+        converter = SerializationConvert()
+    }.await()
+
+    tvFragment.text = userList[0].name
+}
+
+
@Serializable
+data class UserModel(var name: String, var age: Int, var height: Int)
+
+

常用配置

+

以下为反序列化Json常用配置

+
val jsonDecoder = Json {
+    ignoreUnknownKeys = true // 数据类可以不用声明Json的所有字段
+    coerceInputValues = true // 如果Json字段是Null则使用数据类字段默认值
+}
+
+

数据类使用默认值 +

@Serializable
+data class Data(var name:String = "", var age:Int = 0)
+

+

启用默认值

+

coerceInputValues = true时, json字段为null数据类字段为非空类型情况下采用字段默认值, 没有默认值请explicitNulls = false则赋值为null

+

同时当出现未知的枚举类型也会使用默认值

+

字段缺失

+

通过explicitNulls来配置字段缺时处理方式

+
    +
  • 反序列化时, 如果数据类缺失字段, 使用ignoreUnknownKeys = true就会自动使用默认值, 没有默认值请explicitNulls = false赋值为null
  • +
  • 序列化时, 数据类如果字段为null也会被赋值到json中, explicitNulls = false可以忽略掉
  • +
+

自动生成

+

手动写默认值太麻烦, 推荐使用插件生成默认值

+

+

插件具体配置使用请查看: 数据模型生成插件

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/log-notice.html b/log-notice.html new file mode 100644 index 000000000..08436ea1d --- /dev/null +++ b/log-notice.html @@ -0,0 +1,1189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 日志通知 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

日志通知

+ +

使用三方库 Chucker 在通知栏记录网络请求日志

+
+

+

Chucker

+
+

依赖

+
implementation "com.github.chuckerteam.chucker:library:3.5.2"
+
+

添加拦截器

+
NetConfig.initialize(Api.HOST, this) {
+    // ...
+    if (BuildConfig.DEBUG) {
+        addInterceptor(
+            ChuckerInterceptor.Builder(this@App)
+                .collector(ChuckerCollector(this@App))
+                .maxContentLength(250000L)
+                .redactHeaders(emptySet())
+                .alwaysReadResponseBody(false)
+                .build()
+        )
+    }
+}
+
+

自定义功能浏览 Chucker 官网

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/log-recorder.html b/log-recorder.html new file mode 100644 index 000000000..0b6b02aa9 --- /dev/null +++ b/log-recorder.html @@ -0,0 +1,1446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 日志插件 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

日志插件

+ +

两种日志插件

+ + + + + + + + + + + + + + + + + + + + + +
Okhttp ProfilerProfiler
列表显示动态曲线图
要求添加LogRecordInterceptor可查看所有OkHttp的请求
原理是插件捕获LogCat日志, 线上环境请关闭无法捕获启动一瞬间的请求
+

LogRecordInterceptor

+

添加日志拦截器

+
NetConfig.initialize(Api.HOST, this) {
+    addInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))
+}
+
+ + + + + + + + + + + + + + + + + + + + + +
构造参数描述
enabled是否启用日志
requestByteCount请求日志信息最大字节数, 默认1MB
responseByteCount响应日志信息最大字节数, 默认4MB
+

此时仅LogCat输出日志, 要预览请安装插件

+

安装插件

+

1. 安装插件

+

在插件市场搜索: "Okhttp Profiler"

+

+

2. 打开窗口

+

安装以后在AndroidStudio右下角打开窗口

+

+
+

不显示日志

+

请在请求前确保有打开过插件窗口, 如果依然不显示可以反复打开/关闭窗口

+

每次AS更新都需要该插件作者适配, 可能存在beta版本作者没有适配情况

+
+

使用效果

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
标题描述
Device选择调试设备
Process选择展示记录的进程
抓取一般情况不需要使用, 假设没有及时更新请点击图标
清空清空记录
+

自定义日志

+

继承LogRecordInterceptor复写函数实现自定义

+
    +
  1. 复写getRequestLog返回解密请求参数
  2. +
  3. 复写getResponseLog返回解密响应参数
  4. +
+

初始化时添加自己的拦截器

+
NetConfig.initialize(Api.HOST, this) {
+    addInterceptor(MyLogRecordInterceptor(BuildConfig.DEBUG))
+}
+
+

日志过滤

+

+

不想网络日志影响其他日志查看, 可以添加OKPREL_为日志折叠规则 +

+

其他网络框架

+

LogRecordInterceptor属于OkHttp拦截器, 其他网络请求框架也可以使用

+

甚至可以直接使用LogRecorder输出日志

+ + + + + + + + + + + + + + + + + + + + + + + + + +
LogRecorder描述
generateId产生一个唯一标识符, 用于判断为同一网络请求
recordRequest记录请求信息
recordResponse记录响应信息
recordException记录请求异常信息
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/material/partials/footer.html b/material/partials/footer.html new file mode 100644 index 000000000..7873920a4 --- /dev/null +++ b/material/partials/footer.html @@ -0,0 +1,66 @@ +{% import "partials/language.html" as lang with context %} + + + \ No newline at end of file diff --git a/model-generate.html b/model-generate.html new file mode 100644 index 000000000..7ea9649cb --- /dev/null +++ b/model-generate.html @@ -0,0 +1,1362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 数据类生成插件 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

数据类生成插件

+ +

应该没人会完全手写数据模型吧? 建议使用JSON To Kotlin Class 插件完成

+

安装插件

+

在Plugins里面搜索kotlin关键词下载安装 +

+

使用插件

+

选中分包后, 使用快捷键或者鼠标右键打开填写Json界面

+

+

添加Json然后点击Generate生成

+

+

然后就会在选中的分包下生成一个数据模型类了

+
+

不要生成数组

+

不要输入JSON数组生成(否则生成的类会继承ArrayList), 输入JSON对象, 请求使用Get<List<对象>>

+
+

高级设置

+

点击Advanced打开设置界面

+

可空选项

+

截图即为我的推荐配置

+

+
    +
  1. Keyword 创建的数据模型的字段是 Val还是Var
  2. +
  3. Type 字段是否是可空类型, 最后选项表示根据Json的值判断是否可空
  4. +
  5. 默认值的策略, 无法选择不介绍
  6. +
+

使用的框架

+

生成数据模型时会兼容你使用的框架, 例如Moshi和ks可能需要注解, 然后会自动生成SerialName这些名称注解 +

+

其他

+

截图即为我的推荐配置

+

+
    +
  1. 是否使用注释, 既会将Json字符串作为注释保留在数据模型类中
  2. +
  3. 根据字母排序数据模型的字段
  4. +
  5. 使用内部类. 例如Json中的Json对象会作为内部类被创建在数据模型类中 (推荐开启, 保持高内聚低耦合)
  6. +
  7. 如果Json对象的字段都是原始类型则使用Map来表示
  8. +
  9. 只在需要时创建注解
  10. +
  11. 自动验证Json正确性(在填写时)
  12. +
  13. Json格式化时使用的空格数量
  14. +
  15. 指定一个类作为父类模板(既创建的数据模型都会继承该类)
  16. +
+

扩展

+

截图即为我的推荐配置

+

+
    +
  1. 添加@Keep注解, 为防止被代码混淆
  2. +
  3. 注解和字段处于同一行, 便于美观
  4. +
  5. 使用Parcelable序列化
  6. +
  7. 为字段添加前缀/后缀
  8. +
  9. 为数据模型类添加前缀/后缀
  10. +
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/okhttp-client.html b/okhttp-client.html new file mode 100644 index 000000000..c680fe504 --- /dev/null +++ b/okhttp-client.html @@ -0,0 +1,1265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + OkHttpClient - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

OkHttpClient

+ +

Net全局持有一个OkHttpClient对象发起请求

+
object NetConfig {
+    var okHttpClient: OkHttpClient
+}
+
+

全局

+
NetConfig.initialize(Api.HOST, this) {
+    // 此处this即为OkHttpClient.Builder
+}
+
+

单例

+

可以单独指定当前请求客户端

+
+
+
+

scopeNetLife {
+    tv_response.text = Get<String>(Api.PATH) {
+        setClient {
+            // 此处this即为OkHttpClient.Builder
+            trustCertificate()
+        }
+    }.await()
+}
+
+ 在全局OkHttpClient基础上修改

+
+
+

scopeNetLife {
+    tv_response.text = Get<String>(Api.PATH) {
+        okHttpClient = OkHttpClient.Builder().build()
+    }.await()
+}
+
+创建新的OkHttpClient, 一般不使用, 因为新OkHttpClient会重新创建线程池/连接池等造成内存消耗

+
+
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/progress.html b/progress.html new file mode 100644 index 000000000..4e4a9b826 --- /dev/null +++ b/progress.html @@ -0,0 +1,1431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 进度监听 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

进度监听

+ +

Net支持上传/下载的进度监听, 且具备完善的进度信息

+

上传进度监听

+
scopeNetLife {
+    Post<String>(Api.UPLOAD) {
+        param("file", assetsFile())
+        addUploadListener(object : ProgressListener() {
+            override fun onProgress(p: Progress) {
+                seek.post {
+                    seek.progress = p.progress()
+                    tvProgress.text =
+                        "上传进度: ${p.progress()}% 上传速度: ${p.speedSize()}     " +
+                                "\n\n文件大小: ${p.totalSize()}  已上传: ${p.currentSize()}  剩余大小: ${p.remainSize()}" +
+                                "\n\n已使用时间: ${p.useTime()}  剩余时间: ${p.remainTime()}"
+                }
+            }
+        })
+    }.await()
+}
+
+

下载进度监听

+
scopeNetLife {
+    val file =
+        Get<File>("https://github.com/liangjingkanji/Net/releases/latest/download/net-sample.apk") {
+            setDownloadFileName("net.apk")
+            setDownloadDir(requireContext().filesDir)
+
+            addDownloadListener(object : ProgressListener() {
+                override fun onProgress(p: Progress) {
+                    seek?.post {
+                        val progress = p.progress()
+                        seek.progress = progress
+                        tvProgress.text =
+                            "下载进度: $progress% 下载速度: ${p.speedSize()}     " +
+                                    "\n\n文件大小: ${p.totalSize()}  已下载: ${p.currentSize()}  剩余大小: ${p.remainSize()}" +
+                                    "\n\n已使用时间: ${p.useTime()}  剩余时间: ${p.remainTime()}"
+                    }
+                }
+            })
+        }.await()
+}
+
+
+

监听任何进度

+

不仅是泛型为File才有效, 任何请求/响应都可以监听进度

+
+

监听器

+

实现ProgressListener监听进度信息. 进度信息为Progress

+

进度间隔时间

+

ProgressListener的构造参数interval控制触发进度监听器的间隔时间

+

进度信息

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
currentBytes已完成字节数
totalBytes全部大小字节数
intervalBytes进度间隔时间内完成的字节数
intervalTime距离上次进度变化间隔时间
startElapsedRealtime开始下载时间(该时间值开机到现在的毫秒数)
speedBytes每秒下载字节数
progress进度, 1-100
finish此次下载/上传是否完成
useTimeSeconds已经使用时间, 单位秒
remainTimeSeconds估算的剩余时间, 单位秒
+

格式化字符串

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
currentSize已完成大小, 例如: 120kB 或者 1.5MB
totalSize全部大小
remainSize剩余大小
speedSize每秒下载大小
useTime已使用时间, 格式为: 01:23:04
remainTime估算的剩余时间, 格式为: 01:23:04
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/repeat-request.html b/repeat-request.html new file mode 100644 index 000000000..70b622439 --- /dev/null +++ b/repeat-request.html @@ -0,0 +1,1182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 重复请求 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

重复请求

+ +

常用于筛选列表请求, 选择新的筛选条件时应将上次未完成的取消后再发起请求

+

在Net禁止重复请求仅2行代码

+
var scope: AndroidScope? = null
+
+btnFilter.setOnClickListener {
+    scope?.cancel()
+
+    scope = scopeNetLife {
+        val result = Post<String>("api").await()
+    }
+}
+
+

scope不为空时表示存在旧请求, 无论旧请求是否完成都可以调用cancel()保证取消即可

+
    +
  1. 取消请求
  2. +
  3. 限制时间强制使用缓存, 配置缓存有效期
  4. +
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/request.html b/request.html new file mode 100644 index 000000000..47c3cb116 --- /dev/null +++ b/request.html @@ -0,0 +1,1377 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 请求参数 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

请求参数

+ +
+

请求参数

+

根据请求方式不同请求参数分为两类

+

UrlRequest: GET, HEAD, OPTIONS, TRACE // Query(请求参数位于Url中)
+BodyRequest: POST, DELETE, PUT, PATCH // Body(请求体为流)

+
+

使用示例

+
scopeNetLife {
+    val userInfo = Post<UserInfoModel>(Api.LOGIN) {
+        param("username", "用户名")
+        param("password", "6f2961eb44b12123393fff7e449e50b9de2499c6")
+    }.await()
+}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
paramUrl请求时为Query, Body请求时为表单/文件
jsonJSON字符串
setQuery/addQueryUrl中的Query参数, 如果当为Url请求则该函数等效param
setHeader/addHeader设置/添加请求头
+

JSON

+

三种参数类型上传JSON示例, 更多请阅读方法注释

+
+
+
+
val name = "金城武"
+val age = 29
+val measurements = listOf(100, 100, 100)
+
+scopeNetLife {
+    tvFragment.text = Post<String>("api") {
+        // 只支持基础类型的值, 如果值为对象或者包含对象的集合/数组会导致其值为null
+        json("name" to name, "age" to age, "measurements" to measurements)
+    }.await()
+}
+
+
+
+
val name = "金城武"
+val age = 29
+val measurements = listOf(100, 100, 100) // 只支持基础类型的值, 如果值为对象或者包含对象的集合/数组会导致其值为null
+
+scopeNetLife {
+    tvFragment.text = Post<String>("api") {
+        json(JSONObject().run {
+            put("name", name)
+            put("age", age)
+            put("measurements", JSONArray(measurements))
+        })
+    }.await()
+}
+
+
+
+
val name = "金城武"
+val age = 29
+val measurements = listOf(100, 100, 100)
+
+scopeNetLife {
+    tvFragment.text = Post<String>("api") {
+        body = CustomizerJSONBody(name, age, measurements)
+    }.await()
+}
+
+
+
+
+

如果JSON需要全局参数

+
    +
  1. 自定义RequestBody添加全局参数
  2. +
  3. 使用请求拦截器来添加全局参数 RequestInterceptor
  4. +
+

自定义扩展函数

+

由于json()不能传对象, 因为使用的org.json.JSONObject其不支持映射对象字段

+

但可创建扩展函数来使用射对象序列化框架来解析, 如下

+
+
+
+
fun BodyRequest.gson(vararg body: Pair<String, Any?>) {
+    this.body = Gson().toJson(body.toMap()).toRequestBody(MediaConst.JSON)
+}
+
+
+
+
fun BodyRequest.fastJson(vararg body: Pair<String, Any?>) {
+    this.body = JSON.toJSON(body.toMap()).toRequestBody(MediaConst.JSON)
+}
+
+
+
+
+

使用

+
scopeNetLife {
+    tvFragment.text = Post<String>("api") {
+        gson("name" to name, "model" to Model()) // 参数支持Gson可解析的对象
+        // fastJson("name" to name, "model" to Model()) // 使用FastJson
+    }.await()
+}
+
+

全局请求参数

+

使用RequestInterceptor请求拦截器添加全局参数/请求头, 更复杂请实现Interceptor

+
class GlobalHeaderInterceptor : RequestInterceptor {
+
+    // 每次请求都会回调, 可以是动态参数
+    override fun interceptor(request: BaseRequest) {
+        request.setHeader("client", "Android")
+        request.setHeader("token", UserConfig.token)
+    }
+}
+
+
NetConfig.initialize(Api.HOST, this) {
+    setRequestInterceptor(GlobalHeaderInterceptor())
+}
+
+

更多请求参数相关请阅读Api文档/函数列表

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/scope.html b/scope.html new file mode 100644 index 000000000..c48afa7ee --- /dev/null +++ b/scope.html @@ -0,0 +1,1373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 作用域 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

作用域

+ +

创建不同协程作用域可以实现不同的功能

+
+

减少崩溃

+

Net所有作用域内抛出异常都会被捕获到, 可以防止应用崩溃

+
+

异步任务的作用域

+

可以捕捉异常的协程作用域, 用于构建普通异步任务

+ + + + + + + + + + + + + + + + + + + + + +
函数描述
scope创建最基础的作用域
scopeLife创建跟随生命周期自动取消的作用域
ViewModel.scopeLife创建跟随ViewModel生命周期的作用域, 如何在ViewModel创建作用域
+

网络请求的作用域

+

除异步任务外还适用于网络请求场景的作用域, 对比上面异步任务的作用域区别:

+
    +
  1. 发生错误自动吐司(可以自定义或者取消)
  2. +
  3. 发生错误会触发全局错误处理NetErrorHandler
  4. +
  5. 具备一些特殊场景功能, 比如根据网络请求结果自动处理下拉刷新/上拉加载/缺省页/加载框的状态
  6. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
scopeNet创建自动处理网络错误的作用域
scopeNetLife创建自动处理网络错误的作用域, 且包含跟随Activity或者Fragment生命周期
scopeDialog创建自动加载对话框的作用域, 生命周期跟随对话框
ViewModel.scopeNetLife创建跟随ViewModel生命周期的作用域, 如何在ViewModel创建作用域
PageRefreshLayout.scope创建跟随PageRefreshLayout生命周期的作用域
StateLayout.scope创建跟随StateLayout生命周期的作用域
+
+

区分函数接受者

+

注意StateLayout.scope等存在函数接受者的方法和scope属于两个方法, 严禁混用

+
+
+

第三方库支持

+

PageRefreshLayout/StateLayout 属于第三方开源项目 BRV +框架中的布局, 可用于支持自动化缺省页/下拉刷新

+
+

如果想更了解协程使用方式, +可以阅读一篇文章: 最全面的Kotlin协程: Coroutine/Channel/Flow 以及实际应用

+

嵌套作用域

+

有时候可能面临内嵌scopeXX函数(嵌套作用域), 这时候生命周期如下

+
scopeNetLife {
+    val task = Post<String>("api0").await()
+
+    scopeNetLife {
+        val task = Post<String>("api0").await() // 此时发生请求错误
+    }.catch {
+        // A
+    }
+}.catch {
+    // B
+}
+
+
    +
  • 错误将在A处可以获取到, 且不影响外部scopeNetLife的请求
  • +
  • 两个scopeNetLife的异常抛出和捕获互不影响
  • +
  • scopeXX()等函数同理
  • +
+

子作用域

+
scopeNet {
+    val await = Post<String>("api").await()
+
+    launch {
+       val task = Post<String>("api0").await()  // 此时发生请求错误
+    }.invokeOnCompletion {
+        // A
+    }
+}.catch {
+     // B
+}
+
+
    +
  • 这种情况 先执行A然后执行B, 并且都能捕获异常.
  • +
  • 同时scopeNet发生错误也会导致launch内的请求被取消, launch发生错误也会导致scopeNet发生错误
  • +
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search/search_index.js b/search/search_index.js new file mode 100644 index 000000000..1c8fb086b --- /dev/null +++ b/search/search_index.js @@ -0,0 +1 @@ +var __index = {"config":{"lang":["en"],"separator":"[\\s\\-,:!=\\[\\]()\"/]+|(?!\\b)(?=[A-Z][a-z])|\\.(?!\\d)|&[lg]t;","pipeline":["stemmer"]},"docs":[{"location":"index.html","title":"\u4f7f\u7528","text":"

Net\u662f\u57fa\u4e8eOkHttp/\u534f\u7a0b\u7684\u975e\u4fb5\u5165\u5f0f\u6846\u67b6(\u53ef\u4f7f\u7528\u6240\u6709Api), \u53ef\u5347\u7ea7OkHttp\u7248\u672c\u4fdd\u6301\u7f51\u7edc\u5b89\u5168

STAR/\u5206\u4eab\u53ef\u4ee5\u8ba9\u66f4\u591a\u4eba\u53c2\u4e0e\u5230\u672c\u5f00\u6e90\u9879\u76ee

\u524d\u8a00

  • \u672a\u5b9e\u73b0\u529f\u80fd\u53ef\u4ee5\u641c\u7d22\"OkHttp\u5982\u4f55XX\"\u6765\u6269\u5c55
  • \u9605\u8bfb\u793a\u4f8b/\u6e90\u7801\u6765\u5b66\u4e60\u5982\u4f55\u5c01\u88c5
  • \u5982\u679c\u89c9\u5f97\u6587\u6863\u770b\u4e0d\u61c2\u90a3\u80af\u5b9a\u662f\u4f5c\u8005\u95ee\u9898, \u8bf7\u53cd\u9988\u7ed9\u4f5c\u8005\u6216\u8005\u81ea\u6211\u4fee\u8ba2
"},{"location":"index.html#_1","title":"\u4f7f\u7528","text":"

\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\u7684\u4e09\u4e2a\u6b65\u9aa4

  1. \u521b\u5efa\u4f5c\u7528\u57df
  2. \u53d1\u8d77\u8bf7\u6c42\u52a8\u4f5c
  3. \u7b49\u5f85\u6570\u636e\u8fd4\u56de
\u7b80\u5355\u8bf7\u6c42\u540c\u6b65\u8bf7\u6c42\u5e76\u53d1\u8bf7\u6c42
scopeNetLife {\n// \u5927\u62ec\u53f7\u5185\u5c5e\u4e8e\u4f5c\u7528\u57df\nval data = Get<String>(Api.USER).await() // \u53d1\u8d77GET\u8bf7\u6c42\u5e76\u8fd4\u56de`String`\n}\n
scopeNetLife {\n// B\u5c06\u7b49\u5f85A\u8bf7\u6c42\u8fd4\u56de\u7ed3\u679c\u540e\u53d1\u8d77\u8bf7\u6c42\nval userInfo = Get<UserInfo>(Api.USER).await() // A\nval config = Get<Config>(Api.CONFIG){ // B\nparam(\"userId\", userInfo.id) // \u5c06\u4e0a\u4e2a\u8bf7\u6c42\u7ed3\u679c\u4f5c\u4e3a\u53c2\u6570\n}.await()\n}\n
scopeNetLife {\n// \u4e24\u4e2a\u8bf7\u6c42\u540c\u65f6\u53d1\u8d77\nval getUserInfoAsync = Get<UserInfo>(Api.USER)\nval getConfigAsync = Get<Config>(Api.CONFIG)\nval userInfo = getUserInfoAsync.await() // \u7b49\u5f85\u6570\u636e\u8fd4\u56de\nval config = getConfigAsync.await()\n}\n
  1. \u591a\u4e2a\u7f51\u7edc\u8bf7\u6c42\u5728\u540c\u4e00\u4e2a\u4f5c\u7528\u57df\u5185\u53ef\u4ee5\u7edf\u4e00\u7ba1\u7406
  2. \u5982\u679c\u591a\u4e2a\u7f51\u7edc\u8bf7\u6c42\u4e4b\u95f4\u6beb\u65e0\u5173\u8054, \u53ef\u4ee5\u521b\u5efa\u591a\u4e2a\u4f5c\u7528\u57df\u6765\u8bf7\u6c42

\u5f3a\u5236\u521d\u59cb\u5316

\u591a\u8fdb\u7a0b\u6216Xposed\u9879\u76ee\u8981\u6c42\u5148\u521d\u59cb\u5316

\u81ea\u52a8\u8bc6\u522bUrl\u6216\u8005Path\u8bf7\u6c42

scopeNetLife {\nval userInfo = Get<String>(\"/net\").await()\nval config = Get<String>(\"https://github.com/liangjingkanji/net\").await()\n}\n
"},{"location":"index.html#_2","title":"\u8fd4\u56de\u7ed3\u679c","text":"

\u8fd4\u56de\u7ed3\u679c\u652f\u6301\u7684\u6570\u636e\u7c7b\u578b(\u5373Post\u7b49\u51fd\u6570\u7684\u6cdb\u578b)\u7531\u8f6c\u6362\u5668\u51b3\u5b9a, \u9ed8\u8ba4\u652f\u6301\u4ee5\u4e0b\u7c7b\u578b

\u51fd\u6570 \u63cf\u8ff0 String \u5b57\u7b26\u4e32 ByteArray \u5b57\u8282\u6570\u7ec4 ByteString \u5185\u90e8\u5b9a\u4e49\u7684\u4e00\u79cd\u5b57\u7b26\u4e32\u5bf9\u8c61 Response \u6700\u57fa\u7840\u7684\u54cd\u5e94 File \u6587\u4ef6\u5bf9\u8c61, \u8fd9\u79cd\u60c5\u51b5\u5176\u5b9e\u5e94\u5f53\u79f0\u4e3a\u4e0b\u8f7d\u6587\u4ef6
scopeNetLife {\nval file = Get<File>(Api.FILE).await()\n}\n

\u8be6\u7ec6\u67e5\u770b\u8f6c\u6362\u5668, \u975e\u4ee5\u4e0a\u7c7b\u578b\u8981\u6c42\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668

\u4e0b\u8f7dApk \u4e0b\u8f7d\u6e90\u7801 \u793a\u4f8b\u4ee3\u7801 \u754c\u9762\u6f14\u793a

"},{"location":"auto-dialog.html","title":"\u81ea\u52a8\u52a0\u8f7d\u6846","text":"

Net\u652f\u6301\u53d1\u8d77\u8bf7\u6c42\u5f00\u59cb\u65f6\u663e\u793a\u52a0\u8f7d\u6846, \u8bf7\u6c42\u7ed3\u675f\u65f6\u9690\u85cf\u52a0\u8f7d\u6846(\u65e0\u8bba\u6210\u8d25)

"},{"location":"auto-dialog.html#_1","title":"\u81ea\u52a8\u663e\u793a","text":"
scopeDialog {\ntvFragment.text = Post<String>(\"dialog\") {\nparam(\"username\", \"\u7528\u6237\u540d\") // \u8bf7\u6c42\u53c2\u6570\nparam(\"pwd\", \"123456\")\n}.await()\n}\n

\u9ed8\u8ba4\u662f\u539f\u751f\u52a0\u8f7d\u6846(MaterialDesign Dialog), \u53ef\u81ea\u5b9a\u4e49

"},{"location":"auto-dialog.html#_2","title":"\u5355\u4f8b\u81ea\u5b9a\u4e49","text":"

\u6307\u5b9a\u5f53\u524d\u8bf7\u6c42\u52a0\u8f7d\u6846

val dialog = BubbleDialog(requireActivity(), \"\u52a0\u8f7d\u4e2d\")\nscopeDialog(dialog) {\nbinding.tvFragment.text = Post<String>(\"dialog\") {\nparam(\"username\", \"\u7528\u6237\u540d\")\nparam(\"pwd\", \"123456\")\n}.await()\n}\n

\u83ca\u82b1\u52a0\u8f7d\u5bf9\u8bdd\u6846

\u793a\u4f8b\u4f7f\u7528\u7684iOS\u98ce\u683c\u5bf9\u8bdd\u6846: BubbleDialog

"},{"location":"auto-dialog.html#_3","title":"\u5168\u5c40\u81ea\u5b9a\u4e49","text":"

\u521d\u59cb\u5316\u65f6\u6307\u5b9a\u52a0\u8f7d\u5bf9\u8bdd\u6846\u6784\u9020\u5668NetDialogFactory

NetConfig.initialize(Api.HOST, this) {\nsetDialogFactory {\nProgressDialog(it).apply {\nsetMessage(\"\u6211\u662f\u5168\u5c40\u81ea\u5b9a\u4e49\u7684\u52a0\u8f7d\u5bf9\u8bdd\u6846...\")\n}\n}\n}\n

\u5982\u4ec5\u4fee\u6539\u52a0\u8f7d\u5bf9\u8bdd\u6846\u6587\u672c, \u5728\u9879\u76eevalues\u76ee\u5f55\u7684strings.xml\u6dfb\u52a0\u4ee5\u4e0b

<!--\u5bf9\u8bdd\u6846-->\n<string name=\"net_dialog_msg\">\u52a0\u8f7d\u4e2d</string>\n

\u81ea\u5b9a\u4e49\u7684\u52a0\u8f7d\u6846\u4e0d\u662fDialog

\u7531\u4e8escopeDialog\u53ea\u80fd\u6307\u5b9aDialog\u7c7b\u578b, \u56e0\u6b64\u53ea\u80fd\u624b\u52a8\u5b9e\u73b0Dialog\u63a5\u53e3

\u4ec5\u8981\u6c42\u590d\u5199 DialogCoroutineScope \u5185\u8c03\u7528\u7684Dialog\u65b9\u6cd5

"},{"location":"auto-dialog.html#_4","title":"\u751f\u547d\u5468\u671f","text":"

\u4f7f\u7528scopeDialog\u53d1\u8d77\u8bf7\u6c42\u540e, \u5206\u4e3a\u4e09\u4e2a\u751f\u547d\u5468\u671f

\u52a0\u8f7d\u6846\u72b6\u6001 \u4f5c\u7528\u57df \u663e\u793a \u6267\u884cscopeDialog\u65f6\u663e\u793a\u52a0\u8f7d\u6846 \u9690\u85cf \u4f5c\u7528\u57df\u5185\u4efb\u52a1\u7ed3\u675f\u65f6\u9690\u85cf\u52a0\u8f7d\u6846 \u624b\u52a8\u53d6\u6d88 \u53d6\u6d88\u4f5c\u7528\u57df\u5185\u6240\u6709\u7f51\u7edc\u8bf7\u6c42"},{"location":"auto-pull.html","title":"\u81ea\u52a8\u5206\u9875\u52a0\u8f7d","text":"

\u9996\u5148\u8bf7\u9605\u8bfb\u4e0a\u7ae0\u8282 \u81ea\u52a8\u4e0b\u62c9\u5237\u65b0, \u5df2\u63d0\u53ca\u5185\u5bb9\u4e0d\u518d\u91cd\u590d

"},{"location":"auto-pull.html#_1","title":"\u81ea\u52a8\u5206\u9875","text":"

\u63d0\u4f9baddData()\u6765\u7b80\u5316\u5206\u9875, \u5f00\u53d1\u8005\u53ef\u4ee5\u501f\u9274\u5b9e\u73b0

page.onRefresh {\nscope {\nval data = Get<ListModel>(\"list\") {\nparam(\"page\", index)\n}.await().data\naddData(data.list) {\nindex < data.total\n}\n}\n}.autoRefresh()\n
"},{"location":"auto-pull.html#_2","title":"\u7d22\u5f15\u81ea\u589e","text":"

index \u6bcf\u6b21\u4e0a\u62c9\u52a0\u8f7d\u81ea\u52a8++1, \u5237\u65b0\u5217\u8868\u91cd\u7f6e\u4e3aPageRefreshLayout.startIndex

"},{"location":"auto-pull.html#_3","title":"\u6709\u66f4\u591a\u9875","text":"

\u6839\u636ehasMore\u8fd4\u56de\u7ed3\u679c\u662f\u5426\u5173\u95ed\u4e0a\u62c9\u52a0\u8f7d, isEmpty\u51b3\u5b9a\u662f\u5426\u663e\u793a\u7a7a\u6570\u636e\u7f3a\u7701\u9875

fun addData(\ndata: List<Any?>?,\nadapter: BindingAdapter? = null,\nisEmpty: () -> Boolean = { data.isNullOrEmpty() },\nhasMore: BindingAdapter.() -> Boolean = { true }\n)\n

1. PageRefreshLayout \u4e0b\u62c9\u5237\u65b0/\u4e0a\u62c9\u52a0\u8f7d

"},{"location":"auto-refresh.html","title":"\u81ea\u52a8\u4e0b\u62c9\u5237\u65b0","text":"

\u6a21\u5757\u5316\u4f9d\u8d56

\u5982\u679c\u81ea\u5df1\u5904\u7406\u4e0b\u62c9\u5237\u65b0\u53ef\u8df3\u8fc7\u672c\u7ae0, Net\u53ef\u4ee5\u4ec5\u4ec5\u4f5c\u4e3a\u7b80\u5355\u7684\u7f51\u7edc\u6846\u67b6\u5b58\u5728

Net\u53ef\u4f9d\u8d56\u4e09\u65b9\u5e93 BRV \u5b9e\u73b0\u81ea\u52a8\u5904\u7406\u4e0b\u62c9\u5237\u65b0

implementation 'com.github.liangjingkanji:BRV:+' // \u4f7f\u7528\u56fa\u5b9a\u7248\u672c\u53f7\u66ff\u6362+\u7b26\u53f7\n
"},{"location":"auto-refresh.html#pagerefreshlayout","title":"PageRefreshLayout","text":"
<com.drake.brv.PageRefreshLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\nxmlns:tools=\"http://schemas.android.com/tools\"\nxmlns:app=\"http://schemas.android.com/apk/res-auto\"\nandroid:id=\"@+id/page\"\nandroid:layout_width=\"match_parent\"\nandroid:layout_height=\"match_parent\"\ntools:context=\".ui.fragment.PushRefreshFragment\">\n<androidx.recyclerview.widget.RecyclerView\nandroid:id=\"@+id/rv_push\"\nandroid:layout_width=\"match_parent\"\nandroid:layout_height=\"match_parent\" />\n</com.drake.brv.PageRefreshLayout>\n
"},{"location":"auto-refresh.html#_1","title":"\u521b\u5efa\u5217\u8868","text":"
rv_push.linear().setup {\naddType<String>(R.layout.item_list)\n}\n
"},{"location":"auto-refresh.html#_2","title":"\u7f51\u7edc\u8bf7\u6c42","text":"
  1. \u8bf7\u6c42\u5f00\u59cb, \u663e\u793a\u4e0b\u62c9\u5237\u65b0\u52a8\u753b
  2. \u8bf7\u6c42\u6210\u529f, \u663e\u793a\u5185\u5bb9\u7f3a\u7701\u9875
  3. \u8bf7\u6c42\u5931\u8d25, \u663e\u793a\u9519\u8bef\u7f3a\u7701\u9875
page.onRefresh {\nscope {\n// \u8bf7\u6c42\u5230\u6570\u636e\u8bbe\u7f6e\u5230RecyclerView\nrv_push.models = Get<ListModel>(\"list\").await().data.list\n}\n}.autoRefresh()\n
"},{"location":"auto-refresh.html#_3","title":"\u751f\u547d\u5468\u671f","text":"\u751f\u547d\u5468\u671f \u63cf\u8ff0 \u5f00\u59cb showLoading/autoRefresh\u89e6\u53d1onRefresh, \u5f00\u59cb\u8bf7\u6c42 \u7ed3\u675f PageRefreshLayout\u88ab\u9500\u6bc1, \u8bf7\u6c42\u81ea\u52a8\u53d6\u6d88"},{"location":"auto-state.html","title":"\u81ea\u52a8\u7f3a\u7701\u9875","text":"

\u6a21\u5757\u5316\u4f9d\u8d56

\u5982\u679c\u81ea\u5df1\u5904\u7406\u7f3a\u7701\u9875\u53ef\u8df3\u8fc7\u672c\u7ae0, Net\u53ef\u4ee5\u4ec5\u4ec5\u4f5c\u4e3a\u7b80\u5355\u7684\u7f51\u7edc\u6846\u67b6\u5b58\u5728

Net\u53ef\u4f9d\u8d56\u4e09\u65b9\u5e93\u5b9e\u73b0\u81ea\u52a8\u7f3a\u7701\u9875, \u4ee5\u4e0b\u4e8c\u9009\u4e00\u4f9d\u8d56

  1. \u4f9d\u8d56 StateLayout
    implementation 'com.github.liangjingkanji:StateLayout:+' // \u4f7f\u7528\u56fa\u5b9a\u7248\u672c\u53f7\u66ff\u6362+\u7b26\u53f7\n
  2. \u4f9d\u8d56 BRV (\u56e0\u4e3aBRV\u5305\u542bStateLayout)
    implementation 'com.github.liangjingkanji:BRV:+' // \u4f7f\u7528\u56fa\u5b9a\u7248\u672c\u53f7\u66ff\u6362+\u7b26\u53f7\n
"},{"location":"auto-state.html#_1","title":"\u521d\u59cb\u5316","text":"

\u5728Application\u4e2d\u521d\u59cb\u5316\u7f3a\u7701\u9875

StateConfig.apply {\nemptyLayout = R.layout.layout_empty\nloadingLayout = R.layout.layout_loading\nerrorLayout = R.layout.layout_error\n}\n
"},{"location":"auto-state.html#_2","title":"\u521b\u5efa","text":"

\u4f7f\u7528StateLayout\u5305\u88f9\u7684\u5185\u5bb9\u5373\u5185\u5bb9(content)

<com.drake.statelayout.StateLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\nxmlns:tools=\"http://schemas.android.com/tools\"\nandroid:layout_width=\"match_parent\"\nandroid:id=\"@+id/state\"\nandroid:layout_height=\"match_parent\"\ntools:context=\".ui.fragment.StateLayoutFragment\">\n<TextView\nandroid:id=\"@+id/tvFragment\"\nandroid:padding=\"32dp\"\nandroid:textStyle=\"bold\"\nandroid:layout_width=\"match_parent\"\nandroid:layout_height=\"match_parent\"\nandroid:text=\"\u5185\u5bb9\" />\n</com.drake.statelayout.StateLayout>\n
"},{"location":"auto-state.html#_3","title":"\u7f51\u7edc\u8bf7\u6c42","text":"
  1. \u8bf7\u6c42\u5f00\u59cb, \u663e\u793a\u52a0\u8f7d\u4e2d\u7f3a\u7701\u9875
  2. \u8bf7\u6c42\u6210\u529f, \u663e\u793a\u5185\u5bb9\u7f3a\u7701\u9875
  3. \u8bf7\u6c42\u5931\u8d25, \u663e\u793a\u9519\u8bef\u7f3a\u7701\u9875

state.onRefresh {\nscope {\ntvFragment.text = Get<String>(\"api\").await()\n}\n}.showLoading()\n

"},{"location":"auto-state.html#_4","title":"\u751f\u547d\u5468\u671f","text":"\u751f\u547d\u5468\u671f \u63cf\u8ff0 \u5f00\u59cb showLoading\u89e6\u53d1onRefresh, \u5f00\u59cb\u8bf7\u6c42 \u7ed3\u675f \u7f3a\u7701\u9875\u88ab\u9500\u6bc1, \u8bf7\u6c42\u81ea\u52a8\u53d6\u6d88"},{"location":"cache.html","title":"\u7f13\u5b58","text":""},{"location":"cache.html#_1","title":"\u7f13\u5b58\u4f18\u52bf","text":"
  1. \u9875\u9762\u79d2\u5f00
  2. \u51cf\u5c11\u670d\u52a1\u5668\u538b\u529b
  3. \u65e0\u7f51\u7edc\u53ef\u7528
"},{"location":"cache.html#net","title":"Net\u7f13\u5b58\u7279\u70b9","text":"
  1. \u7f13\u5b58\u4efb\u4f55\u8bf7\u6c42\u65b9\u5f0f
  2. \u7f13\u5b58\u4efb\u4f55\u6570\u636e, File/\u56fe\u7247/JSON/ProtoBuf\u7b49
  3. \u9650\u5236\u6700\u5927\u7f13\u5b58\u7a7a\u95f4
  4. \u4f7f\u7528DiskLruCache\u5b9e\u73b0, \u5220\u9664\u6700\u8fd1\u6700\u5c11\u4f7f\u7528
"},{"location":"cache.html#_2","title":"\u914d\u7f6e\u7f13\u5b58","text":"

\u4e0d\u914d\u7f6eCache\u662f\u4e0d\u4f1a\u542f\u7528\u7f13\u5b58\u7684

NetConfig.initialize(Api.HOST, this) {\n// Net\u652f\u6301Http\u7f13\u5b58\u534f\u8bae\u548c\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\n// \u5f53\u8d85\u8fc7maxSize\u6700\u5927\u503c\u4f1a\u6839\u636e\u6700\u8fd1\u6700\u5c11\u4f7f\u7528\u7b97\u6cd5\u6e05\u9664\u7f13\u5b58\u6765\u9650\u5236\u7f13\u5b58\u5927\u5c0f\ncache(Cache(cacheDir, 1024 * 1024 * 128))\n}\n

\u5224\u65ad\u54cd\u5e94\u6765\u81ea\u7f13\u5b58

\u5982\u679cResponse.cacheResponse\u4e0d\u4e3anull\u7684\u65f6, \u4ee3\u8868Response\u6765\u81ea\u672c\u5730\u7f13\u5b58

"},{"location":"cache.html#http","title":"Http\u7f13\u5b58\u534f\u8bae","text":"

OkHttp\u9ed8\u8ba4\u7684Http\u7f13\u5b58\u534f\u8bae\u63a7\u5236, \u8981\u6c42\u4ee5\u4e0b\u6761\u4ef6

  • Get\u8bf7\u6c42\u65b9\u5f0f
  • \u7f13\u5b58\u4f7f\u7528Url\u4e3akey, \u56e0\u6b64Url\u6539\u53d8\u4f1a\u8bfb\u4e0d\u5230\u7f13\u5b58
  • \u54cd\u5e94\u5934\u63a7\u5236\u7f13\u5b58: Cache-Control

\u901a\u8fc7setCacheControl\u53ef\u4ee5\u63a7\u5236Http\u7f13\u5b58\u534f\u8bae(\u539f\u7406\u662f\u6dfb\u52a0\u8bf7\u6c42\u5934)

scopeNetLife {\nPost<String>(\"api\") {\nsetCacheControl(CacheControl.FORCE_CACHE) // \u5f3a\u5236\u4f7f\u7528\u7f13\u5b58\n// setCacheControl(CacheControl.FORCE_NETWORK) // \u5f3a\u5236\u4f7f\u7528\u7f51\u7edc\n// setCacheControl(CacheControl.Builder().noStore().noCache().build()) // \u5b8c\u5168\u7981\u6b62\u8bfb\u53d6/\u5199\u5165\u7f13\u5b58\n}.await()\n}\n

\u5982\u679c\u65e0\u6cd5\u5b9e\u73b0Http\u6807\u51c6\u7f13\u5b58\u534f\u8bae, \u6216\u8981\u7f13\u5b58Get\u4ee5\u5916\u7684\u8bf7\u6c42\u65b9\u6cd5, \u53ef\u4ee5\u4f7f\u7528\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u6765\u7531\u5ba2\u6237\u7aef\u63a7\u5236\u7f13\u5b58

"},{"location":"cache.html#_3","title":"\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f","text":"

\u65e0\u8bba\u8bf7\u6c42\u662f\u5426\u5b58\u5728Http\u6807\u51c6\u7f13\u5b58\u534f\u8bae, \u5f53\u4f60\u8bbe\u7f6e\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u65f6\u5176\u4f1a\u65e0\u89c6Http\u6807\u51c6\u7f13\u5b58\u534f\u8bae

scopeNetLife {\nbinding.tvFragment.text =\nPost<String>(\"api\") {\nsetCacheMode(CacheMode.REQUEST_THEN_READ) // \u8bf7\u6c42\u7f51\u7edc\u5931\u8d25\u4f1a\u8bfb\u53d6\u7f13\u5b58, \u8bf7\u65ad\u7f51\u6d4b\u8bd5\n}.await()\n}\n
\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f \u63cf\u8ff0 READ \u53ea\u8bfb\u53d6\u7f13\u5b58, \u8bfb\u4e0d\u5230NoCacheException WRITE \u53ea\u8bf7\u6c42\u7f51\u7edc, \u5f3a\u5236\u5199\u5165\u7f13\u5b58 READ_THEN_REQUEST \u5148\u4ece\u7f13\u5b58\u8bfb\u53d6\uff0c\u5982\u679c\u5931\u8d25\u518d\u4ece\u7f51\u7edc\u8bfb\u53d6, \u5f3a\u5236\u5199\u5165\u7f13\u5b58 REQUEST_THEN_READ \u5148\u4ece\u7f51\u7edc\u8bfb\u53d6\uff0c\u5982\u679c\u5931\u8d25\u518d\u4ece\u7f13\u5b58\u8bfb\u53d6, \u5f3a\u5236\u5199\u5165\u7f13\u5b58"},{"location":"cache.html#key","title":"\u81ea\u5b9a\u7f13\u5b58Key","text":"

\u4ec5\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u6709\u6548, \u7f13\u5b58Key\u9ed8\u8ba4\u662f\u8bf7\u6c42\u65b9\u5f0f+URL\u540e\u4ea7\u751f\u7684sha1\u503c

\u5982\u679c\u8981\u7f13\u5b58\u533a\u522b\u8bf7\u6c42\u53c2\u6570, \u8bf7\u81ea\u5b9a\u4e49\u7f13\u5b58key

scopeNetLife {\nbinding.tvFragment.text =\nPost<String>(\"api\") {\nsetCacheMode(CacheMode.REQUEST_THEN_READ) // \u8bf7\u6c42\u7f51\u7edc\u5931\u8d25\u4f1a\u8bfb\u53d6\u7f13\u5b58, \u8bf7\u65ad\u7f51\u6d4b\u8bd5\nsetCacheKey(\"\u8bf7\u6c42\u70ed\u95e8\u4fe1\u606f\" + params) // \u5177\u4f53\u503c\u90fd\u884c\n}.await()\n}\n
"},{"location":"cache.html#_4","title":"\u7f13\u5b58\u6709\u6548\u671f","text":"
  1. \u4ec5\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u6709\u6548, \u6807\u51c6Http\u7f13\u5b58\u534f\u8bae\u9075\u5b88\u534f\u8bae\u672c\u8eab\u7684\u6709\u6548\u671f
  2. \u7f13\u5b58\u6709\u6548\u671f\u8fc7\u671f\u53ea\u662f\u8ba9\u7f13\u5b58\u65e0\u6548, \u4e0d\u4f1a\u7acb\u5373\u5220\u9664 \u6839\u636e(\u6700\u8fd1\u6700\u5c11\u4f7f\u7528)\u539f\u5219\u5728\u7f13\u5b58\u7a7a\u95f4\u8fbe\u5230\u914d\u7f6e\u503c\u65f6\u5220\u9664(\u5373\u4f7f\u7f13\u5b58\u6709\u6548\u671f\u672a\u5230)
scopeNetLife {\nbinding.tvFragment.text =\nPost<String>(\"api\") {\nsetCacheMode(CacheMode.REQUEST_THEN_READ) // \u8bf7\u6c42\u7f51\u7edc\u5931\u8d25\u4f1a\u8bfb\u53d6\u7f13\u5b58, \u8bf7\u65ad\u7f51\u6d4b\u8bd5\nsetCacheValidTime(1, TimeUnit.DAYS) // \u7f13\u5b58\u4ec5\u4e00\u5929\u5185\u6709\u6548\n}.await()\n}\n
"},{"location":"cache.html#_5","title":"\u9884\u89c8(\u7f13\u5b58+\u7f51\u7edc)","text":"

\u9884\u89c8\u53c8\u53ef\u4ee5\u7406\u89e3\u4e3a\u56de\u9000\u8bf7\u6c42, \u4e00\u822c\u7528\u4e8e\u79d2\u5f00\u9996\u9875\u6216\u8005\u56de\u9000\u52a0\u8f7d\u6570\u636e

scopeNetLife {\n// \u7136\u540e\u6267\u884c\u8fd9\u91cc(\u7f51\u7edc\u8bf7\u6c42)\nbinding.tvFragment.text = Get<String>(\"api\") {\nsetCacheMode(CacheMode.WRITE)\n}.await()\nLog.d(\"\u65e5\u5fd7\", \"\u7f51\u7edc\u8bf7\u6c42\")\n}.preview(true) {\n// \u5148\u6267\u884c\u8fd9\u91cc(\u4ec5\u8bfb\u7f13\u5b58), \u4efb\u4f55\u5f02\u5e38\u90fd\u89c6\u4e3a\u8bfb\u53d6\u7f13\u5b58\u5931\u8d25\nbinding.tvFragment.text = Get<String>(\"api\") {\nsetCacheMode(CacheMode.READ)\n}.await()\nLog.d(\"\u65e5\u5fd7\", \"\u8bfb\u53d6\u7f13\u5b58\")\n}\n

\u8fd9\u548c\u52a0\u8f7d\u4e24\u6b21\u6709\u4ec0\u4e48\u533a\u522b?

\u533a\u522b\u662fpreview\u53ef\u4ee5\u63a7\u5236\u4ee5\u4e0b\u884c\u4e3a

  1. breakError \u8bfb\u53d6\u7f13\u5b58\u6210\u529f\u540e\u4e0d\u518d\u5904\u7406\u9519\u8bef\u4fe1\u606f, \u9ed8\u8ba4false
  2. breakLoading \u8bfb\u53d6\u7f13\u5b58\u6210\u529f\u540e\u7ed3\u675f\u52a0\u8f7d\u52a8\u753b, \u9ed8\u8ba4true
"},{"location":"callback.html","title":"Callback","text":"

Net\u652f\u6301OkHttp\u7684\u539f\u6709\u7684\u961f\u5217\u8bf7\u6c42Callback

\u4e0d\u63a8\u8350

Callback\u5c5e\u4e8e\u63a5\u53e3\u56de\u8c03, \u5176\u4ee3\u7801\u5197\u4f59, \u4e14\u65e0\u6cd5\u652f\u6301\u5e76\u53d1\u8bf7\u6c42

Net.post(\"api\").enqueue(object : Callback {\noverride fun onFailure(call: Call, e: IOException) {\n}\noverride fun onResponse(call: Call, response: Response) {\n// \u6b64\u5904\u4e3a\u5b50\u7ebf\u7a0b\nval body = response.body?.string() ?: \"\u65e0\u6570\u636e\"\nrunMain {\n// \u6b64\u5904\u4e3a\u4e3b\u7ebf\u7a0b\nbinding.tvFragment.text = body\n}\n}\n})\n
"},{"location":"cancel.html","title":"\u53d6\u6d88\u8bf7\u6c42","text":"

\u90e8\u5206\u573a\u666f\u9700\u8981\u624b\u52a8\u53d6\u6d88\u8bf7\u6c42, \u4f8b\u5982\u53d6\u6d88\u4e0b\u8f7d

downloadScope = scopeNetLife {\n// \u4e0b\u8f7d\u6587\u4ef6\nval file = Get<File>(\"download\").await()\n}\ndownloadScope.cancel() // \u53d6\u6d88\u4e0b\u8f7d\n
"},{"location":"cancel.html#_1","title":"\u4efb\u610f\u4f4d\u7f6e\u53d6\u6d88","text":"

\u53d1\u8d77\u8bf7\u6c42\u65f6\u6307\u5b9aId

scopeNetLife {\ntvFragment.text = Get<String>(\"api\"){\nsetId(\"\u8bf7\u6c42\u7528\u6237\u4fe1\u606f\")\n}.await()\n}\n
\u6839\u636eID\u53d6\u6d88\u6839\u636eGroup\u53d6\u6d88
Net.cancelId(\"\u8bf7\u6c42\u7528\u6237\u4fe1\u606f\")\n
Net.cancelGroup(\"\u8bf7\u6c42\u5206\u7ec4\u540d\u79f0\")\n
"},{"location":"cancel.html#groupid","title":"Group\u548cId\u533a\u522b","text":"\u51fd\u6570 \u63cf\u8ff0 id \u8bf7\u6c42\u552f\u4e00Id, \u5b9e\u9645\u4e0a\u91cd\u590d\u4e5f\u884c, \u4f46\u662f\u53d6\u6d88\u8bf7\u6c42\u65f6\u904d\u5386\u5230\u6307\u5b9aId\u5c31\u4f1a\u7ed3\u675f\u904d\u5386 group \u5141\u8bb8\u591a\u4e2a\u8bf7\u6c42\u4f7f\u7528\u76f8\u540cgroup, \u5728\u53d6\u6d88\u8bf7\u6c42\u65f6\u4f1a\u904d\u5386\u6240\u6709\u5206\u7ec4\u7684\u8bf7\u6c42

\u4f5c\u7528\u57df\u7ed3\u675f\u8bf7\u6c42\u81ea\u52a8\u53d6\u6d88

\u5728scopeXX()\u4f5c\u7528\u57df\u4e2d\u53d1\u8d77\u8bf7\u6c42\u65f6\u4f1a\u9ed8\u8ba4\u4f7f\u7528\u5f53\u524d\u534f\u7a0b\u9519\u8bef\u5904\u7406\u5668\u4f5c\u4e3aGroup

setGroup(coroutineContext[CoroutineExceptionHandler])\n
\u5728\u4f5c\u7528\u57df\u7ed3\u675f\u65f6 \u4f1acancelGroup, \u6240\u4ee5\u5982\u679c\u4f60\u624b\u52a8\u6307\u5b9a\u5206\u7ec4\u4f1a\u5bfc\u81f4\u65e0\u6cd5\u81ea\u52a8\u53d6\u6d88

"},{"location":"config.html","title":"\u5168\u5c40\u914d\u7f6e","text":"

\u5168\u5c40\u914d\u7f6e\u5e94\u5728Application.onCreate\u4e2d\u914d\u7f6e

"},{"location":"config.html#_1","title":"\u521d\u59cb\u914d\u7f6e","text":"

\u4e24\u79cd\u65b9\u5f0f\u521d\u59cb\u914d\u7f6e, \u4e0d\u521d\u59cb\u5316\u4e5f\u80fd\u76f4\u63a5\u4f7f\u7528

Net\u521d\u59cb\u5316OkHttp\u6784\u9020\u5668\u521d\u59cb\u5316
NetConfig.initialize(Api.HOST, this) {\n// \u8d85\u65f6\u914d\u7f6e, \u9ed8\u8ba4\u662f10\u79d2, \u8bbe\u7f6e\u592a\u957f\u65f6\u95f4\u4f1a\u5bfc\u81f4\u7528\u6237\u7b49\u5f85\u8fc7\u4e45\nconnectTimeout(30, TimeUnit.SECONDS)\nreadTimeout(30, TimeUnit.SECONDS)\nwriteTimeout(30, TimeUnit.SECONDS)\nsetDebug(BuildConfig.DEBUG)\nsetConverter(SerializationConverter())\n}\n
val okHttpClientBuilder = OkHttpClient.Builder()\n.setDebug(BuildConfig.DEBUG)\n.setConverter(SerializationConverter())\n.addInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))\nNetConfig.initialize(Api.HOST, this, okHttpClientBuilder)\n

\u5f3a\u5236\u521d\u59cb\u5316

\u5982\u679c\u662f\u591a\u8fdb\u7a0b\u9879\u76ee(\u4f8b\u5982Xposed)\u5fc5\u987b\u521d\u59cb\u5316, \u56e0\u4e3a\u591a\u8fdb\u7a0b\u65e0\u6cd5\u81ea\u52a8\u6307\u5b9aContext

\u53ef\u914d\u7f6e\u9009\u9879 \u63cf\u8ff0 setDebug \u5f00\u542f\u65e5\u5fd7 setSSLCertificate \u914d\u7f6eHttps\u8bc1\u4e66 trustSSLCertificate \u4fe1\u4efb\u6240\u6709Https\u8bc1\u4e66 setConverter \u8f6c\u6362\u5668, \u5c06\u8bf7\u6c42\u7ed3\u679c\u8f6c\u4e3a\u4efb\u4f55\u7c7b\u578b setRequestInterceptor \u8bf7\u6c42\u62e6\u622a\u5668, \u5168\u5c40\u8bf7\u6c42\u5934/\u8bf7\u6c42\u53c2\u6570 setErrorHandler \u5168\u5c40\u9519\u8bef\u5904\u7406 setDialogFactory \u5168\u5c40\u5bf9\u8bdd\u6846

\u4fee\u6539\u914d\u7f6e

NetConfig\u5b58\u50a8\u6240\u6709\u5168\u5c40\u914d\u7f6e\u53d8\u91cf, \u53ef\u4ee5\u540e\u7eed\u4fee\u6539, \u4e14\u5927\u90e8\u5206\u652f\u6301\u5355\u4f8b\u6307\u5b9a\u914d\u7f6e

"},{"location":"config.html#_2","title":"\u91cd\u8bd5\u6b21\u6570","text":"

\u53ef\u4ee5\u6dfb\u52a0RetryInterceptor\u62e6\u622a\u5668\u5373\u53ef\u5b9e\u73b0\u5931\u8d25\u4ee5\u540e\u4f1a\u91cd\u8bd5\u6307\u5b9a\u6b21\u6570

\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8bbe\u7f6e\u8d85\u65f6\u65f6\u95f4\u5373\u53ef, OkHttp\u5185\u90e8\u4e5f\u6709\u91cd\u8bd5\u673a\u5236

NetConfig.initialize(Api.HOST, this) {\n// ... \u5176\u4ed6\u914d\u7f6e\naddInterceptor(RetryInterceptor(3)) // \u5982\u679c\u5168\u90e8\u5931\u8d25\u4f1a\u91cd\u8bd5\u4e09\u6b21\n}\n

\u957f\u65f6\u95f4\u963b\u788d\u7528\u6237\u4ea4\u4e92

OkHttp\u5185\u90e8\u4e5f\u6709\u91cd\u8bd5\u673a\u5236, \u5982\u679c\u8fd8\u6dfb\u52a0\u91cd\u8bd5\u62e6\u622a\u5668\u53ef\u80fd\u5bfc\u81f4\u8bf7\u6c42\u65f6\u95f4\u8fc7\u957f, \u957f\u65f6\u95f4\u963b\u788d\u7528\u6237\u4ea4\u4e92

"},{"location":"config.html#_3","title":"\u591a\u57df\u540d","text":"

\u6982\u5ff5\u6e90\u4e8eRetrofit(\u79f0\u4e3aBaseUrl), \u56e0\u4e3aRetrofit\u65e0\u6cd5\u4e8c\u6b21\u4fee\u6539\u8bf7\u6c42Host, \u4f46Net\u652f\u6301\u968f\u65f6\u4fee\u6539

\u4ee5\u4e0b\u4ecb\u7ecd\u4e09\u79cd\u4fee\u6539\u65b9\u5f0f

\u4fee\u6539Host\u6307\u5b9a\u5168\u8def\u5f84\u4f7f\u7528\u62e6\u622a\u5668
NetConfig.host = Api.HOST_2\n

\u6307\u5b9aPath(\u4f8b\u5982/api/index)\u4f1a\u81ea\u52a8\u548cNetConfig.host\u62fc\u63a5\u7ec4\u6210Url, \u4f46\u6307\u5b9a\u4ee5http/https\u5f00\u5934\u7684\u5168\u8def\u5f84\u5219\u76f4\u63a5\u4f5c\u4e3a\u8bf7\u6c42Url

scopeNetLife {\nval data = Get<String>(\"https://github.com/path\").await()\n}\n

\u8bf7\u6c42\u65f6\u6307\u5b9atag, \u7136\u540e\u62e6\u622a\u5668\u4e2d\u6839\u636etag\u5224\u65ad\u4fee\u6539host, \u62e6\u622a\u5668\u80fd\u4fee\u6539\u6240\u6709\u8bf7\u6c42/\u54cd\u5e94\u4fe1\u606f

scopeNetLife {\nval data = Get<String>(\"/api/index\", \"User\").await() // User\u5373\u4e3atag\n}\n// \u62e6\u622a\u5668\u4fee\u6539\u8bf7\u6c42URL\u4e0d\u505a\u4ecb\u7ecd\n
"},{"location":"config.html#_4","title":"\u7f51\u7edc\u5b89\u5168\u914d\u7f6e","text":"

Net\u81ea\u52a8\u542f\u7528\u7f51\u7edc\u914d\u7f6e\u6587\u4ef6, \u9ed8\u8ba4\u652f\u6301Http\u8bf7\u6c42, \u53ef\u81ea\u5b9a\u4e49

network_security_config.xml
<network-security-config>\n<base-config cleartextTrafficPermitted=\"true\" />\n</network-security-config>\n

\u65e0\u6cd5\u6253\u5305Apk

\u5f53\u5f00\u53d1\u8005\u81ea\u5b9a\u4e49\u4f7f\u7528\u975e\u540c\u540dnetwork_security_config\u65f6\u7f51\u7edc\u914d\u7f6e\u6587\u4ef6\u65f6\u4f1a\u65e0\u6cd5\u6253\u5305Apk

\u8bf7\u6dfb\u52a0tools:replace AndroidManifest.xml

<application\ntools:replace=\"android:networkSecurityConfig\">\n

"},{"location":"converter-customize.html","title":"\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668","text":"

Net\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668\u53ef\u652f\u6301\u4efb\u4f55\u6570\u636e\u7c7b\u578b, \u751a\u81f3Bitmap

\u6cdb\u578b\u548c\u8f6c\u6362\u5668\u5173\u7cfb

  1. \u5982\u679cPost<Model>, \u90a3\u4e48NetConverter.onConvert\u8fd4\u56de\u503c\u5fc5\u987b\u4e3aModel
  2. \u5982\u679cPost<Model?>, \u5141\u8bb8NetConverter.onConvert\u8fd4\u56de\u503c\u4e3anull
  3. \u5176\u4ed6\u60c5\u51b5\u8bf7\u629b\u51fa\u5f02\u5e38
scopeNetLife {\nval userList = Get<List<UserModel>>(\"list\") {\nconverter = GsonConverter()\n}.await()\n}\n

Net\u7531\u4e8e\u4f4e\u8026\u5408\u539f\u5219\u4e0d\u81ea\u5e26\u4efb\u4f55\u5e8f\u5217\u5316\u6846\u67b6

"},{"location":"converter-customize.html#_1","title":"\u8bbe\u7f6e\u8f6c\u6362\u5668","text":"\u5168\u5c40\u5355\u4f8b
NetConfig.initialize(Api.HOST, this) {\nsetConverter(SerializationConverter())\n}\n
scopeNetLife {\ntvFragment.text = Get<String>(\"api\"){\nconverter = SerializationConverter()\n}.await()\n}\n
"},{"location":"converter-customize.html#_2","title":"\u5e38\u89c1\u8f6c\u6362\u5668","text":"

\u5b9e\u73b0JSONConverter\u7684parseBody\u65b9\u6cd5\u4f7f\u7528\u81ea\u5b9a\u4e49\u5e8f\u5217\u5316\u6846\u67b6\u89e3\u6790

\u5e8f\u5217\u5316\u6846\u67b6 \u793a\u4f8b\u4ee3\u7801 \u63cf\u8ff0 kotlin-serialization SerializationConverter Kotlin\u5b98\u65b9\u5e8f\u5217\u5316\u6846\u67b6 kotlin-serialization ProtobufConverter Kotlin\u5b98\u65b9\u5e8f\u5217\u5316\u6846\u67b6 gson GsonConverter \u8c37\u6b4c\u5e8f\u5217\u5316\u6846\u67b6 fastJson FastJsonConverter \u963f\u91cc\u5df4\u5df4\u5e8f\u5217\u5316\u6846\u67b6 moshi MoshiConverter Square\u5e8f\u5217\u5316\u6846\u67b6"},{"location":"converter-customize.html#_3","title":"\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668","text":"

\u5b9e\u73b0NetConverter\u8fd4\u56de\u81ea\u5b9a\u4e49\u8bf7\u6c42\u7ed3\u679c

\u8f6c\u6362\u5668\u5b9e\u73b0\u975e\u5e38\u7b80\u5355 NetConverter.kt
interface NetConverter {\n@Throws(Throwable::class)\nfun <R> onConvert(succeed: Type, response: Response): R?\ncompanion object DEFAULT : NetConverter {\n/**\n         * \u8fd4\u56de\u7ed3\u679c\u5e94\u5f53\u7b49\u4e8e\u6cdb\u578b\u5bf9\u8c61, \u53ef\u7a7a\n         * @param succeed \u8bf7\u6c42\u8981\u6c42\u8fd4\u56de\u7684\u6cdb\u578b\u7c7b\u578b\n         * @param response \u8bf7\u6c42\u54cd\u5e94\u5bf9\u8c61\n         */\noverride fun <R> onConvert(succeed: Type, response: Response): R? {\nreturn when {\nsucceed === String::class.java && response.isSuccessful -> response.body?.string() as R\nsucceed === ByteString::class.java && response.isSuccessful -> response.body?.byteString() as R\nsucceed is GenericArrayType && succeed.genericComponentType === Byte::class.java && response.isSuccessful -> response.body?.bytes() as R\nsucceed === File::class.java && response.isSuccessful -> response.file() as R\nsucceed === Response::class.java -> response as R\nelse -> throw ConvertException(response, \"An exception occurred while converting the NetConverter.DEFAULT\")\n}\n}\n}\n}\n

\u8f6c\u6362\u5668\u4e2d\u53ef\u4ee5\u6839\u636e\u9700\u52a0\u4e0a\u89e3\u5bc6\u6570\u636e, token\u5931\u6548\u8df3\u8f6c\u767b\u5f55, \u9650\u5236\u591a\u7aef\u767b\u5f55\u7b49\u903b\u8f91

  1. \u65e5\u5fd7\u4fe1\u606f\u8f93\u51fa, \u8bf7\u9605\u8bfb\u65e5\u5fd7\u8bb0\u5f55\u5668
  2. \u8f6c\u6362\u5668\u4e2d\u629b\u51fa\u5f02\u5e38\u88ab\u5168\u5c40\u9519\u8bef\u5904\u7406\u6355\u83b7, \u8bf7\u9605\u8bfb\u5168\u5c40\u9519\u8bef\u5904\u7406
"},{"location":"converter-struct.html","title":"\u81ea\u5b9a\u4e49\u7ed3\u6784\u89e3\u6790","text":"

\u4e0a\u4e00\u7ae0\u8282\u4ecb\u7ecd\u5982\u4f55\u5e8f\u5217\u5316\u6846\u67b6\u89e3\u6790JSON, \u800c\u672c\u7ae0\u662f\u4ecb\u7ecd\u5982\u4f55\u5b9a\u4e49\u6620\u5c04\u6570\u636e\u7c7b

"},{"location":"converter-struct.html#json","title":"JSON","text":"

\u89e3\u6790\u63a5\u53e3\u8fd4\u56de\u7684\u5b8c\u6574JSON

JSON\u6570\u636e\u7c7b\u7f51\u7edc\u8bf7\u6c42
{\n\"code\":0,\n\"msg\":\"\u8bf7\u6c42\u6210\u529f\",\n\"data\": {\n\"name\": \"\u5f6d\u4e8e\u664f\",\n\"age\": 27,\n\"height\": 180\n}\n}\n
data class UserModel (\nvar code:Int,\nvar msg:String,\nvar data:Data,\n) {\ndata class Data(var name: String, var age: Int, var height: Int)\n}\n
scopeNetLife {\nval data = Get<UserModel>(\"api\").await().data\n}\n
\u4ee5\u4e0a\u8bbe\u8ba1\u4e0d\u5408\u7406

\u6b63\u5e38\u60c5\u51b5\u4e0bHttp\u72b6\u6001\u7801200\u65f6\u53ea\u8fd4\u56de\u6709\u6548\u6570\u636e

{\n\"name\": \"\u5f6d\u4e8e\u664f\",\n\"age\": 27,\n\"height\": 180\n}\n
\u4efb\u4f55\u975e\u6b63\u5e38\u6d41\u7a0b\u8fd4\u56de200\u72b6\u6001\u7801, \u4f8b\u5982400(\u9519\u8bef\u8bf7\u6c42)/401(\u8ba4\u8bc1\u5931\u8d25)
{\n\"code\":412302,\n\"msg\":\"\u5bc6\u7801\u9519\u8bef\",\n}\n
\u53ea\u8981\u8ba4\u4e3a\u9700\u8981\u89e3\u6790\u7ed3\u6784\u4f53\u60c5\u51b5\u4e0b, \u90fd\u5e94\u5c5e\u4e8e\u6b63\u5e38\u6d41\u7a0b

"},{"location":"converter-struct.html#_1","title":"\u5254\u9664\u65e0\u6548\u5b57\u6bb5","text":"

\u4ee5\u4e0b\u6f14\u793a\u4ec5\u89e3\u6790data\u5b57\u6bb5\u8fd4\u56de\u6709\u6548\u6570\u636e

\u6b64\u6570\u636e\u7c7b\u53ea\u9700\u8981\u5305\u542bdata\u503c

data class UserModel(var name: String, var age: Int, var height: Int)\n

\u8f6c\u6362\u5668\u53ea\u89e3\u6790data\u5b57\u6bb5

class GsonConvert : JSONConvert(code = \"code\", message = \"msg\", success = \"200\") {\nprivate val gson = GsonBuilder().serializeNulls().create()\noverride fun <S> String.parseBody(succeed: Type): S? {\nval data = JSONObject(this).getString(\"data\")\nreturn gson.fromJson(data, succeed)\n}\n}\n

\u8bf7\u6c42\u76f4\u63a5\u8fd4\u56de

scopeNetLife {\nval data = Get<UserModel>(\"api\").await()\n}\n
"},{"location":"converter-struct.html#_2","title":"\u4e0d\u89c4\u8303\u6570\u636e","text":"

\u63a8\u8350\u5728\u8f6c\u6362\u5668\u4e2d\u89e3\u6790\u4e4b\u524d\u5904\u7406\u597d\u6570\u636e

  1. \u5b57\u6bb5\u503c\u4e3a\"null\"\u800c\u4e0d\u662fnull, \u6216\u8005json\u5728\u5b57\u7b26\u4e32\u4e2d

     {\n\"data\": \"{ \"title\": \"name\" }\"\n\"msg\": \"null\"\n}\n
    \u66ff\u6362\u4e3a\u89c4\u8303\u5185\u5bb9
    json = bodyString.replace(\"\\\"{\", \"{\")\njson = bodyString.replace(\"}\\\"\", \"}\")\njson = bodyString.replace(\"\\\"null\\\"\", \"null\")\n

  2. \u670d\u52a1\u5668\u6210\u529f\u65f6\u4e0d\u8fd4\u56de\u6570\u636e\u6216\u8005\u8fd4\u56denull

    if (response.body == null || bodyString == \"null\") {\n\"{}\".bodyString.parseBody<R>(succeed)\n}\n

  3. \u5b57\u6bb5\u503c\u4e3anull, \u4f7f\u7528 kotlin-serialization \u81ea\u52a8\u4f7f\u7528\u5b57\u6bb5\u9ed8\u8ba4\u503c

    {\n\"msg\": null\n}\n

  4. \u5b57\u6bb5\u65e0\u5f15\u53f7\u6216\u5b57\u6bb5\u540d\u4e3a\u6570\u5b57, \u4f7f\u7528 kotlin-serialization \u53ef\u4ee5\u7981\u7528JSON\u89c4\u8303\u9650\u5236 \u6570\u5b57\u4f7f\u7528map\u89e3\u6790
     {\n\"data\": {\n23: 32\n}\n}\n
    \u7981\u7528JSON\u89c4\u8303\u9650\u5236
    val jsonDecoder = Json {\n// ...\nisLenient = true\n}\n
"},{"location":"converter-struct.html#_3","title":"\u6cdb\u578b\u6570\u636e\u7c7b","text":"

\u67d0\u4e9b\u5730\u533a\u5f88\u591a\u5f00\u53d1\u8005\u4e60\u60ef\u8fd9\u4e48\u4f7f\u7528, \u56e0\u4e3a\u4ed6\u4eec\u63a5\u53e3\u8fd4\u56de\u65e0\u5173\u5b57\u6bb5, \u4f46\u662f\u6280\u672f\u4e0d\u591f\u65e0\u6cd5\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668\u6765\u7b80\u5316\u53d6\u503c

\u6240\u4ee5\u4ed6\u4eec\u9009\u62e9\u66f4\u590d\u6742\u7684\u65b9\u5f0f: \u4f7f\u7528\u6cdb\u578b\u6765\u7b80\u5316

open class BaseResult<T> {\nvar code: Int = 0\nvar msg: String = \"\"\nvar data: T? = null\n}\nclass Result(var name: String) : BaseResult<Result>()\n

\u7528\u52a0\u6cd5\u89e3\u51b3\u95ee\u9898\u7684\u4eba\uff0c\u603b\u6709\u4eba\u613f\u610f\u7528\u4e58\u6cd5\u7ed9\u4f60\u7b54\u6848

"},{"location":"converter.html","title":"\u8f6c\u6362\u5668","text":"

Net\u652f\u6301\u8bf7\u6c42\u8fd4\u56de\u7684\u6570\u636e\u7c7b\u578b\u53d6\u51b3\u4e8e\u4f60\u7684\u8f6c\u6362\u5668\u5b9e\u73b0

"},{"location":"converter.html#getpathawait","title":"Get<\u4efb\u4f55\u5bf9\u8c61>(\"path\").await()","text":"

\u9ed8\u8ba4\u8f6c\u6362\u5668\u652f\u6301\u8fd4\u56de\u4ee5\u4e0b\u6570\u636e\u7c7b\u578b

\u51fd\u6570 \u63cf\u8ff0 String \u5b57\u7b26\u4e32 ByteArray \u5b57\u8282\u6570\u7ec4 ByteString \u66f4\u591a\u529f\u80fd\u7684\u5b57\u7b26\u4e32\u5bf9\u8c61 File \u6587\u4ef6\u5bf9\u8c61, \u8fd9\u79cd\u60c5\u51b5\u5176\u5b9e\u5e94\u5f53\u79f0\u4e3a\u4e0b\u8f7d\u6587\u4ef6 Response \u6240\u6709\u54cd\u5e94\u4fe1\u606f(\u54cd\u5e94\u4f53/\u54cd\u5e94\u5934/\u8bf7\u6c42\u4fe1\u606f\u7b49)

\u4f7f\u7528\u793a\u4f8b

scopeNetLife {\nGet<Response>(\"api\").await().headers(\"\u54cd\u5e94\u5934\u540d\u79f0\") // \u8fd4\u56de\u54cd\u5e94\u5934\n}\n
\u8f6c\u6362\u5668\u5b9e\u73b0\u975e\u5e38\u7b80\u5355 NetConverter.kt
interface NetConverter {\n@Throws(Throwable::class)\nfun <R> onConvert(succeed: Type, response: Response): R?\ncompanion object DEFAULT : NetConverter {\n/**\n         * \u8fd4\u56de\u7ed3\u679c\u5e94\u5f53\u7b49\u4e8e\u6cdb\u578b\u5bf9\u8c61, \u53ef\u7a7a\n         * @param succeed \u8bf7\u6c42\u8981\u6c42\u8fd4\u56de\u7684\u6cdb\u578b\u7c7b\u578b\n         * @param response \u8bf7\u6c42\u54cd\u5e94\u5bf9\u8c61\n         */\noverride fun <R> onConvert(succeed: Type, response: Response): R? {\nreturn when {\nsucceed === String::class.java && response.isSuccessful -> response.body?.string() as R\nsucceed === ByteString::class.java && response.isSuccessful -> response.body?.byteString() as R\nsucceed is GenericArrayType && succeed.genericComponentType === Byte::class.java && response.isSuccessful -> response.body?.bytes() as R\nsucceed === File::class.java && response.isSuccessful -> response.file() as R\nsucceed === Response::class.java -> response as R\nelse -> throw ConvertException(response, \"An exception occurred while converting the NetConverter.DEFAULT\")\n}\n}\n}\n}\n

\u5047\u8bbe\u4e0d\u652f\u6301\u4f60\u9700\u8981\u7684\u6570\u636e\u7c7b\u578b, \u4f8b\u5982JSON/ProtoBuf/Bitmap\u7b49\u8bf7\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668

"},{"location":"cookie.html","title":"Cookie","text":"

\u4f7f\u7528OkHttp\u7684CookieJar, Net\u63d0\u4f9b\u6301\u4e45\u5316CookiePersistentCookieJar

NetConfig.initialize(Api.HOST, this) {\n// \u6dfb\u52a0\u6301\u4e45\u5316Cookie\ncookieJar(PersistentCookieJar(this@App))\n}\n

\u53ef\u4ee5\u624b\u52a8\u589e\u5220Cookie

PersistentCookieJar \u63cf\u8ff0 addAll \u6dfb\u52a0Cookie getAll \u83b7\u53d6\u67d0\u4e2a\u57df\u540d\u7684\u6240\u6709Cookie remove \u5220\u9664\u67d0\u4e2a\u57df\u540d\u4e0b\u6240\u6709\u6216\u8005\u6307\u5b9a\u540d\u79f0\u7684Cookie clear \u5220\u9664\u5ba2\u6237\u7aef\u5168\u90e8Cookie

\u53ef\u901a\u8fc7\u5ba2\u6237\u7aef\u83b7\u53d6\u5230\u5df2\u914d\u7f6ecookieJar

(NetConfig.okHttpClient.cookieJar as? PersistentCookieJar)?.clear()\n

\u9694\u7eddCookies\u5171\u4eab

\u4e3aPersistentCookieJar\u6307\u5b9a\u4e0d\u540cdbName\u963b\u6b62\u4e0d\u540c\u7684\u5ba2\u6237\u7aef\u5171\u4eabCookies

"},{"location":"coroutine-request.html","title":"\u534f\u7a0b\u8bf7\u6c42","text":"

Net\u7684\u534f\u7a0b\u4f5c\u7528\u57df\u4f1a\u81ea\u52a8\u5904\u7406\u534f\u7a0b\u751f\u547d\u5468\u671f

\u5728\u4e0a\u7ae0\u8282\u5df2\u7ecf\u4ecb\u7ecd\u5982\u4f55\u53d1\u8d77\u5e76\u53d1\u7f51\u7edc\u8bf7\u6c42, \u8fd9\u91cc\u6f14\u793a\u540c\u65f6(\u5e76\u53d1)\u8bf7\u6c42\u4e00\u4e07\u6b21, \u7136\u540e\u53d6\u6d88\u5168\u90e8

val job = scopeNetLife {\nrepeat(10000) {\n// \u8fd9\u91cc\u5c06\u8fd4\u56de\u7684\u6570\u636e\u663e\u793a\u5728TextView\u4e0a\nlaunch {\ntvFragment.text = Get<String>(Api.PATH).await()\n}\n}\n}\n

\u7b49\u5f85\u4e94\u79d2\u540e\u53d6\u6d88\u8bf7\u6c42

thread {\nThread.sleep(5000) // \u7b49\u5f85\u4e94\u79d2\njob.cancel()\n}\n

Net\u4e3b\u8981\u4f7f\u7528\u534f\u7a0b\u8bf7\u6c42, \u4f46\u4e5f\u652f\u6301\u5176\u4ed6\u65b9\u5f0f\u53d1\u8d77\u8bf7\u6c42

  • \u540c\u6b65\u8bf7\u6c42
  • \u56de\u8c03\u8bf7\u6c42
  • \u534f\u7a0b\u8bf7\u6c42
"},{"location":"debounce.html","title":"\u641c\u7d22\u8282\u6d41","text":"

\u8282\u6d41

\u5728\u4e00\u5b9a\u65f6\u95f4\u95f4\u9694\u5185\uff0c\u53ea\u6267\u884c\u6700\u540e\u4e00\u6b21\u8bf7\u6c42, \u5ffd\u7565\u5176\u4ed6\u591a\u4f59\u7684\u8bf7\u6c42

\u641c\u7d22\u8f93\u5165\u6846\u4e00\u822c\u90fd\u662f\u8f93\u5165\u5b8c\u5173\u952e\u8bcd\u540e\u81ea\u52a8\u5f00\u59cb\u641c\u7d22

\u8fd9\u4e2a\u8fc7\u7a0b\u6d89\u53ca\u5230

  1. \u6bcf\u6b21\u53d8\u5316\u90fd\u641c\u7d22\u4f1a\u5bfc\u81f4\u670d\u52a1\u5668\u538b\u529b, \u5e94\u5728\u505c\u6b62\u8f93\u5165\u6ee1\u8db3\u4e00\u5b9a\u65f6\u95f4\u540e\u81ea\u52a8\u641c\u7d22
  2. \u5f53\u4ea7\u751f\u65b0\u7684\u641c\u7d22\u8bf7\u6c42\u540e\u5e94\u53d6\u6d88\u65e7\u8bf7\u6c42, \u4ee5\u9632\u6b62\u65e7\u6570\u636e\u8986\u76d6\u65b0\u6570\u636e
  3. \u5f53\u8f93\u5165\u5185\u5bb9\u6ca1\u6709\u53d8\u5316(\u4f8b\u590d\u5236\u7c98\u8d34\u91cd\u590d\u5185\u5bb9\u5230\u641c\u7d22\u6846)\u4e0d\u4f1a\u53d1\u8d77\u641c\u7d22\u8bf7\u6c42

var scope: CoroutineScope? = null\n// distinctUntilChanged \u8868\u793a\u8fc7\u6ee4\u6389\u91cd\u590d\u7ed3\u679c\nbinding.etInput.debounce().distinctUntilChanged().launchIn(this) {\nscope?.cancel() // \u53d1\u8d77\u65b0\u7684\u8bf7\u6c42\u524d\u53d6\u6d88\u65e7\u7684\u8bf7\u6c42, \u907f\u514d\u65e7\u6570\u636e\u8986\u76d6\u65b0\u6570\u636e\nscope = scopeNetLife { // \u4fdd\u5b58\u65e7\u7684\u8bf7\u6c42\u5230\u4e00\u4e2a\u53d8\u91cf\u4e2d\nbinding.tvFragment.text = \"\u8bf7\u6c42\u4e2d\"\nbinding.tvFragment.text = Get<String>(Api.TIME).await()\n}\n}\n

\u6307\u5b9a\u53c2\u6570\u8bbe\u7f6e\u8282\u6d41\u9600\u8d85\u65f6\u65f6\u95f4

fun EditText.debounce(timeoutMillis: Long = 800)\n

"},{"location":"download-file.html","title":"\u4e0b\u8f7d\u6587\u4ef6","text":"

\u6cdb\u578b\u6539\u4e3aFile\u5373\u53ef

scopeNetLife {\nval file = Get<File>(\"download\").await()\n}\n
"},{"location":"download-file.html#_1","title":"\u4e0b\u8f7d\u9009\u9879","text":"

\u4e30\u5bcc\u7684\u4e0b\u8f7d\u5b9a\u5236\u65b9\u6848, \u5e76\u4e14\u5728\u4e0d\u65ad\u66f4\u65b0

scopeNetLife {\nval file =\nGet<File>(\"https://github.com/liangjingkanji/Net/releases/latest/download/net-sample.apk\") {\nsetDownloadFileName(\"net.apk\")\nsetDownloadDir(requireContext().filesDir)\nsetDownloadMd5Verify()\n}.await()\n}\n
\u914d\u7f6e\u9009\u9879 \u63cf\u8ff0 addDownloadListener \u4e0b\u8f7d\u8fdb\u5ea6\u76d1\u542c\u5668 setDownloadFileName \u4e0b\u8f7d\u6587\u4ef6\u540d setDownloadDir \u4e0b\u8f7d\u76ee\u5f55 setDownloadMd5Verify \u4e0b\u8f7d\u6587\u4ef6MD5\u6821\u9a8c setDownloadFileNameConflict \u4e0b\u8f7d\u6587\u4ef6\u540c\u540d\u51b2\u7a81\u89e3\u51b3 setDownloadFileNameDecode \u6587\u4ef6\u540dUrl\u89e3\u7801\u4e2d\u6587 setDownloadTempFile \u4e34\u65f6\u6587\u4ef6\u540d"},{"location":"download-file.html#_2","title":"\u91cd\u590d\u4e0b\u8f7d","text":"

\u9632\u6b62\u91cd\u590d\u4e0b\u8f7d\u6709\u4ee5\u4e0b\u65b9\u5f0f

\u51fd\u6570 \u63cf\u8ff0 \u6587\u4ef6\u5224\u65ad \u5224\u65ad\u672c\u5730\u662f\u5426\u5b58\u5728\u540c\u540d\u6587\u4ef6 \u7f13\u5b58\u6a21\u5f0f \u5f00\u542f\u7f13\u5b58, \u5360\u7528\u8bbe\u5907\u4e24\u4efd\u7a7a\u95f4(\u7f13\u5b58/\u4e0b\u8f7d\u6210\u529f\u6587\u4ef6\u90fd\u5360\u7a7a\u95f4) MD5\u6821\u9a8c \u670d\u52a1\u5668\u8fd4\u56deContent-MD5, \u5ba2\u6237\u7aef\u5f00\u542fsetDownloadMd5Verify"},{"location":"error-global.html","title":"\u5168\u5c40\u6355\u83b7","text":"

\u53ef\u5b9e\u73b0NetErrorHandler\u63a5\u53e3\u6765\u76d1\u542c\u5168\u5c40\u9519\u8bef\u5904\u7406

\u521b\u5efa\u914d\u7f6e
class NetworkingErrorHandler : NetErrorHandler {\noverride fun onError(e: Throwable) {\n// .... \u5176\u4ed6\u9519\u8bef\nif (e is ResponseException && e.tag == 401) { // \u5224\u65ad\u5f02\u5e38\u4e3atoken\u5931\u6548\n// \u6253\u5f00\u767b\u5f55\u754c\u9762\u6216\u8005\u5f39\u767b\u5f55\u5931\u6548\u5bf9\u8bdd\u6846\n}\n}\n}\n
NetConfig.initialize(Api.HOST, this) {\nsetErrorHandler(NetworkingErrorHandler))\n}\n
NetErrorHandler \u4f7f\u7528\u573a\u666f \u89e6\u53d1\u4f4d\u7f6e onError \u5410\u53f8\u9519\u8bef\u4fe1\u606f scopeNetLife/scopeDialog onStateError \u8981\u6c42\u9519\u8bef\u663e\u793a\u5728\u7f3a\u7701\u9875 PageRefreshLayout.scope/StateLayout.scope

\u4ee5\u4e0b\u60c5\u51b5\u5168\u5c40\u9519\u8bef\u5904\u7406\u65e0\u6548

  1. \u5f02\u6b65\u4efb\u52a1\u4f5c\u7528\u57df(scope/scopeLife)\u53d1\u751f\u7684\u9519\u8bef
  2. \u4f7f\u7528\u5355\u4f8b\u9519\u8bef\u5904\u7406\u5904\u7406\u7684\u9519\u8bef
"},{"location":"error-single.html","title":"\u5355\u4f8b\u6355\u83b7","text":"

\u6355\u83b7\u5f53\u524d\u8bf7\u6c42/\u4f5c\u7528\u57df\u9519\u8bef, \u5c06\u4e0d\u4f1a\u518d\u88ab\u5168\u5c40\u9519\u8bef\u5904\u7406

"},{"location":"error-single.html#_1","title":"\u6355\u83b7\u8bf7\u6c42","text":"

\u4e00\u4e2a\u8bf7\u6c42\u53d1\u751f\u9519\u8bef\u4f1a\u53d6\u6d88\u5f53\u524d\u4f5c\u7528\u57df\u5185\u6240\u6709\u8bf7\u6c42, \u4f46\u5355\u72ec\u6355\u83b7\u540e\u4e0d\u4f1a\u518d\u5f71\u54cd\u5176\u4ed6\u8bf7\u6c42

\u4f8b\u5982

scopeNetLife {\nGet<String>(\"api\").await() // \u5931\u8d25\nGet<String>(\"api2\").await() // \u4e0a\u9762\u5931\u8d25, \u6b64\u5904\u4e5f\u4e0d\u4f1a\u6267\u884c\n}\n

\u6355\u83b7\u7b2c\u4e00\u4e2a\u534f\u7a0b\u907f\u514d\u7ec8\u6b62\u540e\u7eed\u6267\u884c

scopeNetLife {\ntry {\nGet<String>(\"api\").await() // \u5931\u8d25\n} catch(e:Exception) {\n}\nGet<String>(\"api2\").await() // \u4e0a\u9762\u5931\u8d25, \u6b64\u5904\u7ee7\u7eed\u6267\u884c\n}\n
\u5f53\u7136\u5982\u679c\u521b\u5efa\u4e0d\u540c\u7684\u4f5c\u7528\u57df\u5206\u522b\u8bf7\u6c42\u90a3\u662f\u4e92\u4e0d\u5f71\u54cd\u7684
scopeNetLife {\nGet<String>(\"api\").await() // \u5931\u8d25\n}\nscopeNetLife {\nGet<String>(\"api2\").await() // \u4e0a\u9762\u5931\u8d25, \u6b64\u5904\u5b8c\u5168\u4e0d\u53d7\u5f71\u54cd\n}\n

"},{"location":"error-single.html#_2","title":"\u6355\u83b7\u4f5c\u7528\u57df","text":"
scope {\nval data = Get<String>(\"http://www.thisiserror.com/\").await()\n}.catch {\n// \u534f\u7a0b\u5185\u53d1\u751f\u9519\u8bef\u56de\u8c03, it\u4e3a\u5f02\u5e38\u5bf9\u8c61\n}.finally {\n// \u534f\u7a0b\u6267\u884c\u5b8c\u6bd5\u56de\u8c03(\u4e0d\u8bba\u6210\u8d25), it\u4e3a\u5f02\u5e38\u5bf9\u8c61\n}\n
\u51fd\u6570 \u533a\u522b catch \u53d1\u751f\u9519\u8bef\u540e\u56de\u8c03, \u53d6\u6d88\u4e0d\u56de\u8c03 \u4e0d\u4f1a\u518d\u6267\u884c\u5168\u5c40\u9519\u8bef\u5904\u7406, \u53ef\u4f7f\u7528handleError\u518d\u6b21\u4f20\u9012\u7ed9\u5168\u5c40 finally \u6267\u884c\u5b8c\u6bd5\u56de\u8c03(\u4e0d\u8bba\u6210\u8d25), \u53d6\u6d88\u4f5c\u7528\u57df\u65f6it\u4e3aCancellationException \u6267\u884c\u5168\u5c40\u9519\u8bef\u5904\u7406"},{"location":"error-throws.html","title":"\u81ea\u5b9a\u4e49\u5f02\u5e38\u629b\u51fa","text":"

\u4ee5\u4e0b\u4e3aNet\u5185\u90e8\u629b\u51fa\u7684\u5f02\u5e38\u5bf9\u8c61

\u5f02\u5e38 \u63cf\u8ff0 NetException \u672a\u77e5\u7684\u7f51\u7edc\u5f02\u5e38, \u4e00\u822c\u60c5\u51b5\u5e94\u5f53\u7ee7\u627f\u4ed6\u6765\u521b\u5efa\u81ea\u5b9a\u4e49\u7684\u7f51\u7edc\u5f02\u5e38 HttpFailureException Http\u8bf7\u6c42\u9519\u8bef, Http\u8bf7\u6c42\u5931\u8d25(onFailure) HttpResponseException Http\u8bf7\u6c42\u6210\u529f\u540e\u53d1\u751f\u7684\u9519\u8bef, Http\u8bf7\u6c42\u6210\u529f\u4f46\u53d1\u751f\u5f02\u5e38(onResponse) URLParseException \u5730\u5740\u9519\u8bef NetUnknownHostException \u57df\u540d\u9519\u8bef NetSocketTimeoutException \u8fde\u63a5\u8d85\u65f6 NetConnectException \u8fde\u63a5\u7f51\u7edc\u5931\u8d25, \u8bbe\u5907\u672a\u5f00\u542f\u7f51\u7edc NetworkingException \u5f53\u524d\u7f51\u7edc\u4e0d\u53ef\u7528, Net\u5e76\u672a\u5b9e\u73b0 DownloadFileException \u4e0b\u8f7d\u6587\u4ef6\u5f02\u5e38 ConvertException \u89e3\u6790\u9519\u8bef, NetConvert\u4e2d\u53d1\u751f\u7684\u672a\u6355\u83b7\u5f02\u5e38\u90fd\u7b97\u89e3\u6790\u9519\u8bef RequestParamsException \u8bf7\u6c42\u53c2\u6570\u9519\u8bef 400 - 499 \u8303\u56f4\u5185\u9519\u8bef\u7801 ServerResponseException \u670d\u52a1\u5668\u9519\u8bef 500 - 599 \u8303\u56f4\u5185\u9519\u8bef\u7801 ResponseException \u9519\u8bef\u7801\u5f02\u5e38, \u4e00\u822c\u5e94\u7528\u4e8e\u540e\u7aef\u8fd4\u56de\u7684\u9519\u8bef\u7801\u548c\u5176\u5b9a\u4e49\u7684\u6210\u529f\u7801\u4e0d\u5339\u914d NullPointerException \u7a7a\u6307\u9488, \u4e00\u822c\u662f\u5728\u4f5c\u7528\u57df\u5185\u64cd\u4f5c\u4e00\u4e2a\u7a7a\u7684\u5bf9\u8c61

NetworkingException

\u7531\u4e8e\u8c37\u6b4c\u9650\u5236Net\u65e0\u6cd5\u5224\u65ad\u7f51\u7edc\u662f\u5426\u53ef\u7528, \u8bf7\u5f00\u53d1\u8005\u81ea\u5df1\u629b\u51fa

"},{"location":"error-throws.html#_1","title":"\u81ea\u5b9a\u4e49\u5f02\u5e38","text":"

\u5728\u8f6c\u6362\u5668(NetConverter)\u6216\u62e6\u622a\u5668(Interceptor)\u4e2d\u629b\u51fa\u4efb\u4f55\u5f02\u5e38 \u8be5\u5f02\u5e38\u5bf9\u8c61\u90fd\u4f1a\u88ab\u5355\u4f8b\u6216\u5168\u5c40\u9519\u8bef\u5904\u7406\u63a5\u6536, \u53ef\u7528\u4e8e\u5224\u65ad\u5f02\u5e38\u4fe1\u606f\u505a\u7279\u6b8a\u5904\u7406 (\u4f8b\u5982Token\u5931\u6548\u5219\u8df3\u8f6c\u5230\u767b\u5f55\u9875\u9762)

\u8f6c\u6362\u53d1\u751f\u5f02\u5e38

NetConverter\u4e2d\u7684\u6240\u6709\u5f02\u5e38\u9664\u975e\u662fNetException\u5b50\u7c7b\u5426\u5219\u90fd\u5c06\u88abConvertException\u5305\u88f9 \u5373\u6355\u83b7\u7684\u662fConvertException, cause\u624d\u4e3a\u5b9e\u9645\u629b\u51fa\u5f02\u5e38

"},{"location":"error-throws.html#_2","title":"\u5f02\u5e38\u4f20\u9012\u5b57\u6bb5","text":"

Net\u81ea\u5e26\u5f02\u5e38\u4f1a\u6709\u7c7b\u578b\u4e3aAny\u7684\u5b57\u6bb5tag, \u53ef\u7528\u4f20\u9012\u5bf9\u8c61\u7528\u4e8e\u5224\u65ad\u9519\u8bef\u5904\u7406

\u4f8b\u5982ResponseException\u5e38\u7528\u4e8e\u4f5c\u4e3a\u8bf7\u6c42\u670d\u52a1\u5668\u6210\u529f\u4f46\u540e\u7aef\u4e1a\u52a1\u9519\u8bef, \u7136\u540etag\u4e3a\u4f20\u9012\u7684\u9519\u8bef\u7801

\u793a\u4f8b\u4ee3\u7801

\u8f6c\u6362\u5668\u629b\u51fa\u5f02\u5e38\u5168\u5c40\u9519\u8bef\u5904\u7406\u5f02\u5e38
class SerializationConverter(\nval success: String = \"0\",\nval code: String = \"code\",\nval message: String = \"msg\"\n) : NetConverter {\noverride fun <R> onConvert(succeed: Type, response: Response): R? {\ntry {\nreturn NetConverter.onConvert<R>(succeed, response)\n} catch (e: ConvertException) {\nval code = response.code\nwhen {\ncode in 200..299 -> { // \u8bf7\u6c42\u6210\u529f\n// ... \u5047\u8bbeToken\u5931\u6548. \u540e\u7aef\u8fd4\u56de\u4e1a\u52a1\u9519\u8bef\u7801 srvCode = 401\nthrow ResponseException(response, errorMessage, tag = srvCode) // \u5c06\u4e1a\u52a1\u9519\u8bef\u7801\u4f5c\u4e3atag\u4f20\u9012\n}\ncode in 400..499 -> throw RequestParamsException(response, code.toString()) // \u8bf7\u6c42\u53c2\u6570\u9519\u8bef\ncode >= 500 -> throw ServerResponseException(response, code.toString()) // \u670d\u52a1\u5668\u5f02\u5e38\u9519\u8bef\nelse -> throw ConvertException(response)\n}\n}\n}\n}\n
class NetworkingErrorHandler : NetErrorHandler {\noverride fun onError(e: Throwable) {\n// .... \u5176\u4ed6\u9519\u8bef\nif (e is ResponseException && e.tag == 401) { // \u5224\u65ad\u5f02\u5e38\u4e3atoken\u5931\u6548\n// \u6253\u5f00\u767b\u5f55\u754c\u9762\u6216\u8005\u5f39\u767b\u5f55\u5931\u6548\u5bf9\u8bdd\u6846\n}\n}\n}\n
"},{"location":"error-tip.html","title":"\u81ea\u5b9a\u4e49\u9519\u8bef\u63d0\u793a","text":"

\u7f51\u7edc\u9519\u8bef\u63d0\u793a

\u7f51\u7edc\u8bf7\u6c42\u53d1\u751f\u9519\u8bef\u4e00\u5b9a\u8981\u63d0\u793a\u7ed9\u7528\u6237, \u5e76\u4e14\u662f\u53ef\u8bfb\u8bed\u4e49\u53e5

\u4fee\u6539\u9ed8\u8ba4\u5410\u53f8\u9519\u8bef\u6587\u672c\u6216\u56fd\u9645\u5316\u53c2\u8003\u4ee5\u4e0b\u65b9\u5f0f

"},{"location":"error-tip.html#_1","title":"\u521b\u5efa\u591a\u8bed\u8a00","text":"

\u9519\u8bef\u63d0\u793a\u6587\u672c\u88ab\u5b9a\u4e49\u5728strings.xml, \u5728\u9879\u76ee\u4e2d\u521b\u5efa\u540c\u540dname\u53ef\u590d\u5199Net\u5b9a\u4e49\u7684\u6587\u672c

\u56fd\u9645\u5316\u8bed\u8a00\u5219\u9700\u521b\u5efa\u591a\u8bed\u8a00values, \u4f8b\u5982\u82f1\u8bed\u662fvalues-en\u4e0b\u521b\u5efastrings.xml

\u9519\u8bef\u6587\u672c
    <!--\u7f51\u7edc\u8bf7\u6c42\u5f02\u5e38-->\n<string name=\"net_connect_error\">\u8fde\u63a5\u7f51\u7edc\u5931\u8d25</string>\n<string name=\"net_url_error\">\u8bf7\u6c42\u8d44\u6e90\u5730\u5740\u9519\u8bef</string>\n<string name=\"net_host_error\">\u65e0\u6cd5\u627e\u5230\u6307\u5b9a\u670d\u52a1\u5668\u4e3b\u673a</string>\n<string name=\"net_connect_timeout_error\">\u8fde\u63a5\u670d\u52a1\u5668\u8d85\u65f6\uff0c%s</string>\n<string name=\"net_download_error\">\u4e0b\u8f7d\u8fc7\u7a0b\u53d1\u751f\u9519\u8bef</string>\n<string name=\"net_no_cache_error\">\u8bfb\u53d6\u7f13\u5b58\u5931\u8d25</string>\n<string name=\"net_parse_error\">\u89e3\u6790\u6570\u636e\u65f6\u53d1\u751f\u5f02\u5e38</string>\n<string name=\"request_failure\">\u8bf7\u6c42\u5931\u8d25</string>\n<string name=\"net_request_error\">\u8bf7\u6c42\u53c2\u6570\u9519\u8bef</string>\n<string name=\"net_server_error\">\u670d\u52a1\u54cd\u5e94\u9519\u8bef</string>\n<string name=\"net_null_error\">\u53d1\u751f\u7a7a\u5f02\u5e38</string>\n<string name=\"net_error\">\u672a\u77e5\u7f51\u7edc\u9519\u8bef</string>\n<string name=\"net_other_error\">\u672a\u77e5\u9519\u8bef</string>\n<string name=\"no_error_message\">\u65e0\u9519\u8bef\u4fe1\u606f</string>\n<!--\u5bf9\u8bdd\u6846-->\n<string name=\"net_dialog_msg\">\u52a0\u8f7d\u4e2d</string>\n
"},{"location":"error-tip.html#neterrorhandler","title":"\u521b\u5efaNetErrorHandler","text":"

\u4f7f\u7528\u81ea\u5b9a\u4e49\u5168\u5c40\u9519\u8bef\u5904\u7406\u53ef\u5b8c\u5168\u4fee\u6539, \u53ef\u4e0d\u63d0\u793a\u9519\u8bef\u6216\u9644\u4e0a\u9519\u8bef\u4fe1\u606f

\u5168\u5c40\u9519\u8bef\u5904\u7406
fun onError(e: Throwable) {\nval message = when (e) {\nis UnknownHostException -> NetConfig.app.getString(R.string.net_host_error)\nis URLParseException -> NetConfig.app.getString(R.string.net_url_error)\nis NetConnectException -> NetConfig.app.getString(R.string.net_connect_error)\nis NetSocketTimeoutException -> NetConfig.app.getString(\nR.string.net_connect_timeout_error,\ne.message\n)\nis DownloadFileException -> NetConfig.app.getString(R.string.net_download_error)\nis ConvertException -> NetConfig.app.getString(R.string.net_parse_error)\nis RequestParamsException -> NetConfig.app.getString(R.string.net_request_error)\nis ServerResponseException -> NetConfig.app.getString(R.string.net_server_error)\nis NullPointerException -> NetConfig.app.getString(R.string.net_null_error)\nis NoCacheException -> NetConfig.app.getString(R.string.net_no_cache_error)\nis ResponseException -> e.message\nis HttpFailureException -> NetConfig.app.getString(R.string.request_failure)\nis NetException -> NetConfig.app.getString(R.string.net_error)\nelse -> NetConfig.app.getString(R.string.net_other_error)\n}\nNet.debug(e)\nTipUtils.toast(message)\n}\n
"},{"location":"error.html","title":"\u9519\u8bef\u5904\u7406","text":"

Net\u6709\u5b8c\u5584\u7684\u9519\u8bef\u5904\u7406\u673a\u5236, \u5177\u5907\u6355\u83b7\u5f02\u5e38/\u53d6\u6d88\u8bf7\u6c42/\u9519\u8bef\u63d0\u793a/\u8ffd\u8e2a\u94fe\u8def

\u6536\u96c6\u7f51\u7edc\u65e5\u5fd7

\u5728Net\u4f5c\u7528\u57df\u5185\u53d1\u751f\u7684\u5f02\u5e38\u90fd\u4f1a\u88ab\u5168\u5c40\u9519\u8bef\u5904\u7406\u6355\u83b7, \u53ef\u4ee5\u5c06\u5176\u7b5b\u9009\u4e0a\u4f20\u65e5\u5fd7

\u4ee5\u4e0b\u4f4d\u7f6e\u629b\u51fa\u5f02\u5e38\u4f1a\u88ab\u6355\u83b7

\u51fd\u6570 \u63cf\u8ff0 \u4f5c\u7528\u57df scopeXX\u4ee3\u7801\u5757\u4e2d \u62e6\u622a\u5668 Interceptor/RequestInterceptor \u8f6c\u6362\u5668 NetConverter

\u5982\u679c\u6355\u83b7\u5230\u9519\u8bef\u9ed8\u8ba4\u4f1a\u6267\u884c\u4ee5\u4e0b\u64cd\u4f5c

  1. Logcat\u8f93\u51fa\u5f02\u5e38\u5806\u6808\u4fe1\u606f, \u81ea\u5b9a\u4e49\u5f02\u5e38\u629b\u51fa
  2. Toast\u663e\u793a\u9519\u8bef\u6587\u672c, \u81ea\u5b9a\u4e49\u9519\u8bef\u63d0\u793a

\u6355\u83b7\u4e0d\u5230\u5f02\u5e38

\u5982\u679c\u8bf7\u6c42\u672a\u6267\u884cawait(), \u90a3\u4e48\u5373\u4f7f\u53d1\u751f\u9519\u8bef\u4e5f\u4e0d\u4f1a\u88ab\u6355\u83b7\u5230

\u81ea\u5b9a\u4e49\u8bf7\u9605\u8bfb\u5168\u5c40\u9519\u8bef\u5904\u7406

"},{"location":"fastest.html","title":"\u6700\u5feb\u8bf7\u6c42\u7ed3\u679c","text":"

\u591a\u4e2a\u8bf7\u6c42\u5e76\u53d1\u6267\u884c

  1. \u5f53\u67d0\u4e2a\u8bf7\u6c42\u6210\u529f\u65f6, \u5269\u4f59\u8bf7\u6c42\u5c06\u88ab\u81ea\u52a8\u53d6\u6d88
  2. \u5168\u90e8\u9519\u8bef\u65f6\u5219\u4f1a\u629b\u51fa\u6700\u540e\u4e00\u4e2a\u8bf7\u6c42\u9519\u8bef\u4f5c\u4e3a\u7ed3\u679c

\u5f02\u5e38\u4fe1\u606f

\u5148\u5931\u8d25\u7684\u8bf7\u6c42\u9519\u8bef\u4f1a\u88ab\u5ffd\u7565, \u4f46LogCat\u4f9d\u7136\u4f1a\u8f93\u51fa\u5f02\u5e38

\u793a\u4f8b

scopeNetLife {\n// \u540c\u65f6\u53d1\u8d77\u56db\u4e2a\u7f51\u7edc\u8bf7\u6c42\nval deferred = Get<String>(\"api0\") // \u9519\u8bef\u63a5\u53e3\nval deferred1 = Get<String>(\"api1\") // \u9519\u8bef\u63a5\u53e3\nval deferred2 = Get<String>(\"api\")\nval deferred3 = Post<String>(\"api\")\n// \u53ea\u8fd4\u56de\u6700\u5feb\u7684\u8bf7\u6c42\u7ed3\u679c\ntvFragment.text = fastest(deferred, deferred1, deferred2, deferred3)\n}\n

"},{"location":"fastest.html#_1","title":"\u53d6\u6d88\u5269\u4f59","text":"

\u4e0a\u9762\u7684\u793a\u4f8b\u4e0d\u4f1a\u5728\u83b7\u53d6\u5230\u7ed3\u679c\u540e\u53d6\u6d88\u5269\u4f59\u8bf7\u6c42, \u9700\u8bbe\u7f6e\u540c\u4e00\u8bf7\u6c42\u5206\u7ec4\u624d\u53ef\u4ee5

scopeNetLife {\n// \u540c\u65f6\u53d1\u8d77\u56db\u4e2a\u7f51\u7edc\u8bf7\u6c42\nval deferred2 = Get<String>(\"api\") { setGroup(\"\u521d\u59cb\u5316\") }\nval deferred3 = Post<String>(\"api\") { setGroup(\"\u521d\u59cb\u5316\") }\nval deferred = Get<String>(\"api0\") { setGroup(\"\u521d\u59cb\u5316\") } // \u9519\u8bef\u63a5\u53e3\nval deferred1 = Get<String>(\"api1\") { setGroup(\"\u521d\u59cb\u5316\") } // \u9519\u8bef\u63a5\u53e3\n// \u53ea\u8fd4\u56de\u6700\u5feb\u7684\u8bf7\u6c42\u7ed3\u679c\ntvFragment.text = fastest(listOf(deferred, deferred1, deferred2, deferred3), \"\u521d\u59cb\u5316\")\n}\n
"},{"location":"fastest.html#_2","title":"\u7c7b\u578b\u4e0d\u4e00\u81f4","text":"

\u5f53\u9700\u8981\u8fd4\u56de\u7ed3\u679c, \u4f46\u591a\u63a5\u53e3\u8fd4\u56de\u6570\u636e\u7c7b\u578b\u4e0d\u540c, \u4f7f\u7528transform\u8f6c\u6362\u4e3a\u540c\u4e00\u7c7b\u578b\u7ed3\u679c

scopeNetLife {\nval fastest = Post<String>(\"api\").transform {\nLog.d(\"\u65e5\u5fd7\", \"Post\") // \u5982\u679c\u8be5\u63a5\u53e3\u6700\u5feb\u5219\u4f1a\u56de\u8c03\u8fd9\u91cc\nit // \u8fd9\u91cc\u53ef\u4ee5\u8fd4\u56de\u5176\u4ed6\u6570\u636e\u7ed3\u679c\n}\nval fastest2 = Get<String>(\"api\").transform {\nLog.d(\"\u65e5\u5fd7\", \"Get\") // \u5982\u679c\u8be5\u63a5\u53e3\u6700\u5feb\u5219\u4f1a\u56de\u8c03\u8fd9\u91cc\nit\n}\ntvFragment.text = fastest(fastest, fastest2)\n}\n

\u53ea\u6709\u6700\u5feb\u8fd4\u56de\u7ed3\u679c\u7684\u7f51\u7edc\u8bf7\u6c42(\u6216\u5f02\u6b65\u4efb\u52a1)\u7684transform\u56de\u8c03\u624d\u4f1a\u88ab\u6267\u884c\u5230

"},{"location":"fastest.html#_3","title":"\u6355\u83b7\u9519\u8bef","text":"
scopeNetLife {\nval task = Get<String>(\"api2\")\nval task1 = Get<String>(\"api2\")\nval task2 = Get<String>(\"api2\")\nval data = try {\nfastest(listOf(task, task1, task2))\n// \u5f53task/task1/task2\u5168\u90e8\u9519\u8bef\u540e\u624d\u5e76\u53d1\u6267\u884cbackupTask/backupTask1\n} catch (e: Exception) {\nval backupTask = Get<String>(\"api2\")\nval backupTask1 = Get<String>(\"api\")\nfastest(listOf(backupTask, backupTask1))\n}\n}\n
"},{"location":"https.html","title":"Https\u8bc1\u4e66","text":"

Net\u53ef\u5feb\u901f\u914d\u7f6eHttps\u8bc1\u4e66, \u6216\u8005\u4f7f\u7528OkHttp\u7684\u65b9\u5f0f

"},{"location":"https.html#ca","title":"\u4f7f\u7528CA\u8bc1\u4e66","text":"

Https\u5982\u679c\u4f7f\u7528\u7684CA\u8bc1\u4e66, \u4e0d\u9700\u8981\u4efb\u4f55\u914d\u7f6e\u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee

scopeNetLife {\ntvFragment.text = Get<String>(Api.PATH).await()\n}\n
"},{"location":"https.html#_1","title":"\u4fe1\u4efb\u6240\u6709\u8bc1\u4e66","text":"

\u4fe1\u4efb\u6240\u6709\u8bc1\u4e66\u53ef\u4ee5\u89e3\u51b3\u65e0\u6cd5\u8bbf\u95ee\u79c1\u6709\u8bc1\u4e66\u7684Https\u5730\u5740\u95ee\u9898

\u5168\u5c40\u914d\u7f6e\u5355\u4f8b\u914d\u7f6e
NetConfig.initialize(Api.HOST, this){\ntrustSSLCertificate() // \u4fe1\u4efb\u6240\u6709\u8bc1\u4e66\n}\n
scopeNetLife {\nGet<String>(Api.PATH){\nsetClient {\ntrustSSLCertificate()\n}\n}.await()\n}\n
"},{"location":"https.html#_2","title":"\u5bfc\u5165\u8bc1\u4e66","text":"

\u79c1\u6709\u8bc1\u4e66\u53ef\u4ee5\u653e\u5230\u4efb\u4f55\u4f4d\u7f6e, \u53ea\u8981\u8bfb\u53d6\u5230InputStream\u6d41\u5bf9\u8c61\u5373\u53ef

\u5168\u5c40\u914d\u7f6e\u5355\u4f8b\u914d\u7f6e
NetConfig.initialize(Api.HOST, this) {\nval privateCertificate = resources.assets.open(\"https.certificate\")\nsetSSLCertificate(privateCertificate)\n}\n
scopeNetLife {\nGet<String>(Api.PATH) {\nsetClient {\nval privateCertificate = resources.assets.open(\"https.certificate\") // \u8fd9\u91cc\u7684\u8bc1\u4e66\u662f\u653e\u5230\u5e94\u7528\u7684\u8d44\u4ea7\u76ee\u5f55\u4e0b\nsetSSLCertificate(privateCertificate)\n}\n}.await()\n}\n
"},{"location":"interceptor.html","title":"\u62e6\u622a\u5668","text":"

\u6839\u636e\u4f7f\u7528\u573a\u666f\u9009\u62e9

  1. Interceptor: \u652f\u6301\u4e09\u65b9OkHttp\u62e6\u622a\u5668\u7ec4\u4ef6, \u5141\u8bb8\u4fee\u6539\u8bf7\u6c42/\u54cd\u5e94\u4fe1\u606f, \u53ef\u4ee5\u8f6c\u53d1\u8bf7\u6c42
  2. RequestInterceptor: Net\u72ec\u6709\u7684\u8f7b\u91cf\u7ea7\u62e6\u622a\u5668, \u5141\u8bb8\u4fee\u6539\u5168\u5c40\u8bf7\u6c42\u5934/\u8bf7\u6c42\u53c2\u6570, \u65e0\u6cd5\u8f6c\u53d1\u8bf7\u6c42

\u7981\u6b62\u968f\u610f\u5c01\u88c5

\u4e0d\u5e94\u4e3a\u5168\u5c40\u53c2\u6570/\u52a0\u5bc6\u7b49\u5c01\u88c5\u8bf7\u6c42\u65b9\u6cd5, \u5e94\u81ea\u5b9a\u4e49\u62e6\u622a\u5668/\u8f6c\u6362\u5668\u6765\u5b9e\u73b0, \u5e38\u89c1\u62e6\u622a\u5668\u793a\u4f8b

"},{"location":"interceptor.html#_1","title":"\u62e6\u622a\u5668","text":"

\u6dfb\u52a0\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\naddInterceptor(RefreshTokenInterceptor())\n}\n

\u6f14\u793a\u5ba2\u6237\u7aef\u81ea\u52a8\u5237\u65b0token\u7684\u62e6\u622a\u5668

/**\n * \u6f14\u793a\u5982\u4f55\u81ea\u52a8\u5237\u65b0token\u4ee4\u724c\n */\nclass RefreshTokenInterceptor : Interceptor {\noverride fun intercept(chain: Interceptor.Chain): Response {\nval request = chain.request()\nval response = chain.proceed(request) // \u5982\u679ctoken\u5931\u6548\nreturn synchronized(RefreshTokenInterceptor::class.java) {\nif (response.code == 401 && UserConfig.isLogin && !request.url.pathSegments.contains(\"token\")) {\nval json = Net.get(\"token\").execute<String>() // \u540c\u6b65\u5237\u65b0token\nUserConfig.token = JSONObject(json).optString(\"token\")\nchain.proceed(request)\n} else {\nresponse\n}\n}\n}\n}\n
"},{"location":"interceptor.html#_2","title":"\u8bf7\u6c42\u62e6\u622a\u5668","text":"

\u8f7b\u91cf\u7ea7\u62e6\u622a\u5668(RequestInterceptor), \u5176Api\u66f4\u9002\u5408\u6dfb\u52a0\u5168\u5c40\u8bf7\u6c42\u5934/\u53c2\u6570

NetConfig.initialize(Api.HOST, this) {\nsetRequestInterceptor(object : RequestInterceptor {\noverride fun interceptor(request: BaseRequest) {\nrequest.param(\"client\", \"Net\")\nrequest.setHeader(\"token\", \"123456\")\n}\n})\n}\n

\u53ef\u4ee5\u770b\u51fasetRequestInterceptor\u4ec5\u652f\u6301\u4e00\u4e2a, addInterceptor\u652f\u6301\u591a\u4e2a\u62e6\u622a\u5668

"},{"location":"interval.html","title":"\u8f6e\u8be2\u5668/\u5012\u8ba1\u65f6","text":"

Net\u81ea\u5e26\u8f6e\u8be2\u5668(\u8ba1\u65f6\u5668), \u5305\u542b\u4ee5\u4e0b\u7279\u6027

  • \u6b63\u8ba1\u65f6
  • \u5012\u8ba1\u65f6
  • \u6307\u5b9a\u6b21\u6570
  • \u652f\u6301\u5f00\u59cb/\u505c\u6b62/\u6682\u505c/\u7ee7\u7eed/\u91cd\u7f6e/\u5207\u6362\u5f00\u5173
  • \u4ec5\u9875\u9762\u663e\u793a\u65f6\u8ba1\u65f6
  • \u9875\u9762\u9500\u6bc1\u81ea\u52a8\u53d6\u6d88

\u9650\u5236\u6b21\u6570/\u95f4\u9694\u65e0\u9650\u6267\u884c\u5012\u8ba1\u65f6
interval = Interval(100, 1, TimeUnit.SECONDS).life(this) // \u81ea\u5b9a\u4e49\u8ba1\u6570\u5668\u4e2a\u6570\u7684\u8f6e\u8be2\u5668\n
 interval = Interval(1, TimeUnit.SECONDS) // \u6bcf\u79d2\u56de\u8c03\u4e00\u6b21, \u4e0d\u4f1a\u81ea\u52a8\u7ed3\u675f\n
// \u5012\u8ba1\u65f6\u8f6e\u8be2\u5668, \u5f53[start]]\u6bd4[end]\u503c\u5927, \u4e14end\u4e0d\u7b49\u4e8e-1\u65f6, \u5373\u4e3a\u5012\u8ba1\u65f6\ninterval = Interval(1, 1, TimeUnit.SECONDS, 5).life(this)\n

\u76d1\u542c\u8f6e\u8be2\u5668

interval.subscribe {\ntvFragment.text = it.toString()\n}.finish {\ntvFragment.text = \"\u8ba1\u65f6\u5b8c\u6210\" // \u6700\u540e\u4e00\u4f4d\u6570\u65f6\u540c\u65f6\u56de\u8c03 subscribe/finish\n}.start()\n

Interval \u63cf\u8ff0 start \u5f00\u59cb\u8f6e\u8be2\u5668 stop \u505c\u6b62 cancel \u53d6\u6d88, \u533a\u522b\u4e8estop, \u6b64\u51fd\u6570\u6267\u884c\u540e\u5e76\u4e0d\u4f1a\u56de\u8c03finish pause \u6682\u505c resume \u7ee7\u7eed reset \u91cd\u7f6e switch \u5207\u6362\u5f00\u5173 subscribe \u6bcf\u6b21\u8ba1\u65f6\u90fd\u4f1a\u6267\u884c\u8be5\u56de\u8c03 finish \u5f53\u8ba1\u65f6\u5668\u5b8c\u6210\u65f6\u6267\u884c\u8be5\u56de\u8c03, \u6267\u884cstop\u540e\u4e5f\u4f1a\u56de\u8c03 life \u6307\u5b9a\u751f\u547d\u5468\u671f\u81ea\u52a8\u53d6\u6d88\u8f6e\u8be2\u5668 onlyResumed \u5f53\u754c\u9762\u4e0d\u53ef\u89c1\u65f6\u6682\u505c, \u5f53\u754c\u9762\u53ef\u89c1\u65f6\u7ee7\u7eed

\u540e\u53f0\u8fd0\u884c

\u7531\u4e8e\u7cfb\u7edf\u9650\u5236, \u672c\u5de5\u5177\u65e0\u6cd5\u4fdd\u8bc1\u540e\u53f0\u8fd0\u884c

"},{"location":"issues.html","title":"\u5e38\u89c1\u95ee\u9898","text":"

Net\u6700\u5927\u7684\u7279\u70b9\u5728\u4e8e\u5b8c\u7f8e\u652f\u6301OkHttp\u7684\u6240\u6709\u529f\u80fd\u7ec4\u4ef6, \u800cOkHttp\u662fAndroid\u4e3b\u6d41\u7f51\u7edc\u89e3\u51b3\u65b9\u6848

\u6240\u4ee5\u5982\u679c\u5b58\u5728Net\u6ca1\u6709\u5b9e\u73b0\u7684\u529f\u80fd\u53ef\u4ee5\u8c37\u6b4c\u641c\u7d22\"OkHttp\u5982\u4f55\u5b9e\u73b0XX\", \u7136\u540e\u53ef\u4ee5\u5f88\u5bb9\u6613\u5728Net\u4e2d\u4f7f\u7528

"},{"location":"issues.html#_1","title":"\u4f4e\u7248\u672c\u517c\u5bb9","text":"

\u5982\u679c\u4f60\u662f\u5728 Android 5 (API level 21) \u4ee5\u4e0a\u5f00\u53d1\u5efa\u8bae\u4f7f\u7528\u6700\u65b0\u7248\u672c: Net \u5982\u679c\u8981\u6c42\u4f4e\u81f3 Android 4.4 (API level 19) \u8bf7\u4f7f\u7528\u517c\u5bb9\u7248\u672c: Net-okhttp3

\u5982\u679c\u9700\u66f4\u4f4e\u7248\u672c\u652f\u6301\u5efa\u8bae\u62c9\u53d6\u4ed3\u5e93\u4fee\u6539minSdkVersion\u540e\u7f16\u8bd1\u6210aar\u4f7f\u7528

"},{"location":"issues.html#_2","title":"\u5f00\u53d1\u8005\u4ea4\u6d41","text":"
  • \u53cd\u9988\u95ee\u9898
  • \u5176\u4ed6\u5f00\u53d1\u8005\u63d0\u53ca\u95ee\u9898
  • \u4ea4\u6d41\u793e\u533a
"},{"location":"kotlin-serialization.html","title":"Kotlin-Serialization","text":"
  1. \u4eceNet3\u5f00\u59cb\u652f\u6301\u4f7f\u7528 Kotlin-Serialization (\u4ee5\u4e0b\u7b80\u79f0ks)
  2. \u66f4\u591a\u4e86\u89e3\u8bf7\u9605\u8bfb: Kotlin\u6700\u5f3a\u89e3\u6790\u5e93 - kotlin-serialization
"},{"location":"kotlin-serialization.html#_1","title":"\u7279\u70b9","text":"
  • \u5b98\u65b9\u5e93
  • \u52a8\u6001\u6570\u636e\u7c7b\u578b\u89e3\u6790
  • \u81ea\u5b9a\u4e49\u5e8f\u5217\u5316\u5668
  • \u652f\u6301ProtoBuf/JSON\u7b49\u6570\u636e\u7ed3\u6784\u5e8f\u5217\u5316
  • \u975e\u7a7a\u8986\u76d6(\u5373JSON\u5b57\u6bb5\u4e3anull\u5219\u4f7f\u7528\u53d8\u91cf\u9ed8\u8ba4\u503c)
  • \u542f\u7528\u5bbd\u677e\u6a21\u5f0f, JSON\u548c\u6570\u636e\u7c7b\u7ed3\u6784\u65e0\u9700\u4e00\u81f4
  • \u89e3\u6790\u4efb\u4f55\u7c7b\u578b(Map/List/Pair...)

\u5f3a\u5236\u6ce8\u89e3

ks\u7684\u6570\u636e\u7c7b\u90fd\u8981\u6c42\u4f7f\u7528\u6ce8\u89e3@Serializable(\u9664\u975e\u81ea\u5b9a\u4e49\u89e3\u6790), \u7236\u7c7b\u548c\u5b50\u7c7b\u90fd\u9700\u8981

\u751f\u6210\u9ed8\u8ba4\u503c

\u4f7f\u7528\u63d2\u4ef6\u751f\u6210\u6570\u636eModel, \u652f\u6301\u81ea\u52a8\u751f\u6210\u9ed8\u8ba4\u503c\u548c\u6ce8\u89e3

\u751f\u6210\u9ed8\u8ba4\u503c\u53ef\u907f\u514d\u540e\u7aef\u8fd4\u56de\u5f02\u5e38\u6570\u636e\u5bfc\u81f4\u89e3\u6790\u5d29\u6e83, \u4ee5\u53ca\u53cd\u590d\u7f16\u5199\u5224\u7a7a\u4ee3\u7801

"},{"location":"kotlin-serialization.html#_2","title":"\u4f9d\u8d56","text":"

Project build.gradle

classpath \"org.jetbrains.kotlin:kotlin-serialization:$kotlin_version\"\n// \u548cKotlin\u63d2\u4ef6\u540c\u4e00\u4e2a\u7248\u672c\u53f7\u5373\u53ef\n

Model build.gradle

apply plugin: \"kotlin-kapt\"\napply plugin: 'kotlinx-serialization'\nimplementation \"org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0\"\n
"},{"location":"kotlin-serialization.html#_3","title":"\u914d\u7f6e\u8f6c\u6362\u5668","text":"

\u8fd9\u91cc\u4f7f\u7528\u793a\u4f8b\u4ee3\u7801\u4e2d SerializationConvert \u4f5c\u4e3a\u6f14\u793a

\u5168\u5c40\u914d\u7f6e\u5355\u4f8b\u914d\u7f6e
NetConfig.initialize(Api.HOST, this) {\nsetConverter(SerializationConvert())\n// ... \u5176\u4ed6\u914d\u7f6e\n}\n
val userList = Get<List<UserModel>>(\"list\") {\nconverter = SerializationConvert() // \u5355\u4f8b\u8f6c\u6362\u5668, \u6b64\u65f6\u4f1a\u5ffd\u7565\u5168\u5c40\u8f6c\u6362\u5668\n}.await()\n
"},{"location":"kotlin-serialization.html#_4","title":"\u4f7f\u7528","text":"
scopeNetLife {\nval userList = Get<List<UserModel>>(\"list\") {\nconverter = SerializationConvert()\n}.await()\ntvFragment.text = userList[0].name\n}\n
@Serializable\ndata class UserModel(var name: String, var age: Int, var height: Int)\n
"},{"location":"kotlin-serialization.html#_5","title":"\u5e38\u7528\u914d\u7f6e","text":"

\u4ee5\u4e0b\u4e3a\u53cd\u5e8f\u5217\u5316Json\u5e38\u7528\u914d\u7f6e

val jsonDecoder = Json {\nignoreUnknownKeys = true // \u6570\u636e\u7c7b\u53ef\u4ee5\u4e0d\u7528\u58f0\u660eJson\u7684\u6240\u6709\u5b57\u6bb5\ncoerceInputValues = true // \u5982\u679cJson\u5b57\u6bb5\u662fNull\u5219\u4f7f\u7528\u6570\u636e\u7c7b\u5b57\u6bb5\u9ed8\u8ba4\u503c\n}\n

\u6570\u636e\u7c7b\u4f7f\u7528\u9ed8\u8ba4\u503c

@Serializable\ndata class Data(var name:String = \"\", var age:Int = 0)\n

"},{"location":"kotlin-serialization.html#_6","title":"\u542f\u7528\u9ed8\u8ba4\u503c","text":"

\u5f53coerceInputValues = true\u65f6, json\u5b57\u6bb5\u4e3anull\u6570\u636e\u7c7b\u5b57\u6bb5\u4e3a\u975e\u7a7a\u7c7b\u578b\u60c5\u51b5\u4e0b\u91c7\u7528\u5b57\u6bb5\u9ed8\u8ba4\u503c, \u6ca1\u6709\u9ed8\u8ba4\u503c\u8bf7explicitNulls = false\u5219\u8d4b\u503c\u4e3anull

\u540c\u65f6\u5f53\u51fa\u73b0\u672a\u77e5\u7684\u679a\u4e3e\u7c7b\u578b\u4e5f\u4f1a\u4f7f\u7528\u9ed8\u8ba4\u503c

"},{"location":"kotlin-serialization.html#_7","title":"\u5b57\u6bb5\u7f3a\u5931","text":"

\u901a\u8fc7explicitNulls\u6765\u914d\u7f6e\u5b57\u6bb5\u7f3a\u65f6\u5904\u7406\u65b9\u5f0f

  • \u53cd\u5e8f\u5217\u5316\u65f6, \u5982\u679c\u6570\u636e\u7c7b\u7f3a\u5931\u5b57\u6bb5, \u4f7f\u7528ignoreUnknownKeys = true\u5c31\u4f1a\u81ea\u52a8\u4f7f\u7528\u9ed8\u8ba4\u503c, \u6ca1\u6709\u9ed8\u8ba4\u503c\u8bf7explicitNulls = false\u8d4b\u503c\u4e3anull
  • \u5e8f\u5217\u5316\u65f6, \u6570\u636e\u7c7b\u5982\u679c\u5b57\u6bb5\u4e3anull\u4e5f\u4f1a\u88ab\u8d4b\u503c\u5230json\u4e2d, explicitNulls = false\u53ef\u4ee5\u5ffd\u7565\u6389
"},{"location":"kotlin-serialization.html#_8","title":"\u81ea\u52a8\u751f\u6210","text":"

\u624b\u52a8\u5199\u9ed8\u8ba4\u503c\u592a\u9ebb\u70e6, \u63a8\u8350\u4f7f\u7528\u63d2\u4ef6\u751f\u6210\u9ed8\u8ba4\u503c

\u63d2\u4ef6\u5177\u4f53\u914d\u7f6e\u4f7f\u7528\u8bf7\u67e5\u770b: \u6570\u636e\u6a21\u578b\u751f\u6210\u63d2\u4ef6

"},{"location":"log-notice.html","title":"\u65e5\u5fd7\u901a\u77e5","text":"

\u4f7f\u7528\u4e09\u65b9\u5e93 Chucker \u5728\u901a\u77e5\u680f\u8bb0\u5f55\u7f51\u7edc\u8bf7\u6c42\u65e5\u5fd7

Chucker

\u4f9d\u8d56

implementation \"com.github.chuckerteam.chucker:library:3.5.2\"\n

\u6dfb\u52a0\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\n// ...\nif (BuildConfig.DEBUG) {\naddInterceptor(\nChuckerInterceptor.Builder(this@App)\n.collector(ChuckerCollector(this@App))\n.maxContentLength(250000L)\n.redactHeaders(emptySet())\n.alwaysReadResponseBody(false)\n.build()\n)\n}\n}\n

\u81ea\u5b9a\u4e49\u529f\u80fd\u6d4f\u89c8 Chucker \u5b98\u7f51

"},{"location":"log-recorder.html","title":"\u65e5\u5fd7\u63d2\u4ef6","text":"

\u4e24\u79cd\u65e5\u5fd7\u63d2\u4ef6

Okhttp Profiler Profiler \u5217\u8868\u663e\u793a \u52a8\u6001\u66f2\u7ebf\u56fe \u8981\u6c42\u6dfb\u52a0LogRecordInterceptor \u53ef\u67e5\u770b\u6240\u6709OkHttp\u7684\u8bf7\u6c42 \u539f\u7406\u662f\u63d2\u4ef6\u6355\u83b7LogCat\u65e5\u5fd7, \u7ebf\u4e0a\u73af\u5883\u8bf7\u5173\u95ed \u65e0\u6cd5\u6355\u83b7\u542f\u52a8\u4e00\u77ac\u95f4\u7684\u8bf7\u6c42"},{"location":"log-recorder.html#logrecordinterceptor","title":"LogRecordInterceptor","text":"

\u6dfb\u52a0\u65e5\u5fd7\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\naddInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))\n}\n
\u6784\u9020\u53c2\u6570 \u63cf\u8ff0 enabled \u662f\u5426\u542f\u7528\u65e5\u5fd7 requestByteCount \u8bf7\u6c42\u65e5\u5fd7\u4fe1\u606f\u6700\u5927\u5b57\u8282\u6570, \u9ed8\u8ba41MB responseByteCount \u54cd\u5e94\u65e5\u5fd7\u4fe1\u606f\u6700\u5927\u5b57\u8282\u6570, \u9ed8\u8ba44MB

\u6b64\u65f6\u4ec5LogCat\u8f93\u51fa\u65e5\u5fd7, \u8981\u9884\u89c8\u8bf7\u5b89\u88c5\u63d2\u4ef6

"},{"location":"log-recorder.html#_1","title":"\u5b89\u88c5\u63d2\u4ef6","text":""},{"location":"log-recorder.html#1","title":"1. \u5b89\u88c5\u63d2\u4ef6","text":"

\u5728\u63d2\u4ef6\u5e02\u573a\u641c\u7d22: \"Okhttp Profiler\"

"},{"location":"log-recorder.html#2","title":"2. \u6253\u5f00\u7a97\u53e3","text":"

\u5b89\u88c5\u4ee5\u540e\u5728AndroidStudio\u53f3\u4e0b\u89d2\u6253\u5f00\u7a97\u53e3

\u4e0d\u663e\u793a\u65e5\u5fd7

\u8bf7\u5728\u8bf7\u6c42\u524d\u786e\u4fdd\u6709\u6253\u5f00\u8fc7\u63d2\u4ef6\u7a97\u53e3, \u5982\u679c\u4f9d\u7136\u4e0d\u663e\u793a\u53ef\u4ee5\u53cd\u590d\u6253\u5f00/\u5173\u95ed\u7a97\u53e3

\u6bcf\u6b21AS\u66f4\u65b0\u90fd\u9700\u8981\u8be5\u63d2\u4ef6\u4f5c\u8005\u9002\u914d, \u53ef\u80fd\u5b58\u5728beta\u7248\u672c\u4f5c\u8005\u6ca1\u6709\u9002\u914d\u60c5\u51b5

\u4f7f\u7528\u6548\u679c

\u6807\u9898 \u63cf\u8ff0 Device \u9009\u62e9\u8c03\u8bd5\u8bbe\u5907 Process \u9009\u62e9\u5c55\u793a\u8bb0\u5f55\u7684\u8fdb\u7a0b \u6293\u53d6 \u4e00\u822c\u60c5\u51b5\u4e0d\u9700\u8981\u4f7f\u7528, \u5047\u8bbe\u6ca1\u6709\u53ca\u65f6\u66f4\u65b0\u8bf7\u70b9\u51fb\u56fe\u6807 \u6e05\u7a7a \u6e05\u7a7a\u8bb0\u5f55"},{"location":"log-recorder.html#_2","title":"\u81ea\u5b9a\u4e49\u65e5\u5fd7","text":"

\u7ee7\u627fLogRecordInterceptor\u590d\u5199\u51fd\u6570\u5b9e\u73b0\u81ea\u5b9a\u4e49

  1. \u590d\u5199getRequestLog\u8fd4\u56de\u89e3\u5bc6\u8bf7\u6c42\u53c2\u6570
  2. \u590d\u5199getResponseLog\u8fd4\u56de\u89e3\u5bc6\u54cd\u5e94\u53c2\u6570

\u521d\u59cb\u5316\u65f6\u6dfb\u52a0\u81ea\u5df1\u7684\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\naddInterceptor(MyLogRecordInterceptor(BuildConfig.DEBUG))\n}\n
"},{"location":"log-recorder.html#_3","title":"\u65e5\u5fd7\u8fc7\u6ee4","text":"

\u4e0d\u60f3\u7f51\u7edc\u65e5\u5fd7\u5f71\u54cd\u5176\u4ed6\u65e5\u5fd7\u67e5\u770b, \u53ef\u4ee5\u6dfb\u52a0OKPREL_\u4e3a\u65e5\u5fd7\u6298\u53e0\u89c4\u5219

"},{"location":"log-recorder.html#_4","title":"\u5176\u4ed6\u7f51\u7edc\u6846\u67b6","text":"

LogRecordInterceptor\u5c5e\u4e8eOkHttp\u62e6\u622a\u5668, \u5176\u4ed6\u7f51\u7edc\u8bf7\u6c42\u6846\u67b6\u4e5f\u53ef\u4ee5\u4f7f\u7528

\u751a\u81f3\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528LogRecorder\u8f93\u51fa\u65e5\u5fd7

LogRecorder \u63cf\u8ff0 generateId \u4ea7\u751f\u4e00\u4e2a\u552f\u4e00\u6807\u8bc6\u7b26, \u7528\u4e8e\u5224\u65ad\u4e3a\u540c\u4e00\u7f51\u7edc\u8bf7\u6c42 recordRequest \u8bb0\u5f55\u8bf7\u6c42\u4fe1\u606f recordResponse \u8bb0\u5f55\u54cd\u5e94\u4fe1\u606f recordException \u8bb0\u5f55\u8bf7\u6c42\u5f02\u5e38\u4fe1\u606f"},{"location":"model-generate.html","title":"\u6570\u636e\u7c7b\u751f\u6210\u63d2\u4ef6","text":"

\u5e94\u8be5\u6ca1\u4eba\u4f1a\u5b8c\u5168\u624b\u5199\u6570\u636e\u6a21\u578b\u5427? \u5efa\u8bae\u4f7f\u7528JSON To Kotlin Class \u63d2\u4ef6\u5b8c\u6210

"},{"location":"model-generate.html#_1","title":"\u5b89\u88c5\u63d2\u4ef6","text":"

\u5728Plugins\u91cc\u9762\u641c\u7d22kotlin\u5173\u952e\u8bcd\u4e0b\u8f7d\u5b89\u88c5

"},{"location":"model-generate.html#_2","title":"\u4f7f\u7528\u63d2\u4ef6","text":"

\u9009\u4e2d\u5206\u5305\u540e, \u4f7f\u7528\u5feb\u6377\u952e\u6216\u8005\u9f20\u6807\u53f3\u952e\u6253\u5f00\u586b\u5199Json\u754c\u9762

\u6dfb\u52a0Json\u7136\u540e\u70b9\u51fbGenerate\u751f\u6210

\u7136\u540e\u5c31\u4f1a\u5728\u9009\u4e2d\u7684\u5206\u5305\u4e0b\u751f\u6210\u4e00\u4e2a\u6570\u636e\u6a21\u578b\u7c7b\u4e86

\u4e0d\u8981\u751f\u6210\u6570\u7ec4

\u4e0d\u8981\u8f93\u5165JSON\u6570\u7ec4\u751f\u6210(\u5426\u5219\u751f\u6210\u7684\u7c7b\u4f1a\u7ee7\u627fArrayList), \u8f93\u5165JSON\u5bf9\u8c61, \u8bf7\u6c42\u4f7f\u7528Get<List<\u5bf9\u8c61>>

"},{"location":"model-generate.html#_3","title":"\u9ad8\u7ea7\u8bbe\u7f6e","text":"

\u70b9\u51fbAdvanced\u6253\u5f00\u8bbe\u7f6e\u754c\u9762

"},{"location":"model-generate.html#_4","title":"\u53ef\u7a7a\u9009\u9879","text":"

\u622a\u56fe\u5373\u4e3a\u6211\u7684\u63a8\u8350\u914d\u7f6e

  1. Keyword \u521b\u5efa\u7684\u6570\u636e\u6a21\u578b\u7684\u5b57\u6bb5\u662f Val\u8fd8\u662fVar
  2. Type \u5b57\u6bb5\u662f\u5426\u662f\u53ef\u7a7a\u7c7b\u578b, \u6700\u540e\u9009\u9879\u8868\u793a\u6839\u636eJson\u7684\u503c\u5224\u65ad\u662f\u5426\u53ef\u7a7a
  3. \u9ed8\u8ba4\u503c\u7684\u7b56\u7565, \u65e0\u6cd5\u9009\u62e9\u4e0d\u4ecb\u7ecd
"},{"location":"model-generate.html#_5","title":"\u4f7f\u7528\u7684\u6846\u67b6","text":"

\u751f\u6210\u6570\u636e\u6a21\u578b\u65f6\u4f1a\u517c\u5bb9\u4f60\u4f7f\u7528\u7684\u6846\u67b6, \u4f8b\u5982Moshi\u548cks\u53ef\u80fd\u9700\u8981\u6ce8\u89e3, \u7136\u540e\u4f1a\u81ea\u52a8\u751f\u6210SerialName\u8fd9\u4e9b\u540d\u79f0\u6ce8\u89e3

"},{"location":"model-generate.html#_6","title":"\u5176\u4ed6","text":"

\u622a\u56fe\u5373\u4e3a\u6211\u7684\u63a8\u8350\u914d\u7f6e

  1. \u662f\u5426\u4f7f\u7528\u6ce8\u91ca, \u65e2\u4f1a\u5c06Json\u5b57\u7b26\u4e32\u4f5c\u4e3a\u6ce8\u91ca\u4fdd\u7559\u5728\u6570\u636e\u6a21\u578b\u7c7b\u4e2d
  2. \u6839\u636e\u5b57\u6bcd\u6392\u5e8f\u6570\u636e\u6a21\u578b\u7684\u5b57\u6bb5
  3. \u4f7f\u7528\u5185\u90e8\u7c7b. \u4f8b\u5982Json\u4e2d\u7684Json\u5bf9\u8c61\u4f1a\u4f5c\u4e3a\u5185\u90e8\u7c7b\u88ab\u521b\u5efa\u5728\u6570\u636e\u6a21\u578b\u7c7b\u4e2d (\u63a8\u8350\u5f00\u542f, \u4fdd\u6301\u9ad8\u5185\u805a\u4f4e\u8026\u5408)
  4. \u5982\u679cJson\u5bf9\u8c61\u7684\u5b57\u6bb5\u90fd\u662f\u539f\u59cb\u7c7b\u578b\u5219\u4f7f\u7528Map\u6765\u8868\u793a
  5. \u53ea\u5728\u9700\u8981\u65f6\u521b\u5efa\u6ce8\u89e3
  6. \u81ea\u52a8\u9a8c\u8bc1Json\u6b63\u786e\u6027(\u5728\u586b\u5199\u65f6)
  7. Json\u683c\u5f0f\u5316\u65f6\u4f7f\u7528\u7684\u7a7a\u683c\u6570\u91cf
  8. \u6307\u5b9a\u4e00\u4e2a\u7c7b\u4f5c\u4e3a\u7236\u7c7b\u6a21\u677f(\u65e2\u521b\u5efa\u7684\u6570\u636e\u6a21\u578b\u90fd\u4f1a\u7ee7\u627f\u8be5\u7c7b)
"},{"location":"model-generate.html#_7","title":"\u6269\u5c55","text":"

\u622a\u56fe\u5373\u4e3a\u6211\u7684\u63a8\u8350\u914d\u7f6e

  1. \u6dfb\u52a0@Keep\u6ce8\u89e3, \u4e3a\u9632\u6b62\u88ab\u4ee3\u7801\u6df7\u6dc6
  2. \u6ce8\u89e3\u548c\u5b57\u6bb5\u5904\u4e8e\u540c\u4e00\u884c, \u4fbf\u4e8e\u7f8e\u89c2
  3. \u4f7f\u7528Parcelable\u5e8f\u5217\u5316
  4. \u4e3a\u5b57\u6bb5\u6dfb\u52a0\u524d\u7f00/\u540e\u7f00
  5. \u4e3a\u6570\u636e\u6a21\u578b\u7c7b\u6dfb\u52a0\u524d\u7f00/\u540e\u7f00
"},{"location":"okhttp-client.html","title":"OkHttpClient","text":"

Net\u5168\u5c40\u6301\u6709\u4e00\u4e2aOkHttpClient\u5bf9\u8c61\u53d1\u8d77\u8bf7\u6c42

object NetConfig {\nvar okHttpClient: OkHttpClient\n}\n
"},{"location":"okhttp-client.html#_1","title":"\u5168\u5c40","text":"
NetConfig.initialize(Api.HOST, this) {\n// \u6b64\u5904this\u5373\u4e3aOkHttpClient.Builder\n}\n
"},{"location":"okhttp-client.html#_2","title":"\u5355\u4f8b","text":"

\u53ef\u4ee5\u5355\u72ec\u6307\u5b9a\u5f53\u524d\u8bf7\u6c42\u5ba2\u6237\u7aef

\u4fee\u6539\u5168\u5c40\u5ba2\u6237\u7aef\u521b\u5efa\u65b0\u5ba2\u6237\u7aef

scopeNetLife {\ntv_response.text = Get<String>(Api.PATH) {\nsetClient {\n// \u6b64\u5904this\u5373\u4e3aOkHttpClient.Builder\ntrustCertificate()\n}\n}.await()\n}\n
\u5728\u5168\u5c40OkHttpClient\u57fa\u7840\u4e0a\u4fee\u6539

scopeNetLife {\ntv_response.text = Get<String>(Api.PATH) {\nokHttpClient = OkHttpClient.Builder().build()\n}.await()\n}\n
\u521b\u5efa\u65b0\u7684OkHttpClient, \u4e00\u822c\u4e0d\u4f7f\u7528, \u56e0\u4e3a\u65b0OkHttpClient\u4f1a\u91cd\u65b0\u521b\u5efa\u7ebf\u7a0b\u6c60/\u8fde\u63a5\u6c60\u7b49\u9020\u6210\u5185\u5b58\u6d88\u8017

"},{"location":"progress.html","title":"\u8fdb\u5ea6\u76d1\u542c","text":"

Net\u652f\u6301\u4e0a\u4f20/\u4e0b\u8f7d\u7684\u8fdb\u5ea6\u76d1\u542c, \u4e14\u5177\u5907\u5b8c\u5584\u7684\u8fdb\u5ea6\u4fe1\u606f

"},{"location":"progress.html#_1","title":"\u4e0a\u4f20\u8fdb\u5ea6\u76d1\u542c","text":"
scopeNetLife {\nPost<String>(Api.UPLOAD) {\nparam(\"file\", assetsFile())\naddUploadListener(object : ProgressListener() {\noverride fun onProgress(p: Progress) {\nseek.post {\nseek.progress = p.progress()\ntvProgress.text =\n\"\u4e0a\u4f20\u8fdb\u5ea6: ${p.progress()}% \u4e0a\u4f20\u901f\u5ea6: ${p.speedSize()}     \" +\n\"\\n\\n\u6587\u4ef6\u5927\u5c0f: ${p.totalSize()}  \u5df2\u4e0a\u4f20: ${p.currentSize()}  \u5269\u4f59\u5927\u5c0f: ${p.remainSize()}\" +\n\"\\n\\n\u5df2\u4f7f\u7528\u65f6\u95f4: ${p.useTime()}  \u5269\u4f59\u65f6\u95f4: ${p.remainTime()}\"\n}\n}\n})\n}.await()\n}\n
"},{"location":"progress.html#_2","title":"\u4e0b\u8f7d\u8fdb\u5ea6\u76d1\u542c","text":"
scopeNetLife {\nval file =\nGet<File>(\"https://github.com/liangjingkanji/Net/releases/latest/download/net-sample.apk\") {\nsetDownloadFileName(\"net.apk\")\nsetDownloadDir(requireContext().filesDir)\naddDownloadListener(object : ProgressListener() {\noverride fun onProgress(p: Progress) {\nseek?.post {\nval progress = p.progress()\nseek.progress = progress\ntvProgress.text =\n\"\u4e0b\u8f7d\u8fdb\u5ea6: $progress% \u4e0b\u8f7d\u901f\u5ea6: ${p.speedSize()}     \" +\n\"\\n\\n\u6587\u4ef6\u5927\u5c0f: ${p.totalSize()}  \u5df2\u4e0b\u8f7d: ${p.currentSize()}  \u5269\u4f59\u5927\u5c0f: ${p.remainSize()}\" +\n\"\\n\\n\u5df2\u4f7f\u7528\u65f6\u95f4: ${p.useTime()}  \u5269\u4f59\u65f6\u95f4: ${p.remainTime()}\"\n}\n}\n})\n}.await()\n}\n

\u76d1\u542c\u4efb\u4f55\u8fdb\u5ea6

\u4e0d\u4ec5\u662f\u6cdb\u578b\u4e3aFile\u624d\u6709\u6548, \u4efb\u4f55\u8bf7\u6c42/\u54cd\u5e94\u90fd\u53ef\u4ee5\u76d1\u542c\u8fdb\u5ea6

"},{"location":"progress.html#_3","title":"\u76d1\u542c\u5668","text":"

\u5b9e\u73b0ProgressListener\u76d1\u542c\u8fdb\u5ea6\u4fe1\u606f. \u8fdb\u5ea6\u4fe1\u606f\u4e3aProgress

"},{"location":"progress.html#_4","title":"\u8fdb\u5ea6\u95f4\u9694\u65f6\u95f4","text":"

ProgressListener\u7684\u6784\u9020\u53c2\u6570interval\u63a7\u5236\u89e6\u53d1\u8fdb\u5ea6\u76d1\u542c\u5668\u7684\u95f4\u9694\u65f6\u95f4

"},{"location":"progress.html#_5","title":"\u8fdb\u5ea6\u4fe1\u606f","text":"\u51fd\u6570 \u63cf\u8ff0 currentBytes \u5df2\u5b8c\u6210\u5b57\u8282\u6570 totalBytes \u5168\u90e8\u5927\u5c0f\u5b57\u8282\u6570 intervalBytes \u8fdb\u5ea6\u95f4\u9694\u65f6\u95f4\u5185\u5b8c\u6210\u7684\u5b57\u8282\u6570 intervalTime \u8ddd\u79bb\u4e0a\u6b21\u8fdb\u5ea6\u53d8\u5316\u95f4\u9694\u65f6\u95f4 startElapsedRealtime \u5f00\u59cb\u4e0b\u8f7d\u65f6\u95f4(\u8be5\u65f6\u95f4\u503c\u5f00\u673a\u5230\u73b0\u5728\u7684\u6beb\u79d2\u6570) speedBytes \u6bcf\u79d2\u4e0b\u8f7d\u5b57\u8282\u6570 progress \u8fdb\u5ea6, 1-100 finish \u6b64\u6b21\u4e0b\u8f7d/\u4e0a\u4f20\u662f\u5426\u5b8c\u6210 useTimeSeconds \u5df2\u7ecf\u4f7f\u7528\u65f6\u95f4, \u5355\u4f4d\u79d2 remainTimeSeconds \u4f30\u7b97\u7684\u5269\u4f59\u65f6\u95f4, \u5355\u4f4d\u79d2"},{"location":"progress.html#_6","title":"\u683c\u5f0f\u5316\u5b57\u7b26\u4e32","text":"\u51fd\u6570 \u63cf\u8ff0 currentSize \u5df2\u5b8c\u6210\u5927\u5c0f, \u4f8b\u5982: 120kB \u6216\u8005 1.5MB totalSize \u5168\u90e8\u5927\u5c0f remainSize \u5269\u4f59\u5927\u5c0f speedSize \u6bcf\u79d2\u4e0b\u8f7d\u5927\u5c0f useTime \u5df2\u4f7f\u7528\u65f6\u95f4, \u683c\u5f0f\u4e3a: 01:23:04 remainTime \u4f30\u7b97\u7684\u5269\u4f59\u65f6\u95f4, \u683c\u5f0f\u4e3a: 01:23:04"},{"location":"repeat-request.html","title":"\u91cd\u590d\u8bf7\u6c42","text":"

\u5e38\u7528\u4e8e\u7b5b\u9009\u5217\u8868\u8bf7\u6c42, \u9009\u62e9\u65b0\u7684\u7b5b\u9009\u6761\u4ef6\u65f6\u5e94\u5c06\u4e0a\u6b21\u672a\u5b8c\u6210\u7684\u53d6\u6d88\u540e\u518d\u53d1\u8d77\u8bf7\u6c42

\u5728Net\u7981\u6b62\u91cd\u590d\u8bf7\u6c42\u4ec52\u884c\u4ee3\u7801

var scope: AndroidScope? = null\nbtnFilter.setOnClickListener {\nscope?.cancel()\nscope = scopeNetLife {\nval result = Post<String>(\"api\").await()\n}\n}\n

\u5f53scope\u4e0d\u4e3a\u7a7a\u65f6\u8868\u793a\u5b58\u5728\u65e7\u8bf7\u6c42, \u65e0\u8bba\u65e7\u8bf7\u6c42\u662f\u5426\u5b8c\u6210\u90fd\u53ef\u4ee5\u8c03\u7528cancel()\u4fdd\u8bc1\u53d6\u6d88\u5373\u53ef

  1. \u53d6\u6d88\u8bf7\u6c42
  2. \u9650\u5236\u65f6\u95f4\u5f3a\u5236\u4f7f\u7528\u7f13\u5b58, \u914d\u7f6e\u7f13\u5b58\u6709\u6548\u671f
"},{"location":"request.html","title":"\u8bf7\u6c42\u53c2\u6570","text":"

\u8bf7\u6c42\u53c2\u6570

\u6839\u636e\u8bf7\u6c42\u65b9\u5f0f\u4e0d\u540c\u8bf7\u6c42\u53c2\u6570\u5206\u4e3a\u4e24\u7c7b

UrlRequest: GET, HEAD, OPTIONS, TRACE // Query(\u8bf7\u6c42\u53c2\u6570\u4f4d\u4e8eUrl\u4e2d) BodyRequest: POST, DELETE, PUT, PATCH // Body(\u8bf7\u6c42\u4f53\u4e3a\u6d41)

\u4f7f\u7528\u793a\u4f8b

scopeNetLife {\nval userInfo = Post<UserInfoModel>(Api.LOGIN) {\nparam(\"username\", \"\u7528\u6237\u540d\")\nparam(\"password\", \"6f2961eb44b12123393fff7e449e50b9de2499c6\")\n}.await()\n}\n
\u51fd\u6570 \u63cf\u8ff0 param Url\u8bf7\u6c42\u65f6\u4e3aQuery, Body\u8bf7\u6c42\u65f6\u4e3a\u8868\u5355/\u6587\u4ef6 json JSON\u5b57\u7b26\u4e32 setQuery/addQuery Url\u4e2d\u7684Query\u53c2\u6570, \u5982\u679c\u5f53\u4e3aUrl\u8bf7\u6c42\u5219\u8be5\u51fd\u6570\u7b49\u6548param setHeader/addHeader \u8bbe\u7f6e/\u6dfb\u52a0\u8bf7\u6c42\u5934"},{"location":"request.html#json","title":"JSON","text":"

\u4e09\u79cd\u53c2\u6570\u7c7b\u578b\u4e0a\u4f20JSON\u793a\u4f8b, \u66f4\u591a\u8bf7\u9605\u8bfb\u65b9\u6cd5\u6ce8\u91ca

\u952e\u503c\u5bf9JSONObject\u81ea\u5b9a\u4e49RequestBody
val name = \"\u91d1\u57ce\u6b66\"\nval age = 29\nval measurements = listOf(100, 100, 100)\nscopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\n// \u53ea\u652f\u6301\u57fa\u7840\u7c7b\u578b\u7684\u503c, \u5982\u679c\u503c\u4e3a\u5bf9\u8c61\u6216\u8005\u5305\u542b\u5bf9\u8c61\u7684\u96c6\u5408/\u6570\u7ec4\u4f1a\u5bfc\u81f4\u5176\u503c\u4e3anull\njson(\"name\" to name, \"age\" to age, \"measurements\" to measurements)\n}.await()\n}\n
val name = \"\u91d1\u57ce\u6b66\"\nval age = 29\nval measurements = listOf(100, 100, 100) // \u53ea\u652f\u6301\u57fa\u7840\u7c7b\u578b\u7684\u503c, \u5982\u679c\u503c\u4e3a\u5bf9\u8c61\u6216\u8005\u5305\u542b\u5bf9\u8c61\u7684\u96c6\u5408/\u6570\u7ec4\u4f1a\u5bfc\u81f4\u5176\u503c\u4e3anull\nscopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\njson(JSONObject().run {\nput(\"name\", name)\nput(\"age\", age)\nput(\"measurements\", JSONArray(measurements))\n})\n}.await()\n}\n
val name = \"\u91d1\u57ce\u6b66\"\nval age = 29\nval measurements = listOf(100, 100, 100)\nscopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\nbody = CustomizerJSONBody(name, age, measurements)\n}.await()\n}\n

\u5982\u679cJSON\u9700\u8981\u5168\u5c40\u53c2\u6570

  1. \u81ea\u5b9a\u4e49RequestBody\u6dfb\u52a0\u5168\u5c40\u53c2\u6570
  2. \u4f7f\u7528\u8bf7\u6c42\u62e6\u622a\u5668\u6765\u6dfb\u52a0\u5168\u5c40\u53c2\u6570 RequestInterceptor
"},{"location":"request.html#_1","title":"\u81ea\u5b9a\u4e49\u6269\u5c55\u51fd\u6570","text":"

\u7531\u4e8ejson()\u4e0d\u80fd\u4f20\u5bf9\u8c61, \u56e0\u4e3a\u4f7f\u7528\u7684org.json.JSONObject\u5176\u4e0d\u652f\u6301\u6620\u5c04\u5bf9\u8c61\u5b57\u6bb5

\u4f46\u53ef\u521b\u5efa\u6269\u5c55\u51fd\u6570\u6765\u4f7f\u7528\u5c04\u5bf9\u8c61\u5e8f\u5217\u5316\u6846\u67b6\u6765\u89e3\u6790, \u5982\u4e0b

GsonFastJson
fun BodyRequest.gson(vararg body: Pair<String, Any?>) {\nthis.body = Gson().toJson(body.toMap()).toRequestBody(MediaConst.JSON)\n}\n
fun BodyRequest.fastJson(vararg body: Pair<String, Any?>) {\nthis.body = JSON.toJSON(body.toMap()).toRequestBody(MediaConst.JSON)\n}\n

\u4f7f\u7528

scopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\ngson(\"name\" to name, \"model\" to Model()) // \u53c2\u6570\u652f\u6301Gson\u53ef\u89e3\u6790\u7684\u5bf9\u8c61\n// fastJson(\"name\" to name, \"model\" to Model()) // \u4f7f\u7528FastJson\n}.await()\n}\n
"},{"location":"request.html#_2","title":"\u5168\u5c40\u8bf7\u6c42\u53c2\u6570","text":"

\u4f7f\u7528RequestInterceptor\u8bf7\u6c42\u62e6\u622a\u5668\u6dfb\u52a0\u5168\u5c40\u53c2\u6570/\u8bf7\u6c42\u5934, \u66f4\u590d\u6742\u8bf7\u5b9e\u73b0Interceptor

class GlobalHeaderInterceptor : RequestInterceptor {\n// \u6bcf\u6b21\u8bf7\u6c42\u90fd\u4f1a\u56de\u8c03, \u53ef\u4ee5\u662f\u52a8\u6001\u53c2\u6570\noverride fun interceptor(request: BaseRequest) {\nrequest.setHeader(\"client\", \"Android\")\nrequest.setHeader(\"token\", UserConfig.token)\n}\n}\n
NetConfig.initialize(Api.HOST, this) {\nsetRequestInterceptor(GlobalHeaderInterceptor())\n}\n

\u66f4\u591a\u8bf7\u6c42\u53c2\u6570\u76f8\u5173\u8bf7\u9605\u8bfbApi\u6587\u6863/\u51fd\u6570\u5217\u8868

"},{"location":"scope.html","title":"\u4f5c\u7528\u57df","text":"

\u521b\u5efa\u4e0d\u540c\u534f\u7a0b\u4f5c\u7528\u57df\u53ef\u4ee5\u5b9e\u73b0\u4e0d\u540c\u7684\u529f\u80fd

\u51cf\u5c11\u5d29\u6e83

Net\u6240\u6709\u4f5c\u7528\u57df\u5185\u629b\u51fa\u5f02\u5e38\u90fd\u4f1a\u88ab\u6355\u83b7\u5230, \u53ef\u4ee5\u9632\u6b62\u5e94\u7528\u5d29\u6e83

"},{"location":"scope.html#_1","title":"\u5f02\u6b65\u4efb\u52a1\u7684\u4f5c\u7528\u57df","text":"

\u53ef\u4ee5\u6355\u6349\u5f02\u5e38\u7684\u534f\u7a0b\u4f5c\u7528\u57df, \u7528\u4e8e\u6784\u5efa\u666e\u901a\u5f02\u6b65\u4efb\u52a1

\u51fd\u6570 \u63cf\u8ff0 scope \u521b\u5efa\u6700\u57fa\u7840\u7684\u4f5c\u7528\u57df scopeLife \u521b\u5efa\u8ddf\u968f\u751f\u547d\u5468\u671f\u81ea\u52a8\u53d6\u6d88\u7684\u4f5c\u7528\u57df ViewModel.scopeLife \u521b\u5efa\u8ddf\u968fViewModel\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df, \u5982\u4f55\u5728ViewModel\u521b\u5efa\u4f5c\u7528\u57df"},{"location":"scope.html#_2","title":"\u7f51\u7edc\u8bf7\u6c42\u7684\u4f5c\u7528\u57df","text":"

\u9664\u5f02\u6b65\u4efb\u52a1\u5916\u8fd8\u9002\u7528\u4e8e\u7f51\u7edc\u8bf7\u6c42\u573a\u666f\u7684\u4f5c\u7528\u57df, \u5bf9\u6bd4\u4e0a\u9762\u5f02\u6b65\u4efb\u52a1\u7684\u4f5c\u7528\u57df\u533a\u522b:

  1. \u53d1\u751f\u9519\u8bef\u81ea\u52a8\u5410\u53f8(\u53ef\u4ee5\u81ea\u5b9a\u4e49\u6216\u8005\u53d6\u6d88)
  2. \u53d1\u751f\u9519\u8bef\u4f1a\u89e6\u53d1\u5168\u5c40\u9519\u8bef\u5904\u7406NetErrorHandler
  3. \u5177\u5907\u4e00\u4e9b\u7279\u6b8a\u573a\u666f\u529f\u80fd, \u6bd4\u5982\u6839\u636e\u7f51\u7edc\u8bf7\u6c42\u7ed3\u679c\u81ea\u52a8\u5904\u7406\u4e0b\u62c9\u5237\u65b0/\u4e0a\u62c9\u52a0\u8f7d/\u7f3a\u7701\u9875/\u52a0\u8f7d\u6846\u7684\u72b6\u6001
\u51fd\u6570 \u63cf\u8ff0 scopeNet \u521b\u5efa\u81ea\u52a8\u5904\u7406\u7f51\u7edc\u9519\u8bef\u7684\u4f5c\u7528\u57df scopeNetLife \u521b\u5efa\u81ea\u52a8\u5904\u7406\u7f51\u7edc\u9519\u8bef\u7684\u4f5c\u7528\u57df, \u4e14\u5305\u542b\u8ddf\u968fActivity\u6216\u8005Fragment\u751f\u547d\u5468\u671f scopeDialog \u521b\u5efa\u81ea\u52a8\u52a0\u8f7d\u5bf9\u8bdd\u6846\u7684\u4f5c\u7528\u57df, \u751f\u547d\u5468\u671f\u8ddf\u968f\u5bf9\u8bdd\u6846 ViewModel.scopeNetLife \u521b\u5efa\u8ddf\u968fViewModel\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df, \u5982\u4f55\u5728ViewModel\u521b\u5efa\u4f5c\u7528\u57df PageRefreshLayout.scope \u521b\u5efa\u8ddf\u968fPageRefreshLayout\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df StateLayout.scope \u521b\u5efa\u8ddf\u968fStateLayout\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df

\u533a\u5206\u51fd\u6570\u63a5\u53d7\u8005

\u6ce8\u610fStateLayout.scope\u7b49\u5b58\u5728\u51fd\u6570\u63a5\u53d7\u8005\u7684\u65b9\u6cd5\u548cscope\u5c5e\u4e8e\u4e24\u4e2a\u65b9\u6cd5, \u4e25\u7981\u6df7\u7528

\u7b2c\u4e09\u65b9\u5e93\u652f\u6301

PageRefreshLayout/StateLayout \u5c5e\u4e8e\u7b2c\u4e09\u65b9\u5f00\u6e90\u9879\u76ee BRV \u6846\u67b6\u4e2d\u7684\u5e03\u5c40, \u53ef\u7528\u4e8e\u652f\u6301\u81ea\u52a8\u5316\u7f3a\u7701\u9875/\u4e0b\u62c9\u5237\u65b0

\u5982\u679c\u60f3\u66f4\u4e86\u89e3\u534f\u7a0b\u4f7f\u7528\u65b9\u5f0f, \u53ef\u4ee5\u9605\u8bfb\u4e00\u7bc7\u6587\u7ae0: \u6700\u5168\u9762\u7684Kotlin\u534f\u7a0b: Coroutine/Channel/Flow \u4ee5\u53ca\u5b9e\u9645\u5e94\u7528

"},{"location":"scope.html#_3","title":"\u5d4c\u5957\u4f5c\u7528\u57df","text":"

\u6709\u65f6\u5019\u53ef\u80fd\u9762\u4e34\u5185\u5d4cscopeXX\u51fd\u6570(\u5d4c\u5957\u4f5c\u7528\u57df), \u8fd9\u65f6\u5019\u751f\u547d\u5468\u671f\u5982\u4e0b

scopeNetLife {\nval task = Post<String>(\"api0\").await()\nscopeNetLife {\nval task = Post<String>(\"api0\").await() // \u6b64\u65f6\u53d1\u751f\u8bf7\u6c42\u9519\u8bef\n}.catch {\n// A\n}\n}.catch {\n// B\n}\n
  • \u9519\u8bef\u5c06\u5728A\u5904\u53ef\u4ee5\u83b7\u53d6\u5230, \u4e14\u4e0d\u5f71\u54cd\u5916\u90e8scopeNetLife\u7684\u8bf7\u6c42
  • \u4e24\u4e2ascopeNetLife\u7684\u5f02\u5e38\u629b\u51fa\u548c\u6355\u83b7\u4e92\u4e0d\u5f71\u54cd
  • scopeXX()\u7b49\u51fd\u6570\u540c\u7406
"},{"location":"scope.html#_4","title":"\u5b50\u4f5c\u7528\u57df","text":"
scopeNet {\nval await = Post<String>(\"api\").await()\nlaunch {\nval task = Post<String>(\"api0\").await()  // \u6b64\u65f6\u53d1\u751f\u8bf7\u6c42\u9519\u8bef\n}.invokeOnCompletion {\n// A\n}\n}.catch {\n// B\n}\n
  • \u8fd9\u79cd\u60c5\u51b5 \u5148\u6267\u884cA\u7136\u540e\u6267\u884cB, \u5e76\u4e14\u90fd\u80fd\u6355\u83b7\u5f02\u5e38.
  • \u540c\u65f6scopeNet\u53d1\u751f\u9519\u8bef\u4e5f\u4f1a\u5bfc\u81f4launch\u5185\u7684\u8bf7\u6c42\u88ab\u53d6\u6d88, launch\u53d1\u751f\u9519\u8bef\u4e5f\u4f1a\u5bfc\u81f4scopeNet\u53d1\u751f\u9519\u8bef
"},{"location":"sync-request.html","title":"\u540c\u6b65\u8bf7\u6c42","text":"

Net\u652f\u6301\u5728\u5f53\u524d\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u7ebf\u7a0b\u7684\u540c\u6b65\u8bf7\u6c42

\u4ec0\u4e48\u662f\u540c\u6b65\u8bf7\u6c42

\u5373\u4e0a\u4e2a\u8bf7\u6c42\u7ed3\u675f\u624d\u4f1a\u53d1\u8d77\u4e0b\u4e2a\u8bf7\u6c42, \u5b9e\u9645\u4e0a\u534f\u7a0b\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u4f46\u662f\u4ed6\u4e0d\u4f1a\u963b\u585e\u7ebf\u7a0b

\u540c\u6b65\u8bf7\u6c42\u5e94\u7528\u573a\u666f\u4e00\u822c\u662f\u5728\u62e6\u622a\u5668(\u6267\u884c\u5728\u5b50\u7ebf\u7a0b)\u4e2d\u4f7f\u7528

\u56e0\u4e3aAndroid\u4e3b\u7ebf\u7a0b\u4e0d\u5141\u8bb8\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42, \u8fd9\u91cc\u521b\u5efa\u4e00\u4e2a\u5b50\u7ebf\u7a0b\u6765\u6f14\u793a

\u8fd4\u56de\u6570\u636e\u8fd4\u56deResult
thread {\nval result = Net.post(\"api\").execute<String>() // \u7f51\u7edc\u8bf7\u6c42\u4e0d\u5141\u8bb8\u5728\u4e3b\u7ebf\u7a0b\ntvFragment?.post {\ntvFragment?.text = result  // view\u8981\u6c42\u5728\u4e3b\u7ebf\u7a0b\u66f4\u65b0\n}\n}\n
thread {\nval result = Net.post(\"api\").toResult<String>().getOrDefault(\"\u8bf7\u6c42\u53d1\u751f\u9519\u8bef, \u6211\u662f\u9ed8\u8ba4\u503c\")\ntvFragment?.post {\ntvFragment?.text = result  // view\u8981\u6c42\u5728\u4e3b\u7ebf\u7a0b\u66f4\u65b0\n}\n}\n
  1. execute\u5728\u8bf7\u6c42\u9519\u8bef\u65f6\u4f1a\u76f4\u63a5\u629b\u51fa\u5f02\u5e38
  2. toResult\u4e0d\u4f1a\u629b\u51fa\u5f02\u5e38, \u53efgetOrThrow/exceptionOrNull\u7b49\u8fd4\u56de\u5f02\u5e38\u5bf9\u8c61
"},{"location":"tag.html","title":"\u6807\u7b7e/\u989d\u5916","text":"

Net\u652f\u6301\u4e24\u79cd\u65b9\u5f0f\u643a\u5e26\u6570\u636e, \u8d2f\u7a7f\u6574\u4e2a\u8bf7\u6c42\u6d41\u7a0b(\u8bf7\u6c42/\u62e6\u622a\u5668/\u8f6c\u6362\u5668)

  • tag: HashMap<Class<*>, Any?> \u6807\u7b7e
  • extra: HashMap<String, Any?> \u989d\u5916\u6570\u636e

\u4e24\u8005\u533a\u522b\u4e3a\u5b58\u50a8\u65f6key\u662fClass\u8fd8\u662fString, \u81ea\u7531\u9009\u62e9

"},{"location":"tag.html#_1","title":"\u6807\u7b7e\u4f7f\u7528","text":""},{"location":"tag.html#1","title":"1. \u5199\u5165\u6807\u7b7e","text":"
scopeNetLife {\ntvFragment.text = Get<String>(\"api\", \"\u6807\u7b7eA\"){ // \u4f7f\u7528Any::class.java\u4f5c\u4e3a\u952e\u540d\n// tag(\"\u6807\u7b7eA\") \u7b49\u6548\u4e0a\u4e00\u884c\u7684\u53c2\u6570 \"\u6807\u7b7eA\"\nsetExtra(\"tagName\", \"\u6807\u7b7eB\") // \u5199\u5165\u989d\u5916\u6570\u636e\n}.await()\n}\n
"},{"location":"tag.html#2","title":"2. \u62e6\u622a\u5668\u4e2d\u8bfb\u53d6\u6807\u7b7e","text":"
class MyInterceptor : Interceptor {\noverride fun intercept(chain: Chain): Response {\nval request = chain.request()\nrequest.tag()?.let {\n// \u8bfb\u53d6\u6807\u7b7e\n}\nrequest.extra(\"tagName\")?.let {\n// \u8bfb\u53d6\u989d\u5916\u6570\u636e\n}\nreturn chain.proceed(request)\n}\n}\n
"},{"location":"tag.html#3","title":"3. \u8f6c\u6362\u5668\u4e2d\u8bfb\u53d6\u6807\u7b7e","text":"
class MyConvert : NetConvert {\noverride fun <R> onConvert(succeed: Type, response: Response ): R? {\nresponse.request.tag()?.let{\n// \u8bfb\u53d6\u6807\u7b7e\n}\n}\n}\n

\u901a\u8fc7Request\u53ef\u4ee5\u8bfb\u5199\u6570\u636e

\u65b9\u6cd5 \u63cf\u8ff0 setExtra \u5199\u5165\u989d\u5916\u6570\u636e extra \u8bfb\u53d6\u989d\u5916\u6570\u636e extras \u5168\u90e8\u989d\u5916\u6570\u636e tag \u8bfb\u53d6/\u5199\u5165\u6807\u7b7e tagOf \u8bfb\u53d6/\u5199\u5165\u6807\u7b7e, \u4e3atag()\u7684\u6cdb\u578b\u66ff\u4ee3 tags \u5168\u90e8\u6807\u7b7e"},{"location":"tag.html#_2","title":"\u591a\u4e2a\u6807\u7b7e","text":"
scopeNetLife {\nGet<String>(\"api\"){\nsetExtra(\"person\", Person()) // \u4f7f\u7528Request.extra(\"person\")\u8bfb\u53d6\ntag(User()) // \u7b49\u540c\u4e8etag(Any::class.java, User()), \u4f7f\u7528Request.tag()\u8bfb\u53d6\ntag(User::class.java, User()) // \u4f7f\u7528Request.tag(User::class.java)\u8bfb\u53d6\n}.await()\n}\n

\u5f97\u5230\u6807\u7b7e

class MyInterceptor : Interceptor {\noverride fun intercept(chain: Chain): Response {\nval request = chain.request()\nrequest.extra(\"person\")?.let {\n// it\u65e2\u4e3aPerson\u5bf9\u8c61\n}\nrequest.tagOf<User>() // \u7ed3\u679c\u4e3aUser()\nrequest.tag() // \u7ed3\u679c\u4e3aUser()\nreturn chain.proceed(request)\n}\n}\n
"},{"location":"thread.html","title":"\u5207\u6362\u7ebf\u7a0b","text":"

\u6240\u6709scopeXX\u4f5c\u7528\u57df\u5185\u4e3a\u4e3b\u7ebf\u7a0b, \u53ef\u76f4\u63a5\u66f4\u65b0\u89c6\u56fe

\u8c03\u5ea6\u5668

\u534f\u7a0b\u4e2d\u7684\u8c03\u5ea6\u5668\u5b9e\u9645\u4e0a\u4e3a\u7ebf\u7a0b\u6c60, \u901a\u8fc7\u5207\u6362\u8c03\u5ea6\u5668\u53ef\u4ee5\u5207\u6362\u5230\u4e0d\u540c\u7ebf\u7a0b\u4e0a

"},{"location":"thread.html#_1","title":"\u5207\u6362\u8c03\u5ea6\u5668","text":"
scopeNetLife(dispatcher = Dispatchers.IO) {\nbinding.tvFragment.text = Get<String>(\"api\").await()\n}\n
"},{"location":"thread.html#_2","title":"\u4f5c\u7528\u57df\u5185\u90e8\u5207\u6362","text":"

\u6709\u65f6\u9700\u5f00\u542f\u65b0\u7684\u7ebf\u7a0b\u5904\u7406\u8017\u65f6\u4efb\u52a1

\u4e3b\u7ebf\u7a0b\u4f5c\u7528\u57df\u5185\u5207\u6362\u5b50\u7ebf\u7a0b\u5b50\u7ebf\u7a0b\u4f5c\u7528\u57df\u5185\u5207\u6362\u4e3b\u7ebf\u7a0b
scopeNetLife {\nbinding.tvFragment.text = withIO {\n// \u5047\u8bbe\u6b64\u5904\u662f\u4e00\u4e2aIO\u8bfb\u5199\u963b\u585e\u4efb\u52a1\nreturn \"\u8bfb\u51fa\u7ed3\u679c\"\n}\n}\n
scopeNetLife(dispatcher = Dispatchers.IO) {\nbinding.tvFragment.text = withMain {\n// \u5047\u8bbe\u6b64\u5904\u662f\u4e00\u4e2aIO\u8bfb\u5199\u963b\u585e\u4efb\u52a1\nreturn \"\u8bfb\u51fa\u7ed3\u679c\"\n}\n}\n
\u51fd\u6570 \u63cf\u8ff0 withMain \u5207\u6362\u5230\u4e3b\u7ebf\u7a0b withIO \u5207\u6362\u5230IO\u7ebf\u7a0b withDefault \u5207\u6362\u5230\u5b50\u7ebf\u7a0b withUnconfined \u5207\u6362\u5230\u65e0\u9650\u5236\u8c03\u5ea6\u5668, \u5176\u53d6\u51b3\u4e8e\u4e0a\u4e00\u4e2a\u6267\u884c\u7684\u7ebf\u7a0b\u5207\u6362 launch \u65e0\u8fd4\u56de\u503c\u7684\u6302\u8d77\u51fd\u6570, \u53ef\u6307\u5b9a\u7ebf\u7a0b async \u6709\u8fd4\u56de\u503c\u7684\u6302\u8d77\u51fd\u6570, \u901a\u8fc7await()\u8fd4\u56de\u503c, \u53ef\u6307\u5b9a\u7ebf\u7a0b runMain \u5207\u6362\u5230\u4e3b\u7ebf\u7a0b, \u8be5\u51fd\u6570\u4e0d\u5c5e\u4e8e\u534f\u7a0b\u53ef\u4ee5\u5728\u4efb\u4f55\u5730\u65b9\u8c03\u7528
  • withXX() \u534f\u7a0b\u963b\u585e\u6302\u8d77
  • launch()/async() \u975e\u963b\u585e\u6267\u884c, \u4e24\u8005\u533a\u522b\u662f\u6709\u65e0\u8fd4\u56de\u503c
"},{"location":"timing.html","title":"\u9650\u65f6/\u5b9a\u65f6\u8bf7\u6c42","text":"

\u4ee5\u4e0b\u4e3a\u63d0\u4f9b\u5b9e\u73b0\u5b9a\u65f6/\u9650\u65f6\u8bf7\u6c42\u601d\u8def, \u5e76\u4e0d\u9650\u5b9a\u53ea\u6709\u4ee5\u4e0b\u65b9\u5f0f

"},{"location":"timing.html#_1","title":"\u9650\u65f6\u8bf7\u6c42","text":"

\u5373\u8d85\u8fc7\u6307\u5b9a\u65f6\u95f4\u540e\u7acb\u5373\u53d6\u6d88\u8bf7\u6c42

scopeDialog {\n// \u5f53\u63a5\u53e3\u8bf7\u6c42\u5728100\u6beb\u79d2\u5185\u6ca1\u6709\u5b8c\u6210\u4f1a\u629b\u51fa\u5f02\u5e38TimeoutCancellationException\nwithTimeout(100) {\nGet<String>(Api.PATH).await()\n}\n}.catch {\nLog.e(\"\u65e5\u5fd7\", \"\u8bf7\u6c42\u9519\u8bef\", it) // catch\u65e0\u6cd5\u63a5\u6536\u5230CancellationException\u5f02\u5e38\n}.finally {\nLog.e(\"\u65e5\u5fd7\", \"\u8bf7\u6c42\u5b8c\u6210\", it) // TimeoutCancellationException\u5c5e\u4e8eCancellationException\u5b50\u7c7b\u6545\u53ea\u4f1a\u88abfinally\u63a5\u6536\u5230\nif (it is TimeoutCancellationException) {\ntoast(\"\u7531\u4e8e\u672a\u5728\u6307\u5b9a\u65f6\u95f4\u5b8c\u6210\u8bf7\u6c42\u5219\u53d6\u6d88\u8bf7\u6c42\")\n}\n}\n
"},{"location":"timing.html#_2","title":"\u5b9a\u65f6\u8bf7\u6c42","text":"

\u6307\u5b9a\u8bf7\u6c4210\u6b21

scopeNetLife {\n// \u6bcf\u4e24\u79d2\u8bf7\u6c42\u4e00\u6b21, \u603b\u5171\u6267\u884c10\u6b21\nrepeat(20) {\ndelay(1000)\nval data = Get<String>(Api.PATH).await()\nif(it = 10) {\nreturn@repeat\n}\n}\n}\n

\u65e0\u9650\u5faa\u73af\u8bf7\u6c42, \u53ef\u4ee5\u6839\u636e\u67d0\u4e2a\u6761\u4ef6break\u9000\u51fa

scopeNetLife {\nwhile (true) {\ndelay(1.toDuration(DurationUnit.SECONDS))\nval data = Get<CONFIG>(Api.PATH).await()\nif(data.type = 3) {\nbreak\n}\n}\n}\n
"},{"location":"track.html","title":"\u5f02\u5e38\u8ffd\u8e2a","text":"

Net\u4e2d\u7f51\u7edc\u8bf7\u6c42\u5f02\u5e38\u4f1aLogCat\u8f93\u51fa, \u9664\u975e\u5f00\u53d1\u8005\u4fee\u6539\u5168\u5c40\u9519\u8bef\u5904\u7406

\u6f14\u793a\u8bbf\u95ee\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u8bf7\u6c42\u8def\u5f84

scopeNetLife {\ntvFragment.text = Get<String>(\"https://error.com/Net/\").await()\n}\n

LogCat\u53ef\u4ee5\u770b\u5230\u5f02\u5e38\u5806\u6808\u4fe1\u606f, \u5305\u542b\u5177\u4f53Url\u548c\u4ee3\u7801\u4f4d\u7f6e

"},{"location":"track.html#_1","title":"\u5173\u95ed\u65e5\u5fd7","text":"

\u53ef\u4ee5\u5173\u95ed\u65e5\u5fd7\u6253\u5370

NetConfig.initialize(Api.HOST, this) {\nsetDebug(false) // \u5173\u95ed\u65e5\u5fd7, \u4e00\u822c\u4f7f\u7528 BuildConfig.DEBUG\n}\n
"},{"location":"updates.html","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"updates.html#361","title":"3.6.1","text":"
  • fix: #197 \u4fee\u590dscopeDialog\u7684\u53ef\u53d6\u6d88\u5bf9\u8bdd\u6846\u9ed8\u8ba4\u503c
"},{"location":"updates.html#360","title":"3.6.0","text":"
  • pref: Optimize code
  • feat: contentLength\u672a\u77e5\u7684\u4e0a\u4f20\u5bf9\u8c61finish\u4e5f\u6709\u6548
  • pref: RunningCalls\u904d\u5386\u4f18\u5316
  • pref: \u8003\u8651\u5230Uri.toRequestBody\u8bfb\u53d6\u4e0d\u5230\u6587\u4ef6\u6216\u957f\u5ea6
  • refactor: \u5220\u9664\u5e9f\u5f03\u51fd\u6570
  • refactor: \u4e0b\u8f7d\u4e34\u65f6\u6587\u4ef6\u540d\u540e\u7f00\u6539\u6210.downloading
  • refactor: \u5220\u9664param(RequestBody, Header)
  • refactor: LogRecordInterceptor.kt
  • refactor: \u5220\u9664\u6709\u95ee\u9898\u7684\u53d6\u6d88\u8bf7\u6c42\u51fd\u6570
  • refactor: peekBytes\u7684\u9ed8\u8ba4\u8bfb\u53d6\u5927\u5c0f\u7edf\u4e00\u4e3a1MB
  • fix: \u4fee\u590d\u83b7\u53d6\u8bf7\u6c42\u5bf9\u8c61\u83b7\u53d6ID/Group\u9519\u8bef
  • fix: \u5168\u5c40\u53d6\u6d88\u8bf7\u6c42\u65f6\u53d1\u751fConvertException\u9519\u8bef\u63d0\u793a
  • fix: #187 \u4e0a\u4f20\u8fdb\u5ea6\u76d1\u542cfinish\u5b57\u6bb5\u65e0\u6548
"},{"location":"updates.html#359","title":"3.5.9","text":"
  • fix: \u4fee\u590dJava\u57fa\u7840\u7c7b\u578b\u6cdb\u578b\u89e3\u6790
"},{"location":"updates.html#358","title":"3.5.8","text":"
  • fix: \u5220\u9664\u6743\u9650 ACCESS_NETWORK_STATE, \u89e3\u51b3\u4e2a\u522b\u673a\u578b\u91cd\u590d\u7533\u8bf7\u95ee\u9898
  • upgrade: BRV 1.4.0
"},{"location":"updates.html#357","title":"3.5.7","text":"
  • fix: #165 \u6cdb\u578b\u64e6\u9664
"},{"location":"updates.html#356","title":"3.5.6","text":"
  • feat: \u65b0\u589e BaseRequest.execute \u975e\u5185\u8054\u51fd\u6570\u91cd\u8f7d
  • feat: Net.kt\u652f\u6301Java\u9759\u6001\u8c03\u7528
  • refactor: LogRecordInterceptor @JvmOverloads
  • fix: Interval.onlyResumed \u7ed3\u675f\u8f6e\u8be2
  • pref: \u5220\u9664\u8f6c\u6362\u5668\u83b7\u53d6\u7684\u53cd\u5c04\u8c03\u7528
"},{"location":"updates.html#355","title":"3.5.5","text":"
  • fix: #157 \u65e5\u5fd7\u62e6\u622a\u5668\u5931\u6548
"},{"location":"updates.html#354","title":"3.5.4","text":"
  • refactor: peekString rename to peekBytes, remove logString
  • fix: \u53ef\u80fd\u5b58\u5728\u7684\u5185\u5b58\u6cc4\u6f0f
"},{"location":"updates.html#353","title":"3.5.3","text":"
  • feat: \u9ed8\u8ba4\u4f7f\u7528NetDialogFactory\u7684setCancelable\u914d\u7f6e
  • fix: #150 scopeDialog\u9884\u89c8\u6a21\u5f0f
"},{"location":"updates.html#352","title":"3.5.2","text":"
  • fix: #135 Content-MD5\u672a\u4f7f\u7528Base64\u89e3\u7801
  • feat: \u65b0\u589e BaseRequest.headers
"},{"location":"updates.html#351","title":"3.5.1","text":"
  • feat: \u65b0\u589eparam\u65b9\u6cd5\u53c2\u6570Uri
  • feat: \u65b0\u589eaddQuery\u65b9\u6cd5
  • pref: \u4e0d\u6df7\u6dc6exception\u5305
  • fix: #129 \u8bf7\u6c42URL\u4e0d\u540c\u5bfc\u81f4setCacheKey\u65e0\u6548
"},{"location":"updates.html#350","title":"3.5.0","text":"
  • refactor: \u5220\u9664\u6743\u9650REQUEST_INSTALL_PACKAGES(\u8c37\u6b4c\u5546\u5e97\u6743\u9650\u8981\u6c42)
  • refactor: \u5220\u9664File.install
  • pref: \u6539\u4e3a\u4f7f\u7528AppStartup\u9ed8\u8ba4\u521d\u59cb\u5316
"},{"location":"updates.html#3414","title":"3.4.14","text":"
  • fix: Fragment\u672a\u521d\u59cb\u5316View\u6267\u884cscopeNetLife\u5bfc\u81f4\u7a7a\u6307\u9488
"},{"location":"updates.html#3413","title":"3.4.13","text":"
  • fix: #110 \u7f13\u5b58\u6a21\u5f0f\u4e0bRequest\u4fe1\u606f\u4e22\u5931
"},{"location":"updates.html#3412","title":"3.4.12","text":"
  • fix: FlowUtils.kt #102
"},{"location":"updates.html#3411","title":"3.4.11","text":"
  • fix: \u7f3a\u5931trace\u8bf7\u6c42\u65b9\u5f0f #99
"},{"location":"updates.html#3410","title":"3.4.10","text":"
  • fix: #91 \u4fee\u590dViewPager2\u7684\u89c6\u56fe\u751f\u547d\u5468\u671f\u5bfc\u81f4\u7f51\u7edc\u8bf7\u6c42\u88ab\u53d6\u6d88
  • fix: LogCat\u9519\u8bef\u53d1\u751f\u4f4d\u7f6e\u9ad8\u4eae
  • feat: brv 1.3.76
  • pref: DialogCoroutineScope
"},{"location":"updates.html#348","title":"3.4.8","text":"
  • fix: \u4e0d\u63d0\u4ea4null\u8bf7\u6c42\u53c2\u6570
"},{"location":"updates.html#347","title":"3.4.7","text":"
  • \u5347\u7ea7\u4f9d\u8d56
  • \u652f\u6301\u534f\u7a0b1.6.0
  • optimize Interval
  • EditText.debounce\u4e8b\u4ef6\u7c7b\u578b\u6539\u4e3aEditable
"},{"location":"updates.html#346","title":"3.4.6","text":"
  • \u65b0\u589e\u5f3a\u5236\u7f13\u5b58\u6709\u6548\u671f
"},{"location":"updates.html#345","title":"3.4.5","text":"
  • Fixed #88
  • Interval.life(Fragment)\u6539\u4e3aonDestroyView\u65f6\u9500\u6bc1
"},{"location":"updates.html#344","title":"3.4.4","text":"
  • \u65b0\u589eCookie\u7ba1\u7406
"},{"location":"updates.html#343","title":"3.4.3","text":"
  • \u4fee\u590dgzip\u5bfc\u81f4\u7684\u5f3a\u5236\u7f13\u5b58\u8bfb\u53d6\u5931\u8d25
  • \u4fee\u590dNoCacheException\u65e0\u6cd5\u6355\u83b7
  • \u54cd\u5e94\u53ef\u4ee5\u5224\u65ad\u662f\u5426\u6765\u81ea\u4e8e\u7f13\u5b58
  • \u4f18\u5316\u7f13\u5b58\u76f8\u5173\u4ee3\u7801
"},{"location":"updates.html#342","title":"3.4.2","text":"
  • \u4fee\u590dHttp\u7f13\u5b58\u534f\u8bae\u65e0\u6548
  • \u65e5\u5fd7\u62e6\u622a\u5668\u9519\u8bef\u4fe1\u606f\u7b80\u7565
"},{"location":"updates.html#341","title":"3.4.1","text":"
  • \u7981\u7528\u5931\u8d25\u7f13\u5b58
"},{"location":"updates.html#340","title":"3.4.0","text":"
  • \u65b0\u589e\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f
  • \u65b0\u589e\u9884\u89c8\u6a21\u5f0f(\u53ef\u5b9e\u73b0\u7f13\u5b58+\u7f51\u7edc)
"},{"location":"updates.html#331","title":"3.3.1","text":"
  • \u5e9f\u5f03\u90e8\u5206\u65e5\u5fd7\u76f8\u5173\u51fd\u6570
  • \u65b0\u589eNet.debug\u65e5\u5fd7\u8f93\u51fa\u51fd\u6570
  • \u4fee\u590dQuery\u7f16\u7801\u95ee\u9898
"},{"location":"updates.html#330","title":"3.3.0","text":"
  • \u5220\u9664Callback/onResult(\u7834\u574f\u6027\u8fc1\u79fb)
  • \u5220\u9664requestById/requestByGroup(\u7834\u574f\u6027\u8fc1\u79fb)
  • Add View.scopeNetLife
  • \u7f51\u7edc\u8bf7\u6c42\u5f02\u5e38\u4f4d\u7f6e\u8ffd\u8e2a
"},{"location":"updates.html#322","title":"3.2.2","text":"
  • Fixed #77
  • \u4fee\u590dgzip\u542f\u7528\u60c5\u51b5\u4e0b\u8f7d\u8fdb\u5ea6\u59cb\u7ec8\u4e3a0
  • Progress.finish()\u65b9\u6cd5\u6539\u4e3a\u5c5e\u6027
"},{"location":"updates.html#321","title":"3.2.1","text":"
  • Fixed #76
  • RequestBody?.peekString()\u51fd\u6570\u63a5\u53d7\u8005\u6539\u4e3a\u975e\u53ef\u7a7a\u7c7b\u578b
"},{"location":"updates.html#320","title":"3.2.0","text":"
  • \u66f4\u6539tag\u76f8\u5173\u51fd\u6570
  • \u66f4\u6539NetConfig.app\u7c7b\u578b\u6539\u4e3aContext
  • \u5220\u9664\u654f\u611f\u6743\u9650(\u5916\u90e8\u5b58\u50a8\u8bfb\u5199)
  • \u5220\u9664\u5e9f\u5f03\u51fd\u6570/\u63d0\u9ad8\u51fd\u6570\u5e9f\u5f03\u7b49\u7ea7
  • \u5e9f\u5f03NetConfig.init
  • \u5220\u9664fastest\u51fd\u6570\u63a5\u53d7\u8005
  • \u5220\u9664logRecord\u5c5e\u6027
  • \u4f18\u5316\u57df\u540d\u89e3\u6790\u9519\u8bef\u5f02\u5e38\u4fe1\u606f
  • \u65b0\u589e\u65e0\u7f51\u7edc\u4e0d\u53ef\u7528\u5f02\u5e38NetworkingException
  • \u65b0\u589e\u8f93\u51faMultiPart\u53c2\u6570\u65e5\u5fd7
  • \u66f4\u6539RetryInterceptor/LogRecordInterceptor\u5c5e\u6027\u8bbf\u95ee\u6743\u9650
"},{"location":"updates.html#312","title":"3.1.2","text":"
  • \u5347\u7ea7BRV\u81f31.3.51, \u5176\u5185\u90e8\u5347\u7ea7SmartRefreshLayout\u81f32.0.5. SmartRefreshLayout\u76f8\u5173\u4f9d\u8d56\u9700\u8981\u8fc1\u79fb
  • Interval\u6dfb\u52a0onlyResumed\u51fd\u6570
  • Interval\u4fee\u6539life\u51fd\u6570\u53c2\u6570\u4e3aFragmentActivity\u60c5\u51b5\u4e0b\u7684\u81ea\u52a8\u53d6\u6d88\u8f6e\u8be2\u5668\u7684\u751f\u547d\u5468\u671f
"},{"location":"updates.html#311","title":"3.1.1","text":"

\u5185\u5d4c\u6df7\u6dc6\u89c4\u5219, \u4e0d\u9700\u8981\u624b\u52a8\u6dfb\u52a0

"},{"location":"updates.html#310","title":"3.1.0","text":"
  • \u4fee\u590d\u90e8\u5206\u5b50\u7ebf\u7a0b\u5f00\u542f\u4f5c\u7528\u57df\u5d29\u6e83
  • \u7f51\u7edc\u5f02\u5e38\u5806\u6808\u4f7f\u7528 NetConfig.TAG \u4f5c\u4e3a\u6807\u7b7e, \u4f7f\u7528debug\u65e5\u5fd7\u7c7b\u578b\u8f93\u51fa
  • \u9ed8\u8ba4\u8f6c\u6362\u5668\u73b0\u5728\u8981\u6c42HTTP\u72b6\u6001\u7801\u4e3a\u6210\u529f\u624d\u8fd4\u56de\u6570\u636e(\u6cdb\u578bResponse\u8bf7\u6c42\u5b8c\u6210\u90fd\u8fd4\u56de)
  • \u5f00\u542f\u7f16\u8bd1\u5668\u5f3a\u5236\u66ff\u6362\u5e9f\u5f03\u51fd\u6570(\u53ef\u67e5\u770b\u51fd\u6570\u6ce8\u91ca\u66ff\u6362\u89c4\u5219)
  • \u7981\u6b62\u66b4\u9732\u5197\u4f59\u51fd\u6570
"},{"location":"updates.html#3027","title":"3.0.27","text":"
  • setDownloadDir\u51fd\u6570\u540c\u65f6\u652f\u6301\u5b8c\u6574\u8def\u5f84(\u5373\u5305\u542b\u6587\u4ef6\u540d\u79f0)\u548c\u4e0b\u8f7d\u76ee\u5f55
"},{"location":"updates.html#3026","title":"3.0.26","text":"
  • \u4f18\u5316\u8fd4\u56deByteArray\u7c7b\u578b\u6027\u80fd
  • setQuery\u51fd\u6570\u652f\u6301Number/Boolean\u7c7b\u578b
  • \u65b0\u589e\u4e00\u4e2a\u9519\u8bef\u63d0\u793a HttpFailureException
"},{"location":"updates.html#3025","title":"3.0.25","text":"
  • \u8f6e\u8be2\u5668\u652f\u6301ViewModel\u53d6\u6d88
  • \u4fee\u590d\u65e0\u6cd5\u8fd4\u56deByteArray\u7c7b\u578b\u95ee\u9898
  • \u95f4\u63a5\u4f9d\u8d56 update brv 1.3.37
  • \u66f4\u65b0\u51fd\u6570\u6ce8\u91ca
"},{"location":"updates.html#3024","title":"3.0.24","text":"

\u4fee\u590d\u4e0a\u4f20\u6587\u4ef6\u5305\u542b\u53c2\u6570\u65f6, \u7f16\u7801\u95ee\u9898\u5bfc\u81f4\u7684\u53c2\u6570\u9519\u8bef

"},{"location":"updates.html#3023","title":"3.0.23","text":"
  • \u4fee\u590d\u8f6e\u8be2\u5668\u91cd\u590dstart\u65e0\u6548\u95ee\u9898
  • Interval\u5176\u4ed6\u4f18\u5316
"},{"location":"updates.html#3021","title":"3.0.21","text":"
  • Interval\u6dfb\u52a0cancel\u51fd\u6570\u7528\u4e8e\u53d6\u6d88\u8ba1\u65f6\u5668, \u53d6\u6d88\u5b8c\u6210\u4e0d\u4f1a\u8c03\u7528finish
"},{"location":"updates.html#3020","title":"3.0.20","text":"
  • \u65b0\u589eHttpFailureException\u53ca\u5176\u5b50\u7c7b\u8868\u793a\u8bf7\u6c42\u5931\u8d25\u5f02\u5e38
  • \u65b0\u589eHttpResponseException\u53ca\u5176\u5b50\u7c7b\u8868\u793a\u8bf7\u6c42\u6210\u529f\u540e\u53d1\u751f\u7684\u5f02\u5e38
  • \u66f4\u65b0\u4f9d\u8d56\u5e93BRV\u81f31.3.31
"},{"location":"updates.html#3019","title":"3.0.19","text":"
  • \u66f4\u65b0\u4f9d\u8d56\u5e93BRV\u81f31.3.30
"},{"location":"updates.html#3018","title":"3.0.18","text":"
  • \u4fee\u590dResponse\u6d41\u5f02\u5e38\u5173\u95ed\u95ee\u9898
"},{"location":"updates.html#3017","title":"3.0.17","text":"
  • \u4fee\u590dProfiler\u5bfc\u81f4\u7684\u8bf7\u6c42\u95ee\u9898
"},{"location":"updates.html#3016","title":"3.0.16","text":"
  • \u65e5\u5fd7\u8bb0\u5f55\u5668\u4e2d\u8bf7\u6c42\u53c2\u6570\u9ed8\u8ba4\u4f7f\u7528URLDecoder\u89e3\u7801
"},{"location":"updates.html#3015","title":"3.0.15","text":"
  • \u4fee\u590dFileProvider\u51b2\u7a81
  • \u4e0a\u4f20\u6587\u4ef6\u65f6\u9ed8\u8ba4\u751f\u6210filename(\u5f53\u4f60\u672a\u6307\u5b9a\u6587\u4ef6\u540d\u60c5\u51b5\u4e0b)
  • NetCallback\u7f51\u7edc\u8bf7\u6c42\u88ab\u53d6\u6d88\u4e0d\u4f1a\u56de\u8c03onError
  • \u4e3aNetCallback\u6dfb\u52a0Request\u5bf9\u8c61
  • \u5220\u9664\u5185\u90e8Tooltip\u4f9d\u8d56
"},{"location":"updates.html#3014","title":"3.0.14","text":"
  • \u4fee\u590dKType\u7c7b\u578b\u95ee\u9898
  • \u652f\u6301File.install\u51fd\u6570\u5b89\u88c5\u5e94\u7528
"},{"location":"updates.html#3013","title":"3.0.13","text":"
  • \u4f18\u5316\u6807\u7b7e\u76f8\u5173\u51fd\u6570. \u6574\u4e2a\u7f51\u7edc\u751f\u547d\u5468\u671f\u53ef\u4ee5\u5b8c\u7f8e\u4f20\u9012\u53c2\u6570
  • NetCallback\u5177\u5907\u8ddf\u968f\u751f\u547d\u5468\u671f\u81ea\u52a8\u53d6\u6d88\u7f51\u7edc\u8bf7\u6c42
  • \u6269\u5c55NetCallback\u6765\u6dfb\u52a0DialogCallback/StateCallback/PageCallback
  • \u5e9f\u5f03\u90e8\u5206\u51fd\u6570, \u4f8b\u5982onDialog\u88ab\u5e9f\u5f03, \u73b0\u5728\u7531NetConfig.dialogFactory\u6784\u5efa\u5168\u5c40\u52a0\u8f7d\u5bf9\u8bdd\u6846
  • initNet\u73b0\u5728\u5e9f\u5f03, \u7531NetConfig.initialize\u53d6\u4ee3. \u6240\u6709\u914d\u7f6e\u4fe1\u606f\u7531NetConfig\u627f\u8f7d
  • RequestParamsException\u6dfb\u52a0\u9519\u8bef\u7801\u4fe1\u606f
"},{"location":"updates.html#3012","title":"3.0.12","text":"
  • \u4fee\u590d\u8f6c\u6362\u5668\u629b\u51fa\u7684\u5f02\u5e38\u5168\u90e8\u88abConvertException\u5305\u88f9\u7684\u95ee\u9898
  • NetException\u5b50\u7c7b\u4e0d\u4f1a\u88abConvertException\u5305\u88f9, \u6240\u4ee5\u8981\u6355\u83b7\u8f6c\u6362\u5668\u4e2d\u7684\u81ea\u5b9a\u4e49\u5f02\u5e38\u8bf7\u5176\u7ee7\u627fNetException
"},{"location":"updates.html#3011","title":"3.0.11","text":"
  • \u4fee\u590d\u4e34\u65f6\u4e0b\u8f7d\u6587\u4ef6\u9519\u8bef\u95ee\u9898
  • \u4fee\u590dViewModel\u4f5c\u7528\u57df\u590d\u7528\u95ee\u9898
"},{"location":"updates.html#3010","title":"3.0.10","text":"
  • \u5347\u7ea7Tooltip\u4f9d\u8d56, \u89e3\u51b3\u4f7f\u7528Tooltip_V1.1.1\u4f9d\u8d56\u65f6Net\u5b58\u5728\u5d29\u6e83\u95ee\u9898
"},{"location":"updates.html#309","title":"3.0.9","text":"
  • \u4f18\u5316\u8f6c\u6362\u5668\u5f02\u5e38\u5904\u7406
  • \u8f6c\u6362\u5668\u652f\u6301\u975e\u56fa\u5b9a\u683c\u5f0fJson\u89e3\u6790
"},{"location":"updates.html#307","title":"3.0.7","text":"
  • \u4fee\u590d\u672a\u77e5\u7684TypeToken\u8bbf\u95ee\u6743\u9650\u95ee\u9898
"},{"location":"updates.html#306","title":"3.0.6","text":"
  • \u6240\u6709Json\u89e3\u6790\u6846\u67b6\u90fd\u53ef\u4ee5\u89e3\u6790List<UserModel>\u7b49\u5d4c\u5957\u6cdb\u578b\u6570\u636e\u7ed3\u6784
"},{"location":"updates.html#305","title":"3.0.5","text":"
  • \u4fee\u590dPath\u7f16\u7801\u95ee\u9898
  • \u4e0a\u4f20File\u81ea\u52a8\u8bc6\u522bMediaType
"},{"location":"updates.html#304","title":"3.0.4","text":"
  • \u6dfb\u52a0MediaConst\u8868\u793a\u5e38\u7528MediaType
  • OkHttpBuilder\u6dfb\u52a0setErrorHandler\u53d6\u4ee3onError/onStateError: \u5168\u5c40\u9519\u8bef\u5904\u7406
  • \u63d0\u4f9b\u517c\u5bb9Android4.4(API level 19)\u7684\u7248\u672c: Net-okhttp3
"},{"location":"updates.html#303","title":"3.0.3","text":"
  • \u6dfb\u52a0onResult\u51fd\u6570\u6765\u6267\u884c\u961f\u5217\u8bf7\u6c42: \u961f\u5217\u8bf7\u6c42
  • \u6dfb\u52a0toResult\u51fd\u6570\u6765\u6267\u884c\u540c\u6b65\u8bf7\u6c42: \u540c\u6b65\u8bf7\u6c42
  • \u8bf7\u6c42\u4f53\u65e5\u5fd7\u652f\u6301JSON/\u6587\u672c\u7c7b\u578b
  • LogRecordInterceptor\u66b4\u9732requestString/responseString\u5b9e\u73b0\u51fd\u6570\u7528\u4e8e\u7ee7\u627f\u5b9e\u73b0\u81ea\u5b9a\u4e49\u9700\u6c42
"},{"location":"updates.html#302","title":"3.0.2","text":"

\u4fee\u590d\u591a\u6e20\u9053\u65e0\u6cd5\u5b89\u88c5\u95ee\u9898

"},{"location":"updates.html#301","title":"3.0.1","text":"
  • \u8f6c\u6362\u5668\u652f\u6301KType, \u89e3\u51b3JAVA\u6cdb\u578b\u64e6\u9664\u95ee\u9898
  • \u652f\u6301kotlin-serialization\u8f6c\u6362\u5668
  • \u4fee\u590dJSON\u8bf7\u6c42\u53c2\u6570\u7c7b\u578b\u95ee\u9898
"},{"location":"updates.html#30","title":"3.0","text":"
  • \u91cd\u6784\u4ee3\u7801, \u63d0\u5347\u7a33\u5b9a\u6027\u548c\u5b89\u5168\u6027.
  • \u652f\u6301OkHttp\u7684\u6240\u6709\u51fd\u6570/\u7ec4\u4ef6, \u53ef\u72ec\u7acb\u5347\u7ea7OkHttp\u7248\u672c
  • \u66f4\u52a0\u5f3a\u5927\u7684\u4e0b\u8f7d\u529f\u80fd
  • \u6240\u6709IO\u8bfb\u5199\u4f7f\u7528OKIO
  • \u66f4\u52a0\u4f18\u96c5\u7684\u51fd\u6570\u8bbe\u8ba1
"},{"location":"upload-file.html","title":"\u4e0a\u4f20\u6587\u4ef6","text":"
scopeNetLife {\nPost<String>(Api.UPLOAD) {\nparam(\"fileName\", assetsFile())\n}.await()\n}\n

\u4f7f\u7528addUploadListener\u6dfb\u52a0\u4e0a\u4f20\u8fdb\u5ea6\u76d1\u542c\u5668, \u9605\u8bfb\u8fdb\u5ea6\u76d1\u542c\u7ae0\u8282

"},{"location":"upload-file.html#_1","title":"\u6307\u5b9a\u7c7b\u578b","text":"

\u9ed8\u8ba4\u6839\u636e\u6587\u4ef6\u540e\u7f00\u540d\u751f\u6210MediaType, \u5982\u679c\u60f3\u81ea\u5b9a\u4e49MediaType\u53ef\u4ee5\u76f4\u63a5\u521b\u5efaRequestBody

scopeNetLife {\nPost<String>(Api.UPLOAD) {\nparam(\"file\", assetsFile().toRequestBody(\"image/webp\".toMediaType()))\n}.await()\n}\n
"},{"location":"upload-file.html#_2","title":"\u4e0a\u4f20\u7c7b\u578b","text":"

\u81ea\u5b9a\u4e49RequestBody\u53ef\u4ee5\u5b9e\u73b0\u4efb\u4f55\u6570\u636e\u7c7b\u578b\u7684\u4e0a\u4f20, \u4f46\u662fNet\u63d0\u4f9b\u5e38\u7528\u51fd\u6570\u7b80\u5316Uri/File\u4e0a\u4f20

scopeNetLife {\nPost<String>(Api.UPLOAD) {\n// MultiPart \u4e0a\u4f20\nparam(\"file\", Uri)\nparam(\"file\", File)\n// \u81ea\u5b9a\u4e49\u8bf7\u6c42\u4f53, \u4f1a\u8986\u76d6\u4ee5\u4e0a\u6240\u6709\u8bf7\u6c42\u5185\u5bb9\nbody = CustomizerRequestBody()\n}.await()\n}\n

\u76f4\u63a5\u4e0a\u4f20InputStream\u8f93\u5165\u6d41\u5c5e\u4e8e\u4e0d\u5b89\u5168\u884c\u4e3a, \u5efa\u8bae\u4f60\u4fdd\u5b58\u5230\u6587\u4ef6\u540e\u4e0a\u4f20, \u8be6\u7ec6\u8bf7\u9605\u8bfb: \u4f7f\u7528\u6587\u4ef6\u6d41\u4e0a\u4f20\u6587\u4ef6

"},{"location":"view-model.html","title":"ViewModel","text":"

Net\u652f\u6301\u5728ViewModel\u4e2d\u521b\u5efa\u7f51\u7edc\u8bf7\u6c42/\u5f02\u6b65\u4efb\u52a1

\u4e0d\u63a8\u8350

  1. \u7f51\u7edc\u8bf7\u6c42\u4e0d\u4e00\u5b9a\u8981\u5199\u5728ViewModel
  2. \u7f51\u7edc\u8bf7\u6c42\u4e0d\u8981\u5199\u63a5\u53e3\u56de\u8c03
  3. \u53ef\u4ee5\u5728Activity\u4e2d\u76f4\u63a5\u8fd4\u56de\u8bf7\u6c42\u7ed3\u679c
"},{"location":"view-model.html#_1","title":"\u81ea\u52a8\u751f\u547d\u5468\u671f","text":"
  • \u793a\u4f8b\u4ee3\u7801

\u4f7f\u7528scopeXXLife()\u521b\u5efa\u4f5c\u7528\u57df, \u5728ViewModel\u88ab\u9500\u6bc1\u65f6\u81ea\u52a8\u53d6\u6d88\u8bf7\u6c42

class UserViewModel : ViewModel() {\n// \u7528\u6237\u4fe1\u606f\nprivate var userInfo: MutableLiveData<String> = MutableLiveData()\n/**\n     * \u4f7f\u7528LiveData\u63a5\u53d7\u8bf7\u6c42\u7ed3\u679c, \u5c06\u8be5liveData\u76f4\u63a5\u4f7f\u7528DataBinding\u7ed1\u5b9a\u5230\u9875\u9762\u4e0a, \u4f1a\u5728\u8bf7\u6c42\u6210\u529f\u81ea\u52a8\u66f4\u65b0\u89c6\u56fe\n     */\nfun fetchUserInfo() = scopeNetLife {\nuserInfo.value = Get<String>(Api.GAME).await()\n}\n/**\n     * \u5f00\u59cb\u975e\u963b\u585e\u5f02\u6b65\u4efb\u52a1\n     *  \u8fd4\u56deDeferred, \u8c03\u7528await()\u624d\u4f1a\u8fd4\u56de\u7ed3\u679c\n     */\nfun fetchList(scope: CoroutineScope) = scope.Get<String>(Api.TEST)\n/**\n     * \u5f00\u59cb\u963b\u585e\u5f02\u6b65\u4efb\u52a1\n     * \u76f4\u63a5\u8fd4\u56de\u7ed3\u679c\n     */\nsuspend fun fetchPrecessData() = coroutineScope {\nval response = Get<String>(Api.TEST).await()\nresponse + \"\u5904\u7406\u6570\u636e\"\n}\n}\n
"}]} \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 000000000..f4f2e4dd0 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-,:!=\\[\\]()\"/]+|(?!\\b)(?=[A-Z][a-z])|\\.(?!\\d)|&[lg]t;","pipeline":["stemmer"]},"docs":[{"location":"index.html","title":"\u4f7f\u7528","text":"

Net\u662f\u57fa\u4e8eOkHttp/\u534f\u7a0b\u7684\u975e\u4fb5\u5165\u5f0f\u6846\u67b6(\u53ef\u4f7f\u7528\u6240\u6709Api), \u53ef\u5347\u7ea7OkHttp\u7248\u672c\u4fdd\u6301\u7f51\u7edc\u5b89\u5168

STAR/\u5206\u4eab\u53ef\u4ee5\u8ba9\u66f4\u591a\u4eba\u53c2\u4e0e\u5230\u672c\u5f00\u6e90\u9879\u76ee

\u524d\u8a00

  • \u672a\u5b9e\u73b0\u529f\u80fd\u53ef\u4ee5\u641c\u7d22\"OkHttp\u5982\u4f55XX\"\u6765\u6269\u5c55
  • \u9605\u8bfb\u793a\u4f8b/\u6e90\u7801\u6765\u5b66\u4e60\u5982\u4f55\u5c01\u88c5
  • \u5982\u679c\u89c9\u5f97\u6587\u6863\u770b\u4e0d\u61c2\u90a3\u80af\u5b9a\u662f\u4f5c\u8005\u95ee\u9898, \u8bf7\u53cd\u9988\u7ed9\u4f5c\u8005\u6216\u8005\u81ea\u6211\u4fee\u8ba2
"},{"location":"index.html#_1","title":"\u4f7f\u7528","text":"

\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\u7684\u4e09\u4e2a\u6b65\u9aa4

  1. \u521b\u5efa\u4f5c\u7528\u57df
  2. \u53d1\u8d77\u8bf7\u6c42\u52a8\u4f5c
  3. \u7b49\u5f85\u6570\u636e\u8fd4\u56de
\u7b80\u5355\u8bf7\u6c42\u540c\u6b65\u8bf7\u6c42\u5e76\u53d1\u8bf7\u6c42
scopeNetLife {\n// \u5927\u62ec\u53f7\u5185\u5c5e\u4e8e\u4f5c\u7528\u57df\nval data = Get<String>(Api.USER).await() // \u53d1\u8d77GET\u8bf7\u6c42\u5e76\u8fd4\u56de`String`\n}\n
scopeNetLife {\n// B\u5c06\u7b49\u5f85A\u8bf7\u6c42\u8fd4\u56de\u7ed3\u679c\u540e\u53d1\u8d77\u8bf7\u6c42\nval userInfo = Get<UserInfo>(Api.USER).await() // A\nval config = Get<Config>(Api.CONFIG){ // B\nparam(\"userId\", userInfo.id) // \u5c06\u4e0a\u4e2a\u8bf7\u6c42\u7ed3\u679c\u4f5c\u4e3a\u53c2\u6570\n}.await()\n}\n
scopeNetLife {\n// \u4e24\u4e2a\u8bf7\u6c42\u540c\u65f6\u53d1\u8d77\nval getUserInfoAsync = Get<UserInfo>(Api.USER)\nval getConfigAsync = Get<Config>(Api.CONFIG)\nval userInfo = getUserInfoAsync.await() // \u7b49\u5f85\u6570\u636e\u8fd4\u56de\nval config = getConfigAsync.await()\n}\n
  1. \u591a\u4e2a\u7f51\u7edc\u8bf7\u6c42\u5728\u540c\u4e00\u4e2a\u4f5c\u7528\u57df\u5185\u53ef\u4ee5\u7edf\u4e00\u7ba1\u7406
  2. \u5982\u679c\u591a\u4e2a\u7f51\u7edc\u8bf7\u6c42\u4e4b\u95f4\u6beb\u65e0\u5173\u8054, \u53ef\u4ee5\u521b\u5efa\u591a\u4e2a\u4f5c\u7528\u57df\u6765\u8bf7\u6c42

\u5f3a\u5236\u521d\u59cb\u5316

\u591a\u8fdb\u7a0b\u6216Xposed\u9879\u76ee\u8981\u6c42\u5148\u521d\u59cb\u5316

\u81ea\u52a8\u8bc6\u522bUrl\u6216\u8005Path\u8bf7\u6c42

scopeNetLife {\nval userInfo = Get<String>(\"/net\").await()\nval config = Get<String>(\"https://github.com/liangjingkanji/net\").await()\n}\n
"},{"location":"index.html#_2","title":"\u8fd4\u56de\u7ed3\u679c","text":"

\u8fd4\u56de\u7ed3\u679c\u652f\u6301\u7684\u6570\u636e\u7c7b\u578b(\u5373Post\u7b49\u51fd\u6570\u7684\u6cdb\u578b)\u7531\u8f6c\u6362\u5668\u51b3\u5b9a, \u9ed8\u8ba4\u652f\u6301\u4ee5\u4e0b\u7c7b\u578b

\u51fd\u6570 \u63cf\u8ff0 String \u5b57\u7b26\u4e32 ByteArray \u5b57\u8282\u6570\u7ec4 ByteString \u5185\u90e8\u5b9a\u4e49\u7684\u4e00\u79cd\u5b57\u7b26\u4e32\u5bf9\u8c61 Response \u6700\u57fa\u7840\u7684\u54cd\u5e94 File \u6587\u4ef6\u5bf9\u8c61, \u8fd9\u79cd\u60c5\u51b5\u5176\u5b9e\u5e94\u5f53\u79f0\u4e3a\u4e0b\u8f7d\u6587\u4ef6
scopeNetLife {\nval file = Get<File>(Api.FILE).await()\n}\n

\u8be6\u7ec6\u67e5\u770b\u8f6c\u6362\u5668, \u975e\u4ee5\u4e0a\u7c7b\u578b\u8981\u6c42\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668

\u4e0b\u8f7dApk \u4e0b\u8f7d\u6e90\u7801 \u793a\u4f8b\u4ee3\u7801 \u754c\u9762\u6f14\u793a

"},{"location":"auto-dialog.html","title":"\u81ea\u52a8\u52a0\u8f7d\u6846","text":"

Net\u652f\u6301\u53d1\u8d77\u8bf7\u6c42\u5f00\u59cb\u65f6\u663e\u793a\u52a0\u8f7d\u6846, \u8bf7\u6c42\u7ed3\u675f\u65f6\u9690\u85cf\u52a0\u8f7d\u6846(\u65e0\u8bba\u6210\u8d25)

"},{"location":"auto-dialog.html#_1","title":"\u81ea\u52a8\u663e\u793a","text":"
scopeDialog {\ntvFragment.text = Post<String>(\"dialog\") {\nparam(\"username\", \"\u7528\u6237\u540d\") // \u8bf7\u6c42\u53c2\u6570\nparam(\"pwd\", \"123456\")\n}.await()\n}\n

\u9ed8\u8ba4\u662f\u539f\u751f\u52a0\u8f7d\u6846(MaterialDesign Dialog), \u53ef\u81ea\u5b9a\u4e49

"},{"location":"auto-dialog.html#_2","title":"\u5355\u4f8b\u81ea\u5b9a\u4e49","text":"

\u6307\u5b9a\u5f53\u524d\u8bf7\u6c42\u52a0\u8f7d\u6846

val dialog = BubbleDialog(requireActivity(), \"\u52a0\u8f7d\u4e2d\")\nscopeDialog(dialog) {\nbinding.tvFragment.text = Post<String>(\"dialog\") {\nparam(\"username\", \"\u7528\u6237\u540d\")\nparam(\"pwd\", \"123456\")\n}.await()\n}\n

\u83ca\u82b1\u52a0\u8f7d\u5bf9\u8bdd\u6846

\u793a\u4f8b\u4f7f\u7528\u7684iOS\u98ce\u683c\u5bf9\u8bdd\u6846: BubbleDialog

"},{"location":"auto-dialog.html#_3","title":"\u5168\u5c40\u81ea\u5b9a\u4e49","text":"

\u521d\u59cb\u5316\u65f6\u6307\u5b9a\u52a0\u8f7d\u5bf9\u8bdd\u6846\u6784\u9020\u5668NetDialogFactory

NetConfig.initialize(Api.HOST, this) {\nsetDialogFactory {\nProgressDialog(it).apply {\nsetMessage(\"\u6211\u662f\u5168\u5c40\u81ea\u5b9a\u4e49\u7684\u52a0\u8f7d\u5bf9\u8bdd\u6846...\")\n}\n}\n}\n

\u5982\u4ec5\u4fee\u6539\u52a0\u8f7d\u5bf9\u8bdd\u6846\u6587\u672c, \u5728\u9879\u76eevalues\u76ee\u5f55\u7684strings.xml\u6dfb\u52a0\u4ee5\u4e0b

<!--\u5bf9\u8bdd\u6846-->\n<string name=\"net_dialog_msg\">\u52a0\u8f7d\u4e2d</string>\n

\u81ea\u5b9a\u4e49\u7684\u52a0\u8f7d\u6846\u4e0d\u662fDialog

\u7531\u4e8escopeDialog\u53ea\u80fd\u6307\u5b9aDialog\u7c7b\u578b, \u56e0\u6b64\u53ea\u80fd\u624b\u52a8\u5b9e\u73b0Dialog\u63a5\u53e3

\u4ec5\u8981\u6c42\u590d\u5199 DialogCoroutineScope \u5185\u8c03\u7528\u7684Dialog\u65b9\u6cd5

"},{"location":"auto-dialog.html#_4","title":"\u751f\u547d\u5468\u671f","text":"

\u4f7f\u7528scopeDialog\u53d1\u8d77\u8bf7\u6c42\u540e, \u5206\u4e3a\u4e09\u4e2a\u751f\u547d\u5468\u671f

\u52a0\u8f7d\u6846\u72b6\u6001 \u4f5c\u7528\u57df \u663e\u793a \u6267\u884cscopeDialog\u65f6\u663e\u793a\u52a0\u8f7d\u6846 \u9690\u85cf \u4f5c\u7528\u57df\u5185\u4efb\u52a1\u7ed3\u675f\u65f6\u9690\u85cf\u52a0\u8f7d\u6846 \u624b\u52a8\u53d6\u6d88 \u53d6\u6d88\u4f5c\u7528\u57df\u5185\u6240\u6709\u7f51\u7edc\u8bf7\u6c42"},{"location":"auto-pull.html","title":"\u81ea\u52a8\u5206\u9875\u52a0\u8f7d","text":"

\u9996\u5148\u8bf7\u9605\u8bfb\u4e0a\u7ae0\u8282 \u81ea\u52a8\u4e0b\u62c9\u5237\u65b0, \u5df2\u63d0\u53ca\u5185\u5bb9\u4e0d\u518d\u91cd\u590d

"},{"location":"auto-pull.html#_1","title":"\u81ea\u52a8\u5206\u9875","text":"

\u63d0\u4f9baddData()\u6765\u7b80\u5316\u5206\u9875, \u5f00\u53d1\u8005\u53ef\u4ee5\u501f\u9274\u5b9e\u73b0

page.onRefresh {\nscope {\nval data = Get<ListModel>(\"list\") {\nparam(\"page\", index)\n}.await().data\naddData(data.list) {\nindex < data.total\n}\n}\n}.autoRefresh()\n
"},{"location":"auto-pull.html#_2","title":"\u7d22\u5f15\u81ea\u589e","text":"

index \u6bcf\u6b21\u4e0a\u62c9\u52a0\u8f7d\u81ea\u52a8++1, \u5237\u65b0\u5217\u8868\u91cd\u7f6e\u4e3aPageRefreshLayout.startIndex

"},{"location":"auto-pull.html#_3","title":"\u6709\u66f4\u591a\u9875","text":"

\u6839\u636ehasMore\u8fd4\u56de\u7ed3\u679c\u662f\u5426\u5173\u95ed\u4e0a\u62c9\u52a0\u8f7d, isEmpty\u51b3\u5b9a\u662f\u5426\u663e\u793a\u7a7a\u6570\u636e\u7f3a\u7701\u9875

fun addData(\ndata: List<Any?>?,\nadapter: BindingAdapter? = null,\nisEmpty: () -> Boolean = { data.isNullOrEmpty() },\nhasMore: BindingAdapter.() -> Boolean = { true }\n)\n

1. PageRefreshLayout \u4e0b\u62c9\u5237\u65b0/\u4e0a\u62c9\u52a0\u8f7d

"},{"location":"auto-refresh.html","title":"\u81ea\u52a8\u4e0b\u62c9\u5237\u65b0","text":"

\u6a21\u5757\u5316\u4f9d\u8d56

\u5982\u679c\u81ea\u5df1\u5904\u7406\u4e0b\u62c9\u5237\u65b0\u53ef\u8df3\u8fc7\u672c\u7ae0, Net\u53ef\u4ee5\u4ec5\u4ec5\u4f5c\u4e3a\u7b80\u5355\u7684\u7f51\u7edc\u6846\u67b6\u5b58\u5728

Net\u53ef\u4f9d\u8d56\u4e09\u65b9\u5e93 BRV \u5b9e\u73b0\u81ea\u52a8\u5904\u7406\u4e0b\u62c9\u5237\u65b0

implementation 'com.github.liangjingkanji:BRV:+' // \u4f7f\u7528\u56fa\u5b9a\u7248\u672c\u53f7\u66ff\u6362+\u7b26\u53f7\n
"},{"location":"auto-refresh.html#pagerefreshlayout","title":"PageRefreshLayout","text":"
<com.drake.brv.PageRefreshLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\nxmlns:tools=\"http://schemas.android.com/tools\"\nxmlns:app=\"http://schemas.android.com/apk/res-auto\"\nandroid:id=\"@+id/page\"\nandroid:layout_width=\"match_parent\"\nandroid:layout_height=\"match_parent\"\ntools:context=\".ui.fragment.PushRefreshFragment\">\n<androidx.recyclerview.widget.RecyclerView\nandroid:id=\"@+id/rv_push\"\nandroid:layout_width=\"match_parent\"\nandroid:layout_height=\"match_parent\" />\n</com.drake.brv.PageRefreshLayout>\n
"},{"location":"auto-refresh.html#_1","title":"\u521b\u5efa\u5217\u8868","text":"
rv_push.linear().setup {\naddType<String>(R.layout.item_list)\n}\n
"},{"location":"auto-refresh.html#_2","title":"\u7f51\u7edc\u8bf7\u6c42","text":"
  1. \u8bf7\u6c42\u5f00\u59cb, \u663e\u793a\u4e0b\u62c9\u5237\u65b0\u52a8\u753b
  2. \u8bf7\u6c42\u6210\u529f, \u663e\u793a\u5185\u5bb9\u7f3a\u7701\u9875
  3. \u8bf7\u6c42\u5931\u8d25, \u663e\u793a\u9519\u8bef\u7f3a\u7701\u9875
page.onRefresh {\nscope {\n// \u8bf7\u6c42\u5230\u6570\u636e\u8bbe\u7f6e\u5230RecyclerView\nrv_push.models = Get<ListModel>(\"list\").await().data.list\n}\n}.autoRefresh()\n
"},{"location":"auto-refresh.html#_3","title":"\u751f\u547d\u5468\u671f","text":"\u751f\u547d\u5468\u671f \u63cf\u8ff0 \u5f00\u59cb showLoading/autoRefresh\u89e6\u53d1onRefresh, \u5f00\u59cb\u8bf7\u6c42 \u7ed3\u675f PageRefreshLayout\u88ab\u9500\u6bc1, \u8bf7\u6c42\u81ea\u52a8\u53d6\u6d88"},{"location":"auto-state.html","title":"\u81ea\u52a8\u7f3a\u7701\u9875","text":"

\u6a21\u5757\u5316\u4f9d\u8d56

\u5982\u679c\u81ea\u5df1\u5904\u7406\u7f3a\u7701\u9875\u53ef\u8df3\u8fc7\u672c\u7ae0, Net\u53ef\u4ee5\u4ec5\u4ec5\u4f5c\u4e3a\u7b80\u5355\u7684\u7f51\u7edc\u6846\u67b6\u5b58\u5728

Net\u53ef\u4f9d\u8d56\u4e09\u65b9\u5e93\u5b9e\u73b0\u81ea\u52a8\u7f3a\u7701\u9875, \u4ee5\u4e0b\u4e8c\u9009\u4e00\u4f9d\u8d56

  1. \u4f9d\u8d56 StateLayout
    implementation 'com.github.liangjingkanji:StateLayout:+' // \u4f7f\u7528\u56fa\u5b9a\u7248\u672c\u53f7\u66ff\u6362+\u7b26\u53f7\n
  2. \u4f9d\u8d56 BRV (\u56e0\u4e3aBRV\u5305\u542bStateLayout)
    implementation 'com.github.liangjingkanji:BRV:+' // \u4f7f\u7528\u56fa\u5b9a\u7248\u672c\u53f7\u66ff\u6362+\u7b26\u53f7\n
"},{"location":"auto-state.html#_1","title":"\u521d\u59cb\u5316","text":"

\u5728Application\u4e2d\u521d\u59cb\u5316\u7f3a\u7701\u9875

StateConfig.apply {\nemptyLayout = R.layout.layout_empty\nloadingLayout = R.layout.layout_loading\nerrorLayout = R.layout.layout_error\n}\n
"},{"location":"auto-state.html#_2","title":"\u521b\u5efa","text":"

\u4f7f\u7528StateLayout\u5305\u88f9\u7684\u5185\u5bb9\u5373\u5185\u5bb9(content)

<com.drake.statelayout.StateLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\nxmlns:tools=\"http://schemas.android.com/tools\"\nandroid:layout_width=\"match_parent\"\nandroid:id=\"@+id/state\"\nandroid:layout_height=\"match_parent\"\ntools:context=\".ui.fragment.StateLayoutFragment\">\n<TextView\nandroid:id=\"@+id/tvFragment\"\nandroid:padding=\"32dp\"\nandroid:textStyle=\"bold\"\nandroid:layout_width=\"match_parent\"\nandroid:layout_height=\"match_parent\"\nandroid:text=\"\u5185\u5bb9\" />\n</com.drake.statelayout.StateLayout>\n
"},{"location":"auto-state.html#_3","title":"\u7f51\u7edc\u8bf7\u6c42","text":"
  1. \u8bf7\u6c42\u5f00\u59cb, \u663e\u793a\u52a0\u8f7d\u4e2d\u7f3a\u7701\u9875
  2. \u8bf7\u6c42\u6210\u529f, \u663e\u793a\u5185\u5bb9\u7f3a\u7701\u9875
  3. \u8bf7\u6c42\u5931\u8d25, \u663e\u793a\u9519\u8bef\u7f3a\u7701\u9875

state.onRefresh {\nscope {\ntvFragment.text = Get<String>(\"api\").await()\n}\n}.showLoading()\n

"},{"location":"auto-state.html#_4","title":"\u751f\u547d\u5468\u671f","text":"\u751f\u547d\u5468\u671f \u63cf\u8ff0 \u5f00\u59cb showLoading\u89e6\u53d1onRefresh, \u5f00\u59cb\u8bf7\u6c42 \u7ed3\u675f \u7f3a\u7701\u9875\u88ab\u9500\u6bc1, \u8bf7\u6c42\u81ea\u52a8\u53d6\u6d88"},{"location":"cache.html","title":"\u7f13\u5b58","text":""},{"location":"cache.html#_1","title":"\u7f13\u5b58\u4f18\u52bf","text":"
  1. \u9875\u9762\u79d2\u5f00
  2. \u51cf\u5c11\u670d\u52a1\u5668\u538b\u529b
  3. \u65e0\u7f51\u7edc\u53ef\u7528
"},{"location":"cache.html#net","title":"Net\u7f13\u5b58\u7279\u70b9","text":"
  1. \u7f13\u5b58\u4efb\u4f55\u8bf7\u6c42\u65b9\u5f0f
  2. \u7f13\u5b58\u4efb\u4f55\u6570\u636e, File/\u56fe\u7247/JSON/ProtoBuf\u7b49
  3. \u9650\u5236\u6700\u5927\u7f13\u5b58\u7a7a\u95f4
  4. \u4f7f\u7528DiskLruCache\u5b9e\u73b0, \u5220\u9664\u6700\u8fd1\u6700\u5c11\u4f7f\u7528
"},{"location":"cache.html#_2","title":"\u914d\u7f6e\u7f13\u5b58","text":"

\u4e0d\u914d\u7f6eCache\u662f\u4e0d\u4f1a\u542f\u7528\u7f13\u5b58\u7684

NetConfig.initialize(Api.HOST, this) {\n// Net\u652f\u6301Http\u7f13\u5b58\u534f\u8bae\u548c\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\n// \u5f53\u8d85\u8fc7maxSize\u6700\u5927\u503c\u4f1a\u6839\u636e\u6700\u8fd1\u6700\u5c11\u4f7f\u7528\u7b97\u6cd5\u6e05\u9664\u7f13\u5b58\u6765\u9650\u5236\u7f13\u5b58\u5927\u5c0f\ncache(Cache(cacheDir, 1024 * 1024 * 128))\n}\n

\u5224\u65ad\u54cd\u5e94\u6765\u81ea\u7f13\u5b58

\u5982\u679cResponse.cacheResponse\u4e0d\u4e3anull\u7684\u65f6, \u4ee3\u8868Response\u6765\u81ea\u672c\u5730\u7f13\u5b58

"},{"location":"cache.html#http","title":"Http\u7f13\u5b58\u534f\u8bae","text":"

OkHttp\u9ed8\u8ba4\u7684Http\u7f13\u5b58\u534f\u8bae\u63a7\u5236, \u8981\u6c42\u4ee5\u4e0b\u6761\u4ef6

  • Get\u8bf7\u6c42\u65b9\u5f0f
  • \u7f13\u5b58\u4f7f\u7528Url\u4e3akey, \u56e0\u6b64Url\u6539\u53d8\u4f1a\u8bfb\u4e0d\u5230\u7f13\u5b58
  • \u54cd\u5e94\u5934\u63a7\u5236\u7f13\u5b58: Cache-Control

\u901a\u8fc7setCacheControl\u53ef\u4ee5\u63a7\u5236Http\u7f13\u5b58\u534f\u8bae(\u539f\u7406\u662f\u6dfb\u52a0\u8bf7\u6c42\u5934)

scopeNetLife {\nPost<String>(\"api\") {\nsetCacheControl(CacheControl.FORCE_CACHE) // \u5f3a\u5236\u4f7f\u7528\u7f13\u5b58\n// setCacheControl(CacheControl.FORCE_NETWORK) // \u5f3a\u5236\u4f7f\u7528\u7f51\u7edc\n// setCacheControl(CacheControl.Builder().noStore().noCache().build()) // \u5b8c\u5168\u7981\u6b62\u8bfb\u53d6/\u5199\u5165\u7f13\u5b58\n}.await()\n}\n

\u5982\u679c\u65e0\u6cd5\u5b9e\u73b0Http\u6807\u51c6\u7f13\u5b58\u534f\u8bae, \u6216\u8981\u7f13\u5b58Get\u4ee5\u5916\u7684\u8bf7\u6c42\u65b9\u6cd5, \u53ef\u4ee5\u4f7f\u7528\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u6765\u7531\u5ba2\u6237\u7aef\u63a7\u5236\u7f13\u5b58

"},{"location":"cache.html#_3","title":"\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f","text":"

\u65e0\u8bba\u8bf7\u6c42\u662f\u5426\u5b58\u5728Http\u6807\u51c6\u7f13\u5b58\u534f\u8bae, \u5f53\u4f60\u8bbe\u7f6e\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u65f6\u5176\u4f1a\u65e0\u89c6Http\u6807\u51c6\u7f13\u5b58\u534f\u8bae

scopeNetLife {\nbinding.tvFragment.text =\nPost<String>(\"api\") {\nsetCacheMode(CacheMode.REQUEST_THEN_READ) // \u8bf7\u6c42\u7f51\u7edc\u5931\u8d25\u4f1a\u8bfb\u53d6\u7f13\u5b58, \u8bf7\u65ad\u7f51\u6d4b\u8bd5\n}.await()\n}\n
\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f \u63cf\u8ff0 READ \u53ea\u8bfb\u53d6\u7f13\u5b58, \u8bfb\u4e0d\u5230NoCacheException WRITE \u53ea\u8bf7\u6c42\u7f51\u7edc, \u5f3a\u5236\u5199\u5165\u7f13\u5b58 READ_THEN_REQUEST \u5148\u4ece\u7f13\u5b58\u8bfb\u53d6\uff0c\u5982\u679c\u5931\u8d25\u518d\u4ece\u7f51\u7edc\u8bfb\u53d6, \u5f3a\u5236\u5199\u5165\u7f13\u5b58 REQUEST_THEN_READ \u5148\u4ece\u7f51\u7edc\u8bfb\u53d6\uff0c\u5982\u679c\u5931\u8d25\u518d\u4ece\u7f13\u5b58\u8bfb\u53d6, \u5f3a\u5236\u5199\u5165\u7f13\u5b58"},{"location":"cache.html#key","title":"\u81ea\u5b9a\u7f13\u5b58Key","text":"

\u4ec5\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u6709\u6548, \u7f13\u5b58Key\u9ed8\u8ba4\u662f\u8bf7\u6c42\u65b9\u5f0f+URL\u540e\u4ea7\u751f\u7684sha1\u503c

\u5982\u679c\u8981\u7f13\u5b58\u533a\u522b\u8bf7\u6c42\u53c2\u6570, \u8bf7\u81ea\u5b9a\u4e49\u7f13\u5b58key

scopeNetLife {\nbinding.tvFragment.text =\nPost<String>(\"api\") {\nsetCacheMode(CacheMode.REQUEST_THEN_READ) // \u8bf7\u6c42\u7f51\u7edc\u5931\u8d25\u4f1a\u8bfb\u53d6\u7f13\u5b58, \u8bf7\u65ad\u7f51\u6d4b\u8bd5\nsetCacheKey(\"\u8bf7\u6c42\u70ed\u95e8\u4fe1\u606f\" + params) // \u5177\u4f53\u503c\u90fd\u884c\n}.await()\n}\n
"},{"location":"cache.html#_4","title":"\u7f13\u5b58\u6709\u6548\u671f","text":"
  1. \u4ec5\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f\u6709\u6548, \u6807\u51c6Http\u7f13\u5b58\u534f\u8bae\u9075\u5b88\u534f\u8bae\u672c\u8eab\u7684\u6709\u6548\u671f
  2. \u7f13\u5b58\u6709\u6548\u671f\u8fc7\u671f\u53ea\u662f\u8ba9\u7f13\u5b58\u65e0\u6548, \u4e0d\u4f1a\u7acb\u5373\u5220\u9664 \u6839\u636e(\u6700\u8fd1\u6700\u5c11\u4f7f\u7528)\u539f\u5219\u5728\u7f13\u5b58\u7a7a\u95f4\u8fbe\u5230\u914d\u7f6e\u503c\u65f6\u5220\u9664(\u5373\u4f7f\u7f13\u5b58\u6709\u6548\u671f\u672a\u5230)
scopeNetLife {\nbinding.tvFragment.text =\nPost<String>(\"api\") {\nsetCacheMode(CacheMode.REQUEST_THEN_READ) // \u8bf7\u6c42\u7f51\u7edc\u5931\u8d25\u4f1a\u8bfb\u53d6\u7f13\u5b58, \u8bf7\u65ad\u7f51\u6d4b\u8bd5\nsetCacheValidTime(1, TimeUnit.DAYS) // \u7f13\u5b58\u4ec5\u4e00\u5929\u5185\u6709\u6548\n}.await()\n}\n
"},{"location":"cache.html#_5","title":"\u9884\u89c8(\u7f13\u5b58+\u7f51\u7edc)","text":"

\u9884\u89c8\u53c8\u53ef\u4ee5\u7406\u89e3\u4e3a\u56de\u9000\u8bf7\u6c42, \u4e00\u822c\u7528\u4e8e\u79d2\u5f00\u9996\u9875\u6216\u8005\u56de\u9000\u52a0\u8f7d\u6570\u636e

scopeNetLife {\n// \u7136\u540e\u6267\u884c\u8fd9\u91cc(\u7f51\u7edc\u8bf7\u6c42)\nbinding.tvFragment.text = Get<String>(\"api\") {\nsetCacheMode(CacheMode.WRITE)\n}.await()\nLog.d(\"\u65e5\u5fd7\", \"\u7f51\u7edc\u8bf7\u6c42\")\n}.preview(true) {\n// \u5148\u6267\u884c\u8fd9\u91cc(\u4ec5\u8bfb\u7f13\u5b58), \u4efb\u4f55\u5f02\u5e38\u90fd\u89c6\u4e3a\u8bfb\u53d6\u7f13\u5b58\u5931\u8d25\nbinding.tvFragment.text = Get<String>(\"api\") {\nsetCacheMode(CacheMode.READ)\n}.await()\nLog.d(\"\u65e5\u5fd7\", \"\u8bfb\u53d6\u7f13\u5b58\")\n}\n

\u8fd9\u548c\u52a0\u8f7d\u4e24\u6b21\u6709\u4ec0\u4e48\u533a\u522b?

\u533a\u522b\u662fpreview\u53ef\u4ee5\u63a7\u5236\u4ee5\u4e0b\u884c\u4e3a

  1. breakError \u8bfb\u53d6\u7f13\u5b58\u6210\u529f\u540e\u4e0d\u518d\u5904\u7406\u9519\u8bef\u4fe1\u606f, \u9ed8\u8ba4false
  2. breakLoading \u8bfb\u53d6\u7f13\u5b58\u6210\u529f\u540e\u7ed3\u675f\u52a0\u8f7d\u52a8\u753b, \u9ed8\u8ba4true
"},{"location":"callback.html","title":"Callback","text":"

Net\u652f\u6301OkHttp\u7684\u539f\u6709\u7684\u961f\u5217\u8bf7\u6c42Callback

\u4e0d\u63a8\u8350

Callback\u5c5e\u4e8e\u63a5\u53e3\u56de\u8c03, \u5176\u4ee3\u7801\u5197\u4f59, \u4e14\u65e0\u6cd5\u652f\u6301\u5e76\u53d1\u8bf7\u6c42

Net.post(\"api\").enqueue(object : Callback {\noverride fun onFailure(call: Call, e: IOException) {\n}\noverride fun onResponse(call: Call, response: Response) {\n// \u6b64\u5904\u4e3a\u5b50\u7ebf\u7a0b\nval body = response.body?.string() ?: \"\u65e0\u6570\u636e\"\nrunMain {\n// \u6b64\u5904\u4e3a\u4e3b\u7ebf\u7a0b\nbinding.tvFragment.text = body\n}\n}\n})\n
"},{"location":"cancel.html","title":"\u53d6\u6d88\u8bf7\u6c42","text":"

\u90e8\u5206\u573a\u666f\u9700\u8981\u624b\u52a8\u53d6\u6d88\u8bf7\u6c42, \u4f8b\u5982\u53d6\u6d88\u4e0b\u8f7d

downloadScope = scopeNetLife {\n// \u4e0b\u8f7d\u6587\u4ef6\nval file = Get<File>(\"download\").await()\n}\ndownloadScope.cancel() // \u53d6\u6d88\u4e0b\u8f7d\n
"},{"location":"cancel.html#_1","title":"\u4efb\u610f\u4f4d\u7f6e\u53d6\u6d88","text":"

\u53d1\u8d77\u8bf7\u6c42\u65f6\u6307\u5b9aId

scopeNetLife {\ntvFragment.text = Get<String>(\"api\"){\nsetId(\"\u8bf7\u6c42\u7528\u6237\u4fe1\u606f\")\n}.await()\n}\n
\u6839\u636eID\u53d6\u6d88\u6839\u636eGroup\u53d6\u6d88
Net.cancelId(\"\u8bf7\u6c42\u7528\u6237\u4fe1\u606f\")\n
Net.cancelGroup(\"\u8bf7\u6c42\u5206\u7ec4\u540d\u79f0\")\n
"},{"location":"cancel.html#groupid","title":"Group\u548cId\u533a\u522b","text":"\u51fd\u6570 \u63cf\u8ff0 id \u8bf7\u6c42\u552f\u4e00Id, \u5b9e\u9645\u4e0a\u91cd\u590d\u4e5f\u884c, \u4f46\u662f\u53d6\u6d88\u8bf7\u6c42\u65f6\u904d\u5386\u5230\u6307\u5b9aId\u5c31\u4f1a\u7ed3\u675f\u904d\u5386 group \u5141\u8bb8\u591a\u4e2a\u8bf7\u6c42\u4f7f\u7528\u76f8\u540cgroup, \u5728\u53d6\u6d88\u8bf7\u6c42\u65f6\u4f1a\u904d\u5386\u6240\u6709\u5206\u7ec4\u7684\u8bf7\u6c42

\u4f5c\u7528\u57df\u7ed3\u675f\u8bf7\u6c42\u81ea\u52a8\u53d6\u6d88

\u5728scopeXX()\u4f5c\u7528\u57df\u4e2d\u53d1\u8d77\u8bf7\u6c42\u65f6\u4f1a\u9ed8\u8ba4\u4f7f\u7528\u5f53\u524d\u534f\u7a0b\u9519\u8bef\u5904\u7406\u5668\u4f5c\u4e3aGroup

setGroup(coroutineContext[CoroutineExceptionHandler])\n
\u5728\u4f5c\u7528\u57df\u7ed3\u675f\u65f6 \u4f1acancelGroup, \u6240\u4ee5\u5982\u679c\u4f60\u624b\u52a8\u6307\u5b9a\u5206\u7ec4\u4f1a\u5bfc\u81f4\u65e0\u6cd5\u81ea\u52a8\u53d6\u6d88

"},{"location":"config.html","title":"\u5168\u5c40\u914d\u7f6e","text":"

\u5168\u5c40\u914d\u7f6e\u5e94\u5728Application.onCreate\u4e2d\u914d\u7f6e

"},{"location":"config.html#_1","title":"\u521d\u59cb\u914d\u7f6e","text":"

\u4e24\u79cd\u65b9\u5f0f\u521d\u59cb\u914d\u7f6e, \u4e0d\u521d\u59cb\u5316\u4e5f\u80fd\u76f4\u63a5\u4f7f\u7528

Net\u521d\u59cb\u5316OkHttp\u6784\u9020\u5668\u521d\u59cb\u5316
NetConfig.initialize(Api.HOST, this) {\n// \u8d85\u65f6\u914d\u7f6e, \u9ed8\u8ba4\u662f10\u79d2, \u8bbe\u7f6e\u592a\u957f\u65f6\u95f4\u4f1a\u5bfc\u81f4\u7528\u6237\u7b49\u5f85\u8fc7\u4e45\nconnectTimeout(30, TimeUnit.SECONDS)\nreadTimeout(30, TimeUnit.SECONDS)\nwriteTimeout(30, TimeUnit.SECONDS)\nsetDebug(BuildConfig.DEBUG)\nsetConverter(SerializationConverter())\n}\n
val okHttpClientBuilder = OkHttpClient.Builder()\n.setDebug(BuildConfig.DEBUG)\n.setConverter(SerializationConverter())\n.addInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))\nNetConfig.initialize(Api.HOST, this, okHttpClientBuilder)\n

\u5f3a\u5236\u521d\u59cb\u5316

\u5982\u679c\u662f\u591a\u8fdb\u7a0b\u9879\u76ee(\u4f8b\u5982Xposed)\u5fc5\u987b\u521d\u59cb\u5316, \u56e0\u4e3a\u591a\u8fdb\u7a0b\u65e0\u6cd5\u81ea\u52a8\u6307\u5b9aContext

\u53ef\u914d\u7f6e\u9009\u9879 \u63cf\u8ff0 setDebug \u5f00\u542f\u65e5\u5fd7 setSSLCertificate \u914d\u7f6eHttps\u8bc1\u4e66 trustSSLCertificate \u4fe1\u4efb\u6240\u6709Https\u8bc1\u4e66 setConverter \u8f6c\u6362\u5668, \u5c06\u8bf7\u6c42\u7ed3\u679c\u8f6c\u4e3a\u4efb\u4f55\u7c7b\u578b setRequestInterceptor \u8bf7\u6c42\u62e6\u622a\u5668, \u5168\u5c40\u8bf7\u6c42\u5934/\u8bf7\u6c42\u53c2\u6570 setErrorHandler \u5168\u5c40\u9519\u8bef\u5904\u7406 setDialogFactory \u5168\u5c40\u5bf9\u8bdd\u6846

\u4fee\u6539\u914d\u7f6e

NetConfig\u5b58\u50a8\u6240\u6709\u5168\u5c40\u914d\u7f6e\u53d8\u91cf, \u53ef\u4ee5\u540e\u7eed\u4fee\u6539, \u4e14\u5927\u90e8\u5206\u652f\u6301\u5355\u4f8b\u6307\u5b9a\u914d\u7f6e

"},{"location":"config.html#_2","title":"\u91cd\u8bd5\u6b21\u6570","text":"

\u53ef\u4ee5\u6dfb\u52a0RetryInterceptor\u62e6\u622a\u5668\u5373\u53ef\u5b9e\u73b0\u5931\u8d25\u4ee5\u540e\u4f1a\u91cd\u8bd5\u6307\u5b9a\u6b21\u6570

\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8bbe\u7f6e\u8d85\u65f6\u65f6\u95f4\u5373\u53ef, OkHttp\u5185\u90e8\u4e5f\u6709\u91cd\u8bd5\u673a\u5236

NetConfig.initialize(Api.HOST, this) {\n// ... \u5176\u4ed6\u914d\u7f6e\naddInterceptor(RetryInterceptor(3)) // \u5982\u679c\u5168\u90e8\u5931\u8d25\u4f1a\u91cd\u8bd5\u4e09\u6b21\n}\n

\u957f\u65f6\u95f4\u963b\u788d\u7528\u6237\u4ea4\u4e92

OkHttp\u5185\u90e8\u4e5f\u6709\u91cd\u8bd5\u673a\u5236, \u5982\u679c\u8fd8\u6dfb\u52a0\u91cd\u8bd5\u62e6\u622a\u5668\u53ef\u80fd\u5bfc\u81f4\u8bf7\u6c42\u65f6\u95f4\u8fc7\u957f, \u957f\u65f6\u95f4\u963b\u788d\u7528\u6237\u4ea4\u4e92

"},{"location":"config.html#_3","title":"\u591a\u57df\u540d","text":"

\u6982\u5ff5\u6e90\u4e8eRetrofit(\u79f0\u4e3aBaseUrl), \u56e0\u4e3aRetrofit\u65e0\u6cd5\u4e8c\u6b21\u4fee\u6539\u8bf7\u6c42Host, \u4f46Net\u652f\u6301\u968f\u65f6\u4fee\u6539

\u4ee5\u4e0b\u4ecb\u7ecd\u4e09\u79cd\u4fee\u6539\u65b9\u5f0f

\u4fee\u6539Host\u6307\u5b9a\u5168\u8def\u5f84\u4f7f\u7528\u62e6\u622a\u5668
NetConfig.host = Api.HOST_2\n

\u6307\u5b9aPath(\u4f8b\u5982/api/index)\u4f1a\u81ea\u52a8\u548cNetConfig.host\u62fc\u63a5\u7ec4\u6210Url, \u4f46\u6307\u5b9a\u4ee5http/https\u5f00\u5934\u7684\u5168\u8def\u5f84\u5219\u76f4\u63a5\u4f5c\u4e3a\u8bf7\u6c42Url

scopeNetLife {\nval data = Get<String>(\"https://github.com/path\").await()\n}\n

\u8bf7\u6c42\u65f6\u6307\u5b9atag, \u7136\u540e\u62e6\u622a\u5668\u4e2d\u6839\u636etag\u5224\u65ad\u4fee\u6539host, \u62e6\u622a\u5668\u80fd\u4fee\u6539\u6240\u6709\u8bf7\u6c42/\u54cd\u5e94\u4fe1\u606f

scopeNetLife {\nval data = Get<String>(\"/api/index\", \"User\").await() // User\u5373\u4e3atag\n}\n// \u62e6\u622a\u5668\u4fee\u6539\u8bf7\u6c42URL\u4e0d\u505a\u4ecb\u7ecd\n
"},{"location":"config.html#_4","title":"\u7f51\u7edc\u5b89\u5168\u914d\u7f6e","text":"

Net\u81ea\u52a8\u542f\u7528\u7f51\u7edc\u914d\u7f6e\u6587\u4ef6, \u9ed8\u8ba4\u652f\u6301Http\u8bf7\u6c42, \u53ef\u81ea\u5b9a\u4e49

network_security_config.xml
<network-security-config>\n<base-config cleartextTrafficPermitted=\"true\" />\n</network-security-config>\n

\u65e0\u6cd5\u6253\u5305Apk

\u5f53\u5f00\u53d1\u8005\u81ea\u5b9a\u4e49\u4f7f\u7528\u975e\u540c\u540dnetwork_security_config\u65f6\u7f51\u7edc\u914d\u7f6e\u6587\u4ef6\u65f6\u4f1a\u65e0\u6cd5\u6253\u5305Apk

\u8bf7\u6dfb\u52a0tools:replace AndroidManifest.xml

<application\ntools:replace=\"android:networkSecurityConfig\">\n

"},{"location":"converter-customize.html","title":"\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668","text":"

Net\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668\u53ef\u652f\u6301\u4efb\u4f55\u6570\u636e\u7c7b\u578b, \u751a\u81f3Bitmap

\u6cdb\u578b\u548c\u8f6c\u6362\u5668\u5173\u7cfb

  1. \u5982\u679cPost<Model>, \u90a3\u4e48NetConverter.onConvert\u8fd4\u56de\u503c\u5fc5\u987b\u4e3aModel
  2. \u5982\u679cPost<Model?>, \u5141\u8bb8NetConverter.onConvert\u8fd4\u56de\u503c\u4e3anull
  3. \u5176\u4ed6\u60c5\u51b5\u8bf7\u629b\u51fa\u5f02\u5e38
scopeNetLife {\nval userList = Get<List<UserModel>>(\"list\") {\nconverter = GsonConverter()\n}.await()\n}\n

Net\u7531\u4e8e\u4f4e\u8026\u5408\u539f\u5219\u4e0d\u81ea\u5e26\u4efb\u4f55\u5e8f\u5217\u5316\u6846\u67b6

"},{"location":"converter-customize.html#_1","title":"\u8bbe\u7f6e\u8f6c\u6362\u5668","text":"\u5168\u5c40\u5355\u4f8b
NetConfig.initialize(Api.HOST, this) {\nsetConverter(SerializationConverter())\n}\n
scopeNetLife {\ntvFragment.text = Get<String>(\"api\"){\nconverter = SerializationConverter()\n}.await()\n}\n
"},{"location":"converter-customize.html#_2","title":"\u5e38\u89c1\u8f6c\u6362\u5668","text":"

\u5b9e\u73b0JSONConverter\u7684parseBody\u65b9\u6cd5\u4f7f\u7528\u81ea\u5b9a\u4e49\u5e8f\u5217\u5316\u6846\u67b6\u89e3\u6790

\u5e8f\u5217\u5316\u6846\u67b6 \u793a\u4f8b\u4ee3\u7801 \u63cf\u8ff0 kotlin-serialization SerializationConverter Kotlin\u5b98\u65b9\u5e8f\u5217\u5316\u6846\u67b6 kotlin-serialization ProtobufConverter Kotlin\u5b98\u65b9\u5e8f\u5217\u5316\u6846\u67b6 gson GsonConverter \u8c37\u6b4c\u5e8f\u5217\u5316\u6846\u67b6 fastJson FastJsonConverter \u963f\u91cc\u5df4\u5df4\u5e8f\u5217\u5316\u6846\u67b6 moshi MoshiConverter Square\u5e8f\u5217\u5316\u6846\u67b6"},{"location":"converter-customize.html#_3","title":"\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668","text":"

\u5b9e\u73b0NetConverter\u8fd4\u56de\u81ea\u5b9a\u4e49\u8bf7\u6c42\u7ed3\u679c

\u8f6c\u6362\u5668\u5b9e\u73b0\u975e\u5e38\u7b80\u5355 NetConverter.kt
interface NetConverter {\n@Throws(Throwable::class)\nfun <R> onConvert(succeed: Type, response: Response): R?\ncompanion object DEFAULT : NetConverter {\n/**\n         * \u8fd4\u56de\u7ed3\u679c\u5e94\u5f53\u7b49\u4e8e\u6cdb\u578b\u5bf9\u8c61, \u53ef\u7a7a\n         * @param succeed \u8bf7\u6c42\u8981\u6c42\u8fd4\u56de\u7684\u6cdb\u578b\u7c7b\u578b\n         * @param response \u8bf7\u6c42\u54cd\u5e94\u5bf9\u8c61\n         */\noverride fun <R> onConvert(succeed: Type, response: Response): R? {\nreturn when {\nsucceed === String::class.java && response.isSuccessful -> response.body?.string() as R\nsucceed === ByteString::class.java && response.isSuccessful -> response.body?.byteString() as R\nsucceed is GenericArrayType && succeed.genericComponentType === Byte::class.java && response.isSuccessful -> response.body?.bytes() as R\nsucceed === File::class.java && response.isSuccessful -> response.file() as R\nsucceed === Response::class.java -> response as R\nelse -> throw ConvertException(response, \"An exception occurred while converting the NetConverter.DEFAULT\")\n}\n}\n}\n}\n

\u8f6c\u6362\u5668\u4e2d\u53ef\u4ee5\u6839\u636e\u9700\u52a0\u4e0a\u89e3\u5bc6\u6570\u636e, token\u5931\u6548\u8df3\u8f6c\u767b\u5f55, \u9650\u5236\u591a\u7aef\u767b\u5f55\u7b49\u903b\u8f91

  1. \u65e5\u5fd7\u4fe1\u606f\u8f93\u51fa, \u8bf7\u9605\u8bfb\u65e5\u5fd7\u8bb0\u5f55\u5668
  2. \u8f6c\u6362\u5668\u4e2d\u629b\u51fa\u5f02\u5e38\u88ab\u5168\u5c40\u9519\u8bef\u5904\u7406\u6355\u83b7, \u8bf7\u9605\u8bfb\u5168\u5c40\u9519\u8bef\u5904\u7406
"},{"location":"converter-struct.html","title":"\u81ea\u5b9a\u4e49\u7ed3\u6784\u89e3\u6790","text":"

\u4e0a\u4e00\u7ae0\u8282\u4ecb\u7ecd\u5982\u4f55\u5e8f\u5217\u5316\u6846\u67b6\u89e3\u6790JSON, \u800c\u672c\u7ae0\u662f\u4ecb\u7ecd\u5982\u4f55\u5b9a\u4e49\u6620\u5c04\u6570\u636e\u7c7b

"},{"location":"converter-struct.html#json","title":"JSON","text":"

\u89e3\u6790\u63a5\u53e3\u8fd4\u56de\u7684\u5b8c\u6574JSON

JSON\u6570\u636e\u7c7b\u7f51\u7edc\u8bf7\u6c42
{\n\"code\":0,\n\"msg\":\"\u8bf7\u6c42\u6210\u529f\",\n\"data\": {\n\"name\": \"\u5f6d\u4e8e\u664f\",\n\"age\": 27,\n\"height\": 180\n}\n}\n
data class UserModel (\nvar code:Int,\nvar msg:String,\nvar data:Data,\n) {\ndata class Data(var name: String, var age: Int, var height: Int)\n}\n
scopeNetLife {\nval data = Get<UserModel>(\"api\").await().data\n}\n
\u4ee5\u4e0a\u8bbe\u8ba1\u4e0d\u5408\u7406

\u6b63\u5e38\u60c5\u51b5\u4e0bHttp\u72b6\u6001\u7801200\u65f6\u53ea\u8fd4\u56de\u6709\u6548\u6570\u636e

{\n\"name\": \"\u5f6d\u4e8e\u664f\",\n\"age\": 27,\n\"height\": 180\n}\n
\u4efb\u4f55\u975e\u6b63\u5e38\u6d41\u7a0b\u8fd4\u56de200\u72b6\u6001\u7801, \u4f8b\u5982400(\u9519\u8bef\u8bf7\u6c42)/401(\u8ba4\u8bc1\u5931\u8d25)
{\n\"code\":412302,\n\"msg\":\"\u5bc6\u7801\u9519\u8bef\",\n}\n
\u53ea\u8981\u8ba4\u4e3a\u9700\u8981\u89e3\u6790\u7ed3\u6784\u4f53\u60c5\u51b5\u4e0b, \u90fd\u5e94\u5c5e\u4e8e\u6b63\u5e38\u6d41\u7a0b

"},{"location":"converter-struct.html#_1","title":"\u5254\u9664\u65e0\u6548\u5b57\u6bb5","text":"

\u4ee5\u4e0b\u6f14\u793a\u4ec5\u89e3\u6790data\u5b57\u6bb5\u8fd4\u56de\u6709\u6548\u6570\u636e

\u6b64\u6570\u636e\u7c7b\u53ea\u9700\u8981\u5305\u542bdata\u503c

data class UserModel(var name: String, var age: Int, var height: Int)\n

\u8f6c\u6362\u5668\u53ea\u89e3\u6790data\u5b57\u6bb5

class GsonConvert : JSONConvert(code = \"code\", message = \"msg\", success = \"200\") {\nprivate val gson = GsonBuilder().serializeNulls().create()\noverride fun <S> String.parseBody(succeed: Type): S? {\nval data = JSONObject(this).getString(\"data\")\nreturn gson.fromJson(data, succeed)\n}\n}\n

\u8bf7\u6c42\u76f4\u63a5\u8fd4\u56de

scopeNetLife {\nval data = Get<UserModel>(\"api\").await()\n}\n
"},{"location":"converter-struct.html#_2","title":"\u4e0d\u89c4\u8303\u6570\u636e","text":"

\u63a8\u8350\u5728\u8f6c\u6362\u5668\u4e2d\u89e3\u6790\u4e4b\u524d\u5904\u7406\u597d\u6570\u636e

  1. \u5b57\u6bb5\u503c\u4e3a\"null\"\u800c\u4e0d\u662fnull, \u6216\u8005json\u5728\u5b57\u7b26\u4e32\u4e2d

     {\n\"data\": \"{ \"title\": \"name\" }\"\n\"msg\": \"null\"\n}\n
    \u66ff\u6362\u4e3a\u89c4\u8303\u5185\u5bb9
    json = bodyString.replace(\"\\\"{\", \"{\")\njson = bodyString.replace(\"}\\\"\", \"}\")\njson = bodyString.replace(\"\\\"null\\\"\", \"null\")\n

  2. \u670d\u52a1\u5668\u6210\u529f\u65f6\u4e0d\u8fd4\u56de\u6570\u636e\u6216\u8005\u8fd4\u56denull

    if (response.body == null || bodyString == \"null\") {\n\"{}\".bodyString.parseBody<R>(succeed)\n}\n

  3. \u5b57\u6bb5\u503c\u4e3anull, \u4f7f\u7528 kotlin-serialization \u81ea\u52a8\u4f7f\u7528\u5b57\u6bb5\u9ed8\u8ba4\u503c

    {\n\"msg\": null\n}\n

  4. \u5b57\u6bb5\u65e0\u5f15\u53f7\u6216\u5b57\u6bb5\u540d\u4e3a\u6570\u5b57, \u4f7f\u7528 kotlin-serialization \u53ef\u4ee5\u7981\u7528JSON\u89c4\u8303\u9650\u5236 \u6570\u5b57\u4f7f\u7528map\u89e3\u6790
     {\n\"data\": {\n23: 32\n}\n}\n
    \u7981\u7528JSON\u89c4\u8303\u9650\u5236
    val jsonDecoder = Json {\n// ...\nisLenient = true\n}\n
"},{"location":"converter-struct.html#_3","title":"\u6cdb\u578b\u6570\u636e\u7c7b","text":"

\u67d0\u4e9b\u5730\u533a\u5f88\u591a\u5f00\u53d1\u8005\u4e60\u60ef\u8fd9\u4e48\u4f7f\u7528, \u56e0\u4e3a\u4ed6\u4eec\u63a5\u53e3\u8fd4\u56de\u65e0\u5173\u5b57\u6bb5, \u4f46\u662f\u6280\u672f\u4e0d\u591f\u65e0\u6cd5\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668\u6765\u7b80\u5316\u53d6\u503c

\u6240\u4ee5\u4ed6\u4eec\u9009\u62e9\u66f4\u590d\u6742\u7684\u65b9\u5f0f: \u4f7f\u7528\u6cdb\u578b\u6765\u7b80\u5316

open class BaseResult<T> {\nvar code: Int = 0\nvar msg: String = \"\"\nvar data: T? = null\n}\nclass Result(var name: String) : BaseResult<Result>()\n

\u7528\u52a0\u6cd5\u89e3\u51b3\u95ee\u9898\u7684\u4eba\uff0c\u603b\u6709\u4eba\u613f\u610f\u7528\u4e58\u6cd5\u7ed9\u4f60\u7b54\u6848

"},{"location":"converter.html","title":"\u8f6c\u6362\u5668","text":"

Net\u652f\u6301\u8bf7\u6c42\u8fd4\u56de\u7684\u6570\u636e\u7c7b\u578b\u53d6\u51b3\u4e8e\u4f60\u7684\u8f6c\u6362\u5668\u5b9e\u73b0

"},{"location":"converter.html#getpathawait","title":"Get<\u4efb\u4f55\u5bf9\u8c61>(\"path\").await()","text":"

\u9ed8\u8ba4\u8f6c\u6362\u5668\u652f\u6301\u8fd4\u56de\u4ee5\u4e0b\u6570\u636e\u7c7b\u578b

\u51fd\u6570 \u63cf\u8ff0 String \u5b57\u7b26\u4e32 ByteArray \u5b57\u8282\u6570\u7ec4 ByteString \u66f4\u591a\u529f\u80fd\u7684\u5b57\u7b26\u4e32\u5bf9\u8c61 File \u6587\u4ef6\u5bf9\u8c61, \u8fd9\u79cd\u60c5\u51b5\u5176\u5b9e\u5e94\u5f53\u79f0\u4e3a\u4e0b\u8f7d\u6587\u4ef6 Response \u6240\u6709\u54cd\u5e94\u4fe1\u606f(\u54cd\u5e94\u4f53/\u54cd\u5e94\u5934/\u8bf7\u6c42\u4fe1\u606f\u7b49)

\u4f7f\u7528\u793a\u4f8b

scopeNetLife {\nGet<Response>(\"api\").await().headers(\"\u54cd\u5e94\u5934\u540d\u79f0\") // \u8fd4\u56de\u54cd\u5e94\u5934\n}\n
\u8f6c\u6362\u5668\u5b9e\u73b0\u975e\u5e38\u7b80\u5355 NetConverter.kt
interface NetConverter {\n@Throws(Throwable::class)\nfun <R> onConvert(succeed: Type, response: Response): R?\ncompanion object DEFAULT : NetConverter {\n/**\n         * \u8fd4\u56de\u7ed3\u679c\u5e94\u5f53\u7b49\u4e8e\u6cdb\u578b\u5bf9\u8c61, \u53ef\u7a7a\n         * @param succeed \u8bf7\u6c42\u8981\u6c42\u8fd4\u56de\u7684\u6cdb\u578b\u7c7b\u578b\n         * @param response \u8bf7\u6c42\u54cd\u5e94\u5bf9\u8c61\n         */\noverride fun <R> onConvert(succeed: Type, response: Response): R? {\nreturn when {\nsucceed === String::class.java && response.isSuccessful -> response.body?.string() as R\nsucceed === ByteString::class.java && response.isSuccessful -> response.body?.byteString() as R\nsucceed is GenericArrayType && succeed.genericComponentType === Byte::class.java && response.isSuccessful -> response.body?.bytes() as R\nsucceed === File::class.java && response.isSuccessful -> response.file() as R\nsucceed === Response::class.java -> response as R\nelse -> throw ConvertException(response, \"An exception occurred while converting the NetConverter.DEFAULT\")\n}\n}\n}\n}\n

\u5047\u8bbe\u4e0d\u652f\u6301\u4f60\u9700\u8981\u7684\u6570\u636e\u7c7b\u578b, \u4f8b\u5982JSON/ProtoBuf/Bitmap\u7b49\u8bf7\u81ea\u5b9a\u4e49\u8f6c\u6362\u5668

"},{"location":"cookie.html","title":"Cookie","text":"

\u4f7f\u7528OkHttp\u7684CookieJar, Net\u63d0\u4f9b\u6301\u4e45\u5316CookiePersistentCookieJar

NetConfig.initialize(Api.HOST, this) {\n// \u6dfb\u52a0\u6301\u4e45\u5316Cookie\ncookieJar(PersistentCookieJar(this@App))\n}\n

\u53ef\u4ee5\u624b\u52a8\u589e\u5220Cookie

PersistentCookieJar \u63cf\u8ff0 addAll \u6dfb\u52a0Cookie getAll \u83b7\u53d6\u67d0\u4e2a\u57df\u540d\u7684\u6240\u6709Cookie remove \u5220\u9664\u67d0\u4e2a\u57df\u540d\u4e0b\u6240\u6709\u6216\u8005\u6307\u5b9a\u540d\u79f0\u7684Cookie clear \u5220\u9664\u5ba2\u6237\u7aef\u5168\u90e8Cookie

\u53ef\u901a\u8fc7\u5ba2\u6237\u7aef\u83b7\u53d6\u5230\u5df2\u914d\u7f6ecookieJar

(NetConfig.okHttpClient.cookieJar as? PersistentCookieJar)?.clear()\n

\u9694\u7eddCookies\u5171\u4eab

\u4e3aPersistentCookieJar\u6307\u5b9a\u4e0d\u540cdbName\u963b\u6b62\u4e0d\u540c\u7684\u5ba2\u6237\u7aef\u5171\u4eabCookies

"},{"location":"coroutine-request.html","title":"\u534f\u7a0b\u8bf7\u6c42","text":"

Net\u7684\u534f\u7a0b\u4f5c\u7528\u57df\u4f1a\u81ea\u52a8\u5904\u7406\u534f\u7a0b\u751f\u547d\u5468\u671f

\u5728\u4e0a\u7ae0\u8282\u5df2\u7ecf\u4ecb\u7ecd\u5982\u4f55\u53d1\u8d77\u5e76\u53d1\u7f51\u7edc\u8bf7\u6c42, \u8fd9\u91cc\u6f14\u793a\u540c\u65f6(\u5e76\u53d1)\u8bf7\u6c42\u4e00\u4e07\u6b21, \u7136\u540e\u53d6\u6d88\u5168\u90e8

val job = scopeNetLife {\nrepeat(10000) {\n// \u8fd9\u91cc\u5c06\u8fd4\u56de\u7684\u6570\u636e\u663e\u793a\u5728TextView\u4e0a\nlaunch {\ntvFragment.text = Get<String>(Api.PATH).await()\n}\n}\n}\n

\u7b49\u5f85\u4e94\u79d2\u540e\u53d6\u6d88\u8bf7\u6c42

thread {\nThread.sleep(5000) // \u7b49\u5f85\u4e94\u79d2\njob.cancel()\n}\n

Net\u4e3b\u8981\u4f7f\u7528\u534f\u7a0b\u8bf7\u6c42, \u4f46\u4e5f\u652f\u6301\u5176\u4ed6\u65b9\u5f0f\u53d1\u8d77\u8bf7\u6c42

  • \u540c\u6b65\u8bf7\u6c42
  • \u56de\u8c03\u8bf7\u6c42
  • \u534f\u7a0b\u8bf7\u6c42
"},{"location":"debounce.html","title":"\u641c\u7d22\u8282\u6d41","text":"

\u8282\u6d41

\u5728\u4e00\u5b9a\u65f6\u95f4\u95f4\u9694\u5185\uff0c\u53ea\u6267\u884c\u6700\u540e\u4e00\u6b21\u8bf7\u6c42, \u5ffd\u7565\u5176\u4ed6\u591a\u4f59\u7684\u8bf7\u6c42

\u641c\u7d22\u8f93\u5165\u6846\u4e00\u822c\u90fd\u662f\u8f93\u5165\u5b8c\u5173\u952e\u8bcd\u540e\u81ea\u52a8\u5f00\u59cb\u641c\u7d22

\u8fd9\u4e2a\u8fc7\u7a0b\u6d89\u53ca\u5230

  1. \u6bcf\u6b21\u53d8\u5316\u90fd\u641c\u7d22\u4f1a\u5bfc\u81f4\u670d\u52a1\u5668\u538b\u529b, \u5e94\u5728\u505c\u6b62\u8f93\u5165\u6ee1\u8db3\u4e00\u5b9a\u65f6\u95f4\u540e\u81ea\u52a8\u641c\u7d22
  2. \u5f53\u4ea7\u751f\u65b0\u7684\u641c\u7d22\u8bf7\u6c42\u540e\u5e94\u53d6\u6d88\u65e7\u8bf7\u6c42, \u4ee5\u9632\u6b62\u65e7\u6570\u636e\u8986\u76d6\u65b0\u6570\u636e
  3. \u5f53\u8f93\u5165\u5185\u5bb9\u6ca1\u6709\u53d8\u5316(\u4f8b\u590d\u5236\u7c98\u8d34\u91cd\u590d\u5185\u5bb9\u5230\u641c\u7d22\u6846)\u4e0d\u4f1a\u53d1\u8d77\u641c\u7d22\u8bf7\u6c42

var scope: CoroutineScope? = null\n// distinctUntilChanged \u8868\u793a\u8fc7\u6ee4\u6389\u91cd\u590d\u7ed3\u679c\nbinding.etInput.debounce().distinctUntilChanged().launchIn(this) {\nscope?.cancel() // \u53d1\u8d77\u65b0\u7684\u8bf7\u6c42\u524d\u53d6\u6d88\u65e7\u7684\u8bf7\u6c42, \u907f\u514d\u65e7\u6570\u636e\u8986\u76d6\u65b0\u6570\u636e\nscope = scopeNetLife { // \u4fdd\u5b58\u65e7\u7684\u8bf7\u6c42\u5230\u4e00\u4e2a\u53d8\u91cf\u4e2d\nbinding.tvFragment.text = \"\u8bf7\u6c42\u4e2d\"\nbinding.tvFragment.text = Get<String>(Api.TIME).await()\n}\n}\n

\u6307\u5b9a\u53c2\u6570\u8bbe\u7f6e\u8282\u6d41\u9600\u8d85\u65f6\u65f6\u95f4

fun EditText.debounce(timeoutMillis: Long = 800)\n

"},{"location":"download-file.html","title":"\u4e0b\u8f7d\u6587\u4ef6","text":"

\u6cdb\u578b\u6539\u4e3aFile\u5373\u53ef

scopeNetLife {\nval file = Get<File>(\"download\").await()\n}\n
"},{"location":"download-file.html#_1","title":"\u4e0b\u8f7d\u9009\u9879","text":"

\u4e30\u5bcc\u7684\u4e0b\u8f7d\u5b9a\u5236\u65b9\u6848, \u5e76\u4e14\u5728\u4e0d\u65ad\u66f4\u65b0

scopeNetLife {\nval file =\nGet<File>(\"https://github.com/liangjingkanji/Net/releases/latest/download/net-sample.apk\") {\nsetDownloadFileName(\"net.apk\")\nsetDownloadDir(requireContext().filesDir)\nsetDownloadMd5Verify()\n}.await()\n}\n
\u914d\u7f6e\u9009\u9879 \u63cf\u8ff0 addDownloadListener \u4e0b\u8f7d\u8fdb\u5ea6\u76d1\u542c\u5668 setDownloadFileName \u4e0b\u8f7d\u6587\u4ef6\u540d setDownloadDir \u4e0b\u8f7d\u76ee\u5f55 setDownloadMd5Verify \u4e0b\u8f7d\u6587\u4ef6MD5\u6821\u9a8c setDownloadFileNameConflict \u4e0b\u8f7d\u6587\u4ef6\u540c\u540d\u51b2\u7a81\u89e3\u51b3 setDownloadFileNameDecode \u6587\u4ef6\u540dUrl\u89e3\u7801\u4e2d\u6587 setDownloadTempFile \u4e34\u65f6\u6587\u4ef6\u540d"},{"location":"download-file.html#_2","title":"\u91cd\u590d\u4e0b\u8f7d","text":"

\u9632\u6b62\u91cd\u590d\u4e0b\u8f7d\u6709\u4ee5\u4e0b\u65b9\u5f0f

\u51fd\u6570 \u63cf\u8ff0 \u6587\u4ef6\u5224\u65ad \u5224\u65ad\u672c\u5730\u662f\u5426\u5b58\u5728\u540c\u540d\u6587\u4ef6 \u7f13\u5b58\u6a21\u5f0f \u5f00\u542f\u7f13\u5b58, \u5360\u7528\u8bbe\u5907\u4e24\u4efd\u7a7a\u95f4(\u7f13\u5b58/\u4e0b\u8f7d\u6210\u529f\u6587\u4ef6\u90fd\u5360\u7a7a\u95f4) MD5\u6821\u9a8c \u670d\u52a1\u5668\u8fd4\u56deContent-MD5, \u5ba2\u6237\u7aef\u5f00\u542fsetDownloadMd5Verify"},{"location":"error-global.html","title":"\u5168\u5c40\u6355\u83b7","text":"

\u53ef\u5b9e\u73b0NetErrorHandler\u63a5\u53e3\u6765\u76d1\u542c\u5168\u5c40\u9519\u8bef\u5904\u7406

\u521b\u5efa\u914d\u7f6e
class NetworkingErrorHandler : NetErrorHandler {\noverride fun onError(e: Throwable) {\n// .... \u5176\u4ed6\u9519\u8bef\nif (e is ResponseException && e.tag == 401) { // \u5224\u65ad\u5f02\u5e38\u4e3atoken\u5931\u6548\n// \u6253\u5f00\u767b\u5f55\u754c\u9762\u6216\u8005\u5f39\u767b\u5f55\u5931\u6548\u5bf9\u8bdd\u6846\n}\n}\n}\n
NetConfig.initialize(Api.HOST, this) {\nsetErrorHandler(NetworkingErrorHandler))\n}\n
NetErrorHandler \u4f7f\u7528\u573a\u666f \u89e6\u53d1\u4f4d\u7f6e onError \u5410\u53f8\u9519\u8bef\u4fe1\u606f scopeNetLife/scopeDialog onStateError \u8981\u6c42\u9519\u8bef\u663e\u793a\u5728\u7f3a\u7701\u9875 PageRefreshLayout.scope/StateLayout.scope

\u4ee5\u4e0b\u60c5\u51b5\u5168\u5c40\u9519\u8bef\u5904\u7406\u65e0\u6548

  1. \u5f02\u6b65\u4efb\u52a1\u4f5c\u7528\u57df(scope/scopeLife)\u53d1\u751f\u7684\u9519\u8bef
  2. \u4f7f\u7528\u5355\u4f8b\u9519\u8bef\u5904\u7406\u5904\u7406\u7684\u9519\u8bef
"},{"location":"error-single.html","title":"\u5355\u4f8b\u6355\u83b7","text":"

\u6355\u83b7\u5f53\u524d\u8bf7\u6c42/\u4f5c\u7528\u57df\u9519\u8bef, \u5c06\u4e0d\u4f1a\u518d\u88ab\u5168\u5c40\u9519\u8bef\u5904\u7406

"},{"location":"error-single.html#_1","title":"\u6355\u83b7\u8bf7\u6c42","text":"

\u4e00\u4e2a\u8bf7\u6c42\u53d1\u751f\u9519\u8bef\u4f1a\u53d6\u6d88\u5f53\u524d\u4f5c\u7528\u57df\u5185\u6240\u6709\u8bf7\u6c42, \u4f46\u5355\u72ec\u6355\u83b7\u540e\u4e0d\u4f1a\u518d\u5f71\u54cd\u5176\u4ed6\u8bf7\u6c42

\u4f8b\u5982

scopeNetLife {\nGet<String>(\"api\").await() // \u5931\u8d25\nGet<String>(\"api2\").await() // \u4e0a\u9762\u5931\u8d25, \u6b64\u5904\u4e5f\u4e0d\u4f1a\u6267\u884c\n}\n

\u6355\u83b7\u7b2c\u4e00\u4e2a\u534f\u7a0b\u907f\u514d\u7ec8\u6b62\u540e\u7eed\u6267\u884c

scopeNetLife {\ntry {\nGet<String>(\"api\").await() // \u5931\u8d25\n} catch(e:Exception) {\n}\nGet<String>(\"api2\").await() // \u4e0a\u9762\u5931\u8d25, \u6b64\u5904\u7ee7\u7eed\u6267\u884c\n}\n
\u5f53\u7136\u5982\u679c\u521b\u5efa\u4e0d\u540c\u7684\u4f5c\u7528\u57df\u5206\u522b\u8bf7\u6c42\u90a3\u662f\u4e92\u4e0d\u5f71\u54cd\u7684
scopeNetLife {\nGet<String>(\"api\").await() // \u5931\u8d25\n}\nscopeNetLife {\nGet<String>(\"api2\").await() // \u4e0a\u9762\u5931\u8d25, \u6b64\u5904\u5b8c\u5168\u4e0d\u53d7\u5f71\u54cd\n}\n

"},{"location":"error-single.html#_2","title":"\u6355\u83b7\u4f5c\u7528\u57df","text":"
scope {\nval data = Get<String>(\"http://www.thisiserror.com/\").await()\n}.catch {\n// \u534f\u7a0b\u5185\u53d1\u751f\u9519\u8bef\u56de\u8c03, it\u4e3a\u5f02\u5e38\u5bf9\u8c61\n}.finally {\n// \u534f\u7a0b\u6267\u884c\u5b8c\u6bd5\u56de\u8c03(\u4e0d\u8bba\u6210\u8d25), it\u4e3a\u5f02\u5e38\u5bf9\u8c61\n}\n
\u51fd\u6570 \u533a\u522b catch \u53d1\u751f\u9519\u8bef\u540e\u56de\u8c03, \u53d6\u6d88\u4e0d\u56de\u8c03 \u4e0d\u4f1a\u518d\u6267\u884c\u5168\u5c40\u9519\u8bef\u5904\u7406, \u53ef\u4f7f\u7528handleError\u518d\u6b21\u4f20\u9012\u7ed9\u5168\u5c40 finally \u6267\u884c\u5b8c\u6bd5\u56de\u8c03(\u4e0d\u8bba\u6210\u8d25), \u53d6\u6d88\u4f5c\u7528\u57df\u65f6it\u4e3aCancellationException \u6267\u884c\u5168\u5c40\u9519\u8bef\u5904\u7406"},{"location":"error-throws.html","title":"\u81ea\u5b9a\u4e49\u5f02\u5e38\u629b\u51fa","text":"

\u4ee5\u4e0b\u4e3aNet\u5185\u90e8\u629b\u51fa\u7684\u5f02\u5e38\u5bf9\u8c61

\u5f02\u5e38 \u63cf\u8ff0 NetException \u672a\u77e5\u7684\u7f51\u7edc\u5f02\u5e38, \u4e00\u822c\u60c5\u51b5\u5e94\u5f53\u7ee7\u627f\u4ed6\u6765\u521b\u5efa\u81ea\u5b9a\u4e49\u7684\u7f51\u7edc\u5f02\u5e38 HttpFailureException Http\u8bf7\u6c42\u9519\u8bef, Http\u8bf7\u6c42\u5931\u8d25(onFailure) HttpResponseException Http\u8bf7\u6c42\u6210\u529f\u540e\u53d1\u751f\u7684\u9519\u8bef, Http\u8bf7\u6c42\u6210\u529f\u4f46\u53d1\u751f\u5f02\u5e38(onResponse) URLParseException \u5730\u5740\u9519\u8bef NetUnknownHostException \u57df\u540d\u9519\u8bef NetSocketTimeoutException \u8fde\u63a5\u8d85\u65f6 NetConnectException \u8fde\u63a5\u7f51\u7edc\u5931\u8d25, \u8bbe\u5907\u672a\u5f00\u542f\u7f51\u7edc NetworkingException \u5f53\u524d\u7f51\u7edc\u4e0d\u53ef\u7528, Net\u5e76\u672a\u5b9e\u73b0 DownloadFileException \u4e0b\u8f7d\u6587\u4ef6\u5f02\u5e38 ConvertException \u89e3\u6790\u9519\u8bef, NetConvert\u4e2d\u53d1\u751f\u7684\u672a\u6355\u83b7\u5f02\u5e38\u90fd\u7b97\u89e3\u6790\u9519\u8bef RequestParamsException \u8bf7\u6c42\u53c2\u6570\u9519\u8bef 400 - 499 \u8303\u56f4\u5185\u9519\u8bef\u7801 ServerResponseException \u670d\u52a1\u5668\u9519\u8bef 500 - 599 \u8303\u56f4\u5185\u9519\u8bef\u7801 ResponseException \u9519\u8bef\u7801\u5f02\u5e38, \u4e00\u822c\u5e94\u7528\u4e8e\u540e\u7aef\u8fd4\u56de\u7684\u9519\u8bef\u7801\u548c\u5176\u5b9a\u4e49\u7684\u6210\u529f\u7801\u4e0d\u5339\u914d NullPointerException \u7a7a\u6307\u9488, \u4e00\u822c\u662f\u5728\u4f5c\u7528\u57df\u5185\u64cd\u4f5c\u4e00\u4e2a\u7a7a\u7684\u5bf9\u8c61

NetworkingException

\u7531\u4e8e\u8c37\u6b4c\u9650\u5236Net\u65e0\u6cd5\u5224\u65ad\u7f51\u7edc\u662f\u5426\u53ef\u7528, \u8bf7\u5f00\u53d1\u8005\u81ea\u5df1\u629b\u51fa

"},{"location":"error-throws.html#_1","title":"\u81ea\u5b9a\u4e49\u5f02\u5e38","text":"

\u5728\u8f6c\u6362\u5668(NetConverter)\u6216\u62e6\u622a\u5668(Interceptor)\u4e2d\u629b\u51fa\u4efb\u4f55\u5f02\u5e38 \u8be5\u5f02\u5e38\u5bf9\u8c61\u90fd\u4f1a\u88ab\u5355\u4f8b\u6216\u5168\u5c40\u9519\u8bef\u5904\u7406\u63a5\u6536, \u53ef\u7528\u4e8e\u5224\u65ad\u5f02\u5e38\u4fe1\u606f\u505a\u7279\u6b8a\u5904\u7406 (\u4f8b\u5982Token\u5931\u6548\u5219\u8df3\u8f6c\u5230\u767b\u5f55\u9875\u9762)

\u8f6c\u6362\u53d1\u751f\u5f02\u5e38

NetConverter\u4e2d\u7684\u6240\u6709\u5f02\u5e38\u9664\u975e\u662fNetException\u5b50\u7c7b\u5426\u5219\u90fd\u5c06\u88abConvertException\u5305\u88f9 \u5373\u6355\u83b7\u7684\u662fConvertException, cause\u624d\u4e3a\u5b9e\u9645\u629b\u51fa\u5f02\u5e38

"},{"location":"error-throws.html#_2","title":"\u5f02\u5e38\u4f20\u9012\u5b57\u6bb5","text":"

Net\u81ea\u5e26\u5f02\u5e38\u4f1a\u6709\u7c7b\u578b\u4e3aAny\u7684\u5b57\u6bb5tag, \u53ef\u7528\u4f20\u9012\u5bf9\u8c61\u7528\u4e8e\u5224\u65ad\u9519\u8bef\u5904\u7406

\u4f8b\u5982ResponseException\u5e38\u7528\u4e8e\u4f5c\u4e3a\u8bf7\u6c42\u670d\u52a1\u5668\u6210\u529f\u4f46\u540e\u7aef\u4e1a\u52a1\u9519\u8bef, \u7136\u540etag\u4e3a\u4f20\u9012\u7684\u9519\u8bef\u7801

\u793a\u4f8b\u4ee3\u7801

\u8f6c\u6362\u5668\u629b\u51fa\u5f02\u5e38\u5168\u5c40\u9519\u8bef\u5904\u7406\u5f02\u5e38
class SerializationConverter(\nval success: String = \"0\",\nval code: String = \"code\",\nval message: String = \"msg\"\n) : NetConverter {\noverride fun <R> onConvert(succeed: Type, response: Response): R? {\ntry {\nreturn NetConverter.onConvert<R>(succeed, response)\n} catch (e: ConvertException) {\nval code = response.code\nwhen {\ncode in 200..299 -> { // \u8bf7\u6c42\u6210\u529f\n// ... \u5047\u8bbeToken\u5931\u6548. \u540e\u7aef\u8fd4\u56de\u4e1a\u52a1\u9519\u8bef\u7801 srvCode = 401\nthrow ResponseException(response, errorMessage, tag = srvCode) // \u5c06\u4e1a\u52a1\u9519\u8bef\u7801\u4f5c\u4e3atag\u4f20\u9012\n}\ncode in 400..499 -> throw RequestParamsException(response, code.toString()) // \u8bf7\u6c42\u53c2\u6570\u9519\u8bef\ncode >= 500 -> throw ServerResponseException(response, code.toString()) // \u670d\u52a1\u5668\u5f02\u5e38\u9519\u8bef\nelse -> throw ConvertException(response)\n}\n}\n}\n}\n
class NetworkingErrorHandler : NetErrorHandler {\noverride fun onError(e: Throwable) {\n// .... \u5176\u4ed6\u9519\u8bef\nif (e is ResponseException && e.tag == 401) { // \u5224\u65ad\u5f02\u5e38\u4e3atoken\u5931\u6548\n// \u6253\u5f00\u767b\u5f55\u754c\u9762\u6216\u8005\u5f39\u767b\u5f55\u5931\u6548\u5bf9\u8bdd\u6846\n}\n}\n}\n
"},{"location":"error-tip.html","title":"\u81ea\u5b9a\u4e49\u9519\u8bef\u63d0\u793a","text":"

\u7f51\u7edc\u9519\u8bef\u63d0\u793a

\u7f51\u7edc\u8bf7\u6c42\u53d1\u751f\u9519\u8bef\u4e00\u5b9a\u8981\u63d0\u793a\u7ed9\u7528\u6237, \u5e76\u4e14\u662f\u53ef\u8bfb\u8bed\u4e49\u53e5

\u4fee\u6539\u9ed8\u8ba4\u5410\u53f8\u9519\u8bef\u6587\u672c\u6216\u56fd\u9645\u5316\u53c2\u8003\u4ee5\u4e0b\u65b9\u5f0f

"},{"location":"error-tip.html#_1","title":"\u521b\u5efa\u591a\u8bed\u8a00","text":"

\u9519\u8bef\u63d0\u793a\u6587\u672c\u88ab\u5b9a\u4e49\u5728strings.xml, \u5728\u9879\u76ee\u4e2d\u521b\u5efa\u540c\u540dname\u53ef\u590d\u5199Net\u5b9a\u4e49\u7684\u6587\u672c

\u56fd\u9645\u5316\u8bed\u8a00\u5219\u9700\u521b\u5efa\u591a\u8bed\u8a00values, \u4f8b\u5982\u82f1\u8bed\u662fvalues-en\u4e0b\u521b\u5efastrings.xml

\u9519\u8bef\u6587\u672c
    <!--\u7f51\u7edc\u8bf7\u6c42\u5f02\u5e38-->\n<string name=\"net_connect_error\">\u8fde\u63a5\u7f51\u7edc\u5931\u8d25</string>\n<string name=\"net_url_error\">\u8bf7\u6c42\u8d44\u6e90\u5730\u5740\u9519\u8bef</string>\n<string name=\"net_host_error\">\u65e0\u6cd5\u627e\u5230\u6307\u5b9a\u670d\u52a1\u5668\u4e3b\u673a</string>\n<string name=\"net_connect_timeout_error\">\u8fde\u63a5\u670d\u52a1\u5668\u8d85\u65f6\uff0c%s</string>\n<string name=\"net_download_error\">\u4e0b\u8f7d\u8fc7\u7a0b\u53d1\u751f\u9519\u8bef</string>\n<string name=\"net_no_cache_error\">\u8bfb\u53d6\u7f13\u5b58\u5931\u8d25</string>\n<string name=\"net_parse_error\">\u89e3\u6790\u6570\u636e\u65f6\u53d1\u751f\u5f02\u5e38</string>\n<string name=\"request_failure\">\u8bf7\u6c42\u5931\u8d25</string>\n<string name=\"net_request_error\">\u8bf7\u6c42\u53c2\u6570\u9519\u8bef</string>\n<string name=\"net_server_error\">\u670d\u52a1\u54cd\u5e94\u9519\u8bef</string>\n<string name=\"net_null_error\">\u53d1\u751f\u7a7a\u5f02\u5e38</string>\n<string name=\"net_error\">\u672a\u77e5\u7f51\u7edc\u9519\u8bef</string>\n<string name=\"net_other_error\">\u672a\u77e5\u9519\u8bef</string>\n<string name=\"no_error_message\">\u65e0\u9519\u8bef\u4fe1\u606f</string>\n<!--\u5bf9\u8bdd\u6846-->\n<string name=\"net_dialog_msg\">\u52a0\u8f7d\u4e2d</string>\n
"},{"location":"error-tip.html#neterrorhandler","title":"\u521b\u5efaNetErrorHandler","text":"

\u4f7f\u7528\u81ea\u5b9a\u4e49\u5168\u5c40\u9519\u8bef\u5904\u7406\u53ef\u5b8c\u5168\u4fee\u6539, \u53ef\u4e0d\u63d0\u793a\u9519\u8bef\u6216\u9644\u4e0a\u9519\u8bef\u4fe1\u606f

\u5168\u5c40\u9519\u8bef\u5904\u7406
fun onError(e: Throwable) {\nval message = when (e) {\nis UnknownHostException -> NetConfig.app.getString(R.string.net_host_error)\nis URLParseException -> NetConfig.app.getString(R.string.net_url_error)\nis NetConnectException -> NetConfig.app.getString(R.string.net_connect_error)\nis NetSocketTimeoutException -> NetConfig.app.getString(\nR.string.net_connect_timeout_error,\ne.message\n)\nis DownloadFileException -> NetConfig.app.getString(R.string.net_download_error)\nis ConvertException -> NetConfig.app.getString(R.string.net_parse_error)\nis RequestParamsException -> NetConfig.app.getString(R.string.net_request_error)\nis ServerResponseException -> NetConfig.app.getString(R.string.net_server_error)\nis NullPointerException -> NetConfig.app.getString(R.string.net_null_error)\nis NoCacheException -> NetConfig.app.getString(R.string.net_no_cache_error)\nis ResponseException -> e.message\nis HttpFailureException -> NetConfig.app.getString(R.string.request_failure)\nis NetException -> NetConfig.app.getString(R.string.net_error)\nelse -> NetConfig.app.getString(R.string.net_other_error)\n}\nNet.debug(e)\nTipUtils.toast(message)\n}\n
"},{"location":"error.html","title":"\u9519\u8bef\u5904\u7406","text":"

Net\u6709\u5b8c\u5584\u7684\u9519\u8bef\u5904\u7406\u673a\u5236, \u5177\u5907\u6355\u83b7\u5f02\u5e38/\u53d6\u6d88\u8bf7\u6c42/\u9519\u8bef\u63d0\u793a/\u8ffd\u8e2a\u94fe\u8def

\u6536\u96c6\u7f51\u7edc\u65e5\u5fd7

\u5728Net\u4f5c\u7528\u57df\u5185\u53d1\u751f\u7684\u5f02\u5e38\u90fd\u4f1a\u88ab\u5168\u5c40\u9519\u8bef\u5904\u7406\u6355\u83b7, \u53ef\u4ee5\u5c06\u5176\u7b5b\u9009\u4e0a\u4f20\u65e5\u5fd7

\u4ee5\u4e0b\u4f4d\u7f6e\u629b\u51fa\u5f02\u5e38\u4f1a\u88ab\u6355\u83b7

\u51fd\u6570 \u63cf\u8ff0 \u4f5c\u7528\u57df scopeXX\u4ee3\u7801\u5757\u4e2d \u62e6\u622a\u5668 Interceptor/RequestInterceptor \u8f6c\u6362\u5668 NetConverter

\u5982\u679c\u6355\u83b7\u5230\u9519\u8bef\u9ed8\u8ba4\u4f1a\u6267\u884c\u4ee5\u4e0b\u64cd\u4f5c

  1. Logcat\u8f93\u51fa\u5f02\u5e38\u5806\u6808\u4fe1\u606f, \u81ea\u5b9a\u4e49\u5f02\u5e38\u629b\u51fa
  2. Toast\u663e\u793a\u9519\u8bef\u6587\u672c, \u81ea\u5b9a\u4e49\u9519\u8bef\u63d0\u793a

\u6355\u83b7\u4e0d\u5230\u5f02\u5e38

\u5982\u679c\u8bf7\u6c42\u672a\u6267\u884cawait(), \u90a3\u4e48\u5373\u4f7f\u53d1\u751f\u9519\u8bef\u4e5f\u4e0d\u4f1a\u88ab\u6355\u83b7\u5230

\u81ea\u5b9a\u4e49\u8bf7\u9605\u8bfb\u5168\u5c40\u9519\u8bef\u5904\u7406

"},{"location":"fastest.html","title":"\u6700\u5feb\u8bf7\u6c42\u7ed3\u679c","text":"

\u591a\u4e2a\u8bf7\u6c42\u5e76\u53d1\u6267\u884c

  1. \u5f53\u67d0\u4e2a\u8bf7\u6c42\u6210\u529f\u65f6, \u5269\u4f59\u8bf7\u6c42\u5c06\u88ab\u81ea\u52a8\u53d6\u6d88
  2. \u5168\u90e8\u9519\u8bef\u65f6\u5219\u4f1a\u629b\u51fa\u6700\u540e\u4e00\u4e2a\u8bf7\u6c42\u9519\u8bef\u4f5c\u4e3a\u7ed3\u679c

\u5f02\u5e38\u4fe1\u606f

\u5148\u5931\u8d25\u7684\u8bf7\u6c42\u9519\u8bef\u4f1a\u88ab\u5ffd\u7565, \u4f46LogCat\u4f9d\u7136\u4f1a\u8f93\u51fa\u5f02\u5e38

\u793a\u4f8b

scopeNetLife {\n// \u540c\u65f6\u53d1\u8d77\u56db\u4e2a\u7f51\u7edc\u8bf7\u6c42\nval deferred = Get<String>(\"api0\") // \u9519\u8bef\u63a5\u53e3\nval deferred1 = Get<String>(\"api1\") // \u9519\u8bef\u63a5\u53e3\nval deferred2 = Get<String>(\"api\")\nval deferred3 = Post<String>(\"api\")\n// \u53ea\u8fd4\u56de\u6700\u5feb\u7684\u8bf7\u6c42\u7ed3\u679c\ntvFragment.text = fastest(deferred, deferred1, deferred2, deferred3)\n}\n

"},{"location":"fastest.html#_1","title":"\u53d6\u6d88\u5269\u4f59","text":"

\u4e0a\u9762\u7684\u793a\u4f8b\u4e0d\u4f1a\u5728\u83b7\u53d6\u5230\u7ed3\u679c\u540e\u53d6\u6d88\u5269\u4f59\u8bf7\u6c42, \u9700\u8bbe\u7f6e\u540c\u4e00\u8bf7\u6c42\u5206\u7ec4\u624d\u53ef\u4ee5

scopeNetLife {\n// \u540c\u65f6\u53d1\u8d77\u56db\u4e2a\u7f51\u7edc\u8bf7\u6c42\nval deferred2 = Get<String>(\"api\") { setGroup(\"\u521d\u59cb\u5316\") }\nval deferred3 = Post<String>(\"api\") { setGroup(\"\u521d\u59cb\u5316\") }\nval deferred = Get<String>(\"api0\") { setGroup(\"\u521d\u59cb\u5316\") } // \u9519\u8bef\u63a5\u53e3\nval deferred1 = Get<String>(\"api1\") { setGroup(\"\u521d\u59cb\u5316\") } // \u9519\u8bef\u63a5\u53e3\n// \u53ea\u8fd4\u56de\u6700\u5feb\u7684\u8bf7\u6c42\u7ed3\u679c\ntvFragment.text = fastest(listOf(deferred, deferred1, deferred2, deferred3), \"\u521d\u59cb\u5316\")\n}\n
"},{"location":"fastest.html#_2","title":"\u7c7b\u578b\u4e0d\u4e00\u81f4","text":"

\u5f53\u9700\u8981\u8fd4\u56de\u7ed3\u679c, \u4f46\u591a\u63a5\u53e3\u8fd4\u56de\u6570\u636e\u7c7b\u578b\u4e0d\u540c, \u4f7f\u7528transform\u8f6c\u6362\u4e3a\u540c\u4e00\u7c7b\u578b\u7ed3\u679c

scopeNetLife {\nval fastest = Post<String>(\"api\").transform {\nLog.d(\"\u65e5\u5fd7\", \"Post\") // \u5982\u679c\u8be5\u63a5\u53e3\u6700\u5feb\u5219\u4f1a\u56de\u8c03\u8fd9\u91cc\nit // \u8fd9\u91cc\u53ef\u4ee5\u8fd4\u56de\u5176\u4ed6\u6570\u636e\u7ed3\u679c\n}\nval fastest2 = Get<String>(\"api\").transform {\nLog.d(\"\u65e5\u5fd7\", \"Get\") // \u5982\u679c\u8be5\u63a5\u53e3\u6700\u5feb\u5219\u4f1a\u56de\u8c03\u8fd9\u91cc\nit\n}\ntvFragment.text = fastest(fastest, fastest2)\n}\n

\u53ea\u6709\u6700\u5feb\u8fd4\u56de\u7ed3\u679c\u7684\u7f51\u7edc\u8bf7\u6c42(\u6216\u5f02\u6b65\u4efb\u52a1)\u7684transform\u56de\u8c03\u624d\u4f1a\u88ab\u6267\u884c\u5230

"},{"location":"fastest.html#_3","title":"\u6355\u83b7\u9519\u8bef","text":"
scopeNetLife {\nval task = Get<String>(\"api2\")\nval task1 = Get<String>(\"api2\")\nval task2 = Get<String>(\"api2\")\nval data = try {\nfastest(listOf(task, task1, task2))\n// \u5f53task/task1/task2\u5168\u90e8\u9519\u8bef\u540e\u624d\u5e76\u53d1\u6267\u884cbackupTask/backupTask1\n} catch (e: Exception) {\nval backupTask = Get<String>(\"api2\")\nval backupTask1 = Get<String>(\"api\")\nfastest(listOf(backupTask, backupTask1))\n}\n}\n
"},{"location":"https.html","title":"Https\u8bc1\u4e66","text":"

Net\u53ef\u5feb\u901f\u914d\u7f6eHttps\u8bc1\u4e66, \u6216\u8005\u4f7f\u7528OkHttp\u7684\u65b9\u5f0f

"},{"location":"https.html#ca","title":"\u4f7f\u7528CA\u8bc1\u4e66","text":"

Https\u5982\u679c\u4f7f\u7528\u7684CA\u8bc1\u4e66, \u4e0d\u9700\u8981\u4efb\u4f55\u914d\u7f6e\u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee

scopeNetLife {\ntvFragment.text = Get<String>(Api.PATH).await()\n}\n
"},{"location":"https.html#_1","title":"\u4fe1\u4efb\u6240\u6709\u8bc1\u4e66","text":"

\u4fe1\u4efb\u6240\u6709\u8bc1\u4e66\u53ef\u4ee5\u89e3\u51b3\u65e0\u6cd5\u8bbf\u95ee\u79c1\u6709\u8bc1\u4e66\u7684Https\u5730\u5740\u95ee\u9898

\u5168\u5c40\u914d\u7f6e\u5355\u4f8b\u914d\u7f6e
NetConfig.initialize(Api.HOST, this){\ntrustSSLCertificate() // \u4fe1\u4efb\u6240\u6709\u8bc1\u4e66\n}\n
scopeNetLife {\nGet<String>(Api.PATH){\nsetClient {\ntrustSSLCertificate()\n}\n}.await()\n}\n
"},{"location":"https.html#_2","title":"\u5bfc\u5165\u8bc1\u4e66","text":"

\u79c1\u6709\u8bc1\u4e66\u53ef\u4ee5\u653e\u5230\u4efb\u4f55\u4f4d\u7f6e, \u53ea\u8981\u8bfb\u53d6\u5230InputStream\u6d41\u5bf9\u8c61\u5373\u53ef

\u5168\u5c40\u914d\u7f6e\u5355\u4f8b\u914d\u7f6e
NetConfig.initialize(Api.HOST, this) {\nval privateCertificate = resources.assets.open(\"https.certificate\")\nsetSSLCertificate(privateCertificate)\n}\n
scopeNetLife {\nGet<String>(Api.PATH) {\nsetClient {\nval privateCertificate = resources.assets.open(\"https.certificate\") // \u8fd9\u91cc\u7684\u8bc1\u4e66\u662f\u653e\u5230\u5e94\u7528\u7684\u8d44\u4ea7\u76ee\u5f55\u4e0b\nsetSSLCertificate(privateCertificate)\n}\n}.await()\n}\n
"},{"location":"interceptor.html","title":"\u62e6\u622a\u5668","text":"

\u6839\u636e\u4f7f\u7528\u573a\u666f\u9009\u62e9

  1. Interceptor: \u652f\u6301\u4e09\u65b9OkHttp\u62e6\u622a\u5668\u7ec4\u4ef6, \u5141\u8bb8\u4fee\u6539\u8bf7\u6c42/\u54cd\u5e94\u4fe1\u606f, \u53ef\u4ee5\u8f6c\u53d1\u8bf7\u6c42
  2. RequestInterceptor: Net\u72ec\u6709\u7684\u8f7b\u91cf\u7ea7\u62e6\u622a\u5668, \u5141\u8bb8\u4fee\u6539\u5168\u5c40\u8bf7\u6c42\u5934/\u8bf7\u6c42\u53c2\u6570, \u65e0\u6cd5\u8f6c\u53d1\u8bf7\u6c42

\u7981\u6b62\u968f\u610f\u5c01\u88c5

\u4e0d\u5e94\u4e3a\u5168\u5c40\u53c2\u6570/\u52a0\u5bc6\u7b49\u5c01\u88c5\u8bf7\u6c42\u65b9\u6cd5, \u5e94\u81ea\u5b9a\u4e49\u62e6\u622a\u5668/\u8f6c\u6362\u5668\u6765\u5b9e\u73b0, \u5e38\u89c1\u62e6\u622a\u5668\u793a\u4f8b

"},{"location":"interceptor.html#_1","title":"\u62e6\u622a\u5668","text":"

\u6dfb\u52a0\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\naddInterceptor(RefreshTokenInterceptor())\n}\n

\u6f14\u793a\u5ba2\u6237\u7aef\u81ea\u52a8\u5237\u65b0token\u7684\u62e6\u622a\u5668

/**\n * \u6f14\u793a\u5982\u4f55\u81ea\u52a8\u5237\u65b0token\u4ee4\u724c\n */\nclass RefreshTokenInterceptor : Interceptor {\noverride fun intercept(chain: Interceptor.Chain): Response {\nval request = chain.request()\nval response = chain.proceed(request) // \u5982\u679ctoken\u5931\u6548\nreturn synchronized(RefreshTokenInterceptor::class.java) {\nif (response.code == 401 && UserConfig.isLogin && !request.url.pathSegments.contains(\"token\")) {\nval json = Net.get(\"token\").execute<String>() // \u540c\u6b65\u5237\u65b0token\nUserConfig.token = JSONObject(json).optString(\"token\")\nchain.proceed(request)\n} else {\nresponse\n}\n}\n}\n}\n
"},{"location":"interceptor.html#_2","title":"\u8bf7\u6c42\u62e6\u622a\u5668","text":"

\u8f7b\u91cf\u7ea7\u62e6\u622a\u5668(RequestInterceptor), \u5176Api\u66f4\u9002\u5408\u6dfb\u52a0\u5168\u5c40\u8bf7\u6c42\u5934/\u53c2\u6570

NetConfig.initialize(Api.HOST, this) {\nsetRequestInterceptor(object : RequestInterceptor {\noverride fun interceptor(request: BaseRequest) {\nrequest.param(\"client\", \"Net\")\nrequest.setHeader(\"token\", \"123456\")\n}\n})\n}\n

\u53ef\u4ee5\u770b\u51fasetRequestInterceptor\u4ec5\u652f\u6301\u4e00\u4e2a, addInterceptor\u652f\u6301\u591a\u4e2a\u62e6\u622a\u5668

"},{"location":"interval.html","title":"\u8f6e\u8be2\u5668/\u5012\u8ba1\u65f6","text":"

Net\u81ea\u5e26\u8f6e\u8be2\u5668(\u8ba1\u65f6\u5668), \u5305\u542b\u4ee5\u4e0b\u7279\u6027

  • \u6b63\u8ba1\u65f6
  • \u5012\u8ba1\u65f6
  • \u6307\u5b9a\u6b21\u6570
  • \u652f\u6301\u5f00\u59cb/\u505c\u6b62/\u6682\u505c/\u7ee7\u7eed/\u91cd\u7f6e/\u5207\u6362\u5f00\u5173
  • \u4ec5\u9875\u9762\u663e\u793a\u65f6\u8ba1\u65f6
  • \u9875\u9762\u9500\u6bc1\u81ea\u52a8\u53d6\u6d88

\u9650\u5236\u6b21\u6570/\u95f4\u9694\u65e0\u9650\u6267\u884c\u5012\u8ba1\u65f6
interval = Interval(100, 1, TimeUnit.SECONDS).life(this) // \u81ea\u5b9a\u4e49\u8ba1\u6570\u5668\u4e2a\u6570\u7684\u8f6e\u8be2\u5668\n
 interval = Interval(1, TimeUnit.SECONDS) // \u6bcf\u79d2\u56de\u8c03\u4e00\u6b21, \u4e0d\u4f1a\u81ea\u52a8\u7ed3\u675f\n
// \u5012\u8ba1\u65f6\u8f6e\u8be2\u5668, \u5f53[start]]\u6bd4[end]\u503c\u5927, \u4e14end\u4e0d\u7b49\u4e8e-1\u65f6, \u5373\u4e3a\u5012\u8ba1\u65f6\ninterval = Interval(1, 1, TimeUnit.SECONDS, 5).life(this)\n

\u76d1\u542c\u8f6e\u8be2\u5668

interval.subscribe {\ntvFragment.text = it.toString()\n}.finish {\ntvFragment.text = \"\u8ba1\u65f6\u5b8c\u6210\" // \u6700\u540e\u4e00\u4f4d\u6570\u65f6\u540c\u65f6\u56de\u8c03 subscribe/finish\n}.start()\n

Interval \u63cf\u8ff0 start \u5f00\u59cb\u8f6e\u8be2\u5668 stop \u505c\u6b62 cancel \u53d6\u6d88, \u533a\u522b\u4e8estop, \u6b64\u51fd\u6570\u6267\u884c\u540e\u5e76\u4e0d\u4f1a\u56de\u8c03finish pause \u6682\u505c resume \u7ee7\u7eed reset \u91cd\u7f6e switch \u5207\u6362\u5f00\u5173 subscribe \u6bcf\u6b21\u8ba1\u65f6\u90fd\u4f1a\u6267\u884c\u8be5\u56de\u8c03 finish \u5f53\u8ba1\u65f6\u5668\u5b8c\u6210\u65f6\u6267\u884c\u8be5\u56de\u8c03, \u6267\u884cstop\u540e\u4e5f\u4f1a\u56de\u8c03 life \u6307\u5b9a\u751f\u547d\u5468\u671f\u81ea\u52a8\u53d6\u6d88\u8f6e\u8be2\u5668 onlyResumed \u5f53\u754c\u9762\u4e0d\u53ef\u89c1\u65f6\u6682\u505c, \u5f53\u754c\u9762\u53ef\u89c1\u65f6\u7ee7\u7eed

\u540e\u53f0\u8fd0\u884c

\u7531\u4e8e\u7cfb\u7edf\u9650\u5236, \u672c\u5de5\u5177\u65e0\u6cd5\u4fdd\u8bc1\u540e\u53f0\u8fd0\u884c

"},{"location":"issues.html","title":"\u5e38\u89c1\u95ee\u9898","text":"

Net\u6700\u5927\u7684\u7279\u70b9\u5728\u4e8e\u5b8c\u7f8e\u652f\u6301OkHttp\u7684\u6240\u6709\u529f\u80fd\u7ec4\u4ef6, \u800cOkHttp\u662fAndroid\u4e3b\u6d41\u7f51\u7edc\u89e3\u51b3\u65b9\u6848

\u6240\u4ee5\u5982\u679c\u5b58\u5728Net\u6ca1\u6709\u5b9e\u73b0\u7684\u529f\u80fd\u53ef\u4ee5\u8c37\u6b4c\u641c\u7d22\"OkHttp\u5982\u4f55\u5b9e\u73b0XX\", \u7136\u540e\u53ef\u4ee5\u5f88\u5bb9\u6613\u5728Net\u4e2d\u4f7f\u7528

"},{"location":"issues.html#_1","title":"\u4f4e\u7248\u672c\u517c\u5bb9","text":"

\u5982\u679c\u4f60\u662f\u5728 Android 5 (API level 21) \u4ee5\u4e0a\u5f00\u53d1\u5efa\u8bae\u4f7f\u7528\u6700\u65b0\u7248\u672c: Net \u5982\u679c\u8981\u6c42\u4f4e\u81f3 Android 4.4 (API level 19) \u8bf7\u4f7f\u7528\u517c\u5bb9\u7248\u672c: Net-okhttp3

\u5982\u679c\u9700\u66f4\u4f4e\u7248\u672c\u652f\u6301\u5efa\u8bae\u62c9\u53d6\u4ed3\u5e93\u4fee\u6539minSdkVersion\u540e\u7f16\u8bd1\u6210aar\u4f7f\u7528

"},{"location":"issues.html#_2","title":"\u5f00\u53d1\u8005\u4ea4\u6d41","text":"
  • \u53cd\u9988\u95ee\u9898
  • \u5176\u4ed6\u5f00\u53d1\u8005\u63d0\u53ca\u95ee\u9898
  • \u4ea4\u6d41\u793e\u533a
"},{"location":"kotlin-serialization.html","title":"Kotlin-Serialization","text":"
  1. \u4eceNet3\u5f00\u59cb\u652f\u6301\u4f7f\u7528 Kotlin-Serialization (\u4ee5\u4e0b\u7b80\u79f0ks)
  2. \u66f4\u591a\u4e86\u89e3\u8bf7\u9605\u8bfb: Kotlin\u6700\u5f3a\u89e3\u6790\u5e93 - kotlin-serialization
"},{"location":"kotlin-serialization.html#_1","title":"\u7279\u70b9","text":"
  • \u5b98\u65b9\u5e93
  • \u52a8\u6001\u6570\u636e\u7c7b\u578b\u89e3\u6790
  • \u81ea\u5b9a\u4e49\u5e8f\u5217\u5316\u5668
  • \u652f\u6301ProtoBuf/JSON\u7b49\u6570\u636e\u7ed3\u6784\u5e8f\u5217\u5316
  • \u975e\u7a7a\u8986\u76d6(\u5373JSON\u5b57\u6bb5\u4e3anull\u5219\u4f7f\u7528\u53d8\u91cf\u9ed8\u8ba4\u503c)
  • \u542f\u7528\u5bbd\u677e\u6a21\u5f0f, JSON\u548c\u6570\u636e\u7c7b\u7ed3\u6784\u65e0\u9700\u4e00\u81f4
  • \u89e3\u6790\u4efb\u4f55\u7c7b\u578b(Map/List/Pair...)

\u5f3a\u5236\u6ce8\u89e3

ks\u7684\u6570\u636e\u7c7b\u90fd\u8981\u6c42\u4f7f\u7528\u6ce8\u89e3@Serializable(\u9664\u975e\u81ea\u5b9a\u4e49\u89e3\u6790), \u7236\u7c7b\u548c\u5b50\u7c7b\u90fd\u9700\u8981

\u751f\u6210\u9ed8\u8ba4\u503c

\u4f7f\u7528\u63d2\u4ef6\u751f\u6210\u6570\u636eModel, \u652f\u6301\u81ea\u52a8\u751f\u6210\u9ed8\u8ba4\u503c\u548c\u6ce8\u89e3

\u751f\u6210\u9ed8\u8ba4\u503c\u53ef\u907f\u514d\u540e\u7aef\u8fd4\u56de\u5f02\u5e38\u6570\u636e\u5bfc\u81f4\u89e3\u6790\u5d29\u6e83, \u4ee5\u53ca\u53cd\u590d\u7f16\u5199\u5224\u7a7a\u4ee3\u7801

"},{"location":"kotlin-serialization.html#_2","title":"\u4f9d\u8d56","text":"

Project build.gradle

classpath \"org.jetbrains.kotlin:kotlin-serialization:$kotlin_version\"\n// \u548cKotlin\u63d2\u4ef6\u540c\u4e00\u4e2a\u7248\u672c\u53f7\u5373\u53ef\n

Model build.gradle

apply plugin: \"kotlin-kapt\"\napply plugin: 'kotlinx-serialization'\nimplementation \"org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0\"\n
"},{"location":"kotlin-serialization.html#_3","title":"\u914d\u7f6e\u8f6c\u6362\u5668","text":"

\u8fd9\u91cc\u4f7f\u7528\u793a\u4f8b\u4ee3\u7801\u4e2d SerializationConvert \u4f5c\u4e3a\u6f14\u793a

\u5168\u5c40\u914d\u7f6e\u5355\u4f8b\u914d\u7f6e
NetConfig.initialize(Api.HOST, this) {\nsetConverter(SerializationConvert())\n// ... \u5176\u4ed6\u914d\u7f6e\n}\n
val userList = Get<List<UserModel>>(\"list\") {\nconverter = SerializationConvert() // \u5355\u4f8b\u8f6c\u6362\u5668, \u6b64\u65f6\u4f1a\u5ffd\u7565\u5168\u5c40\u8f6c\u6362\u5668\n}.await()\n
"},{"location":"kotlin-serialization.html#_4","title":"\u4f7f\u7528","text":"
scopeNetLife {\nval userList = Get<List<UserModel>>(\"list\") {\nconverter = SerializationConvert()\n}.await()\ntvFragment.text = userList[0].name\n}\n
@Serializable\ndata class UserModel(var name: String, var age: Int, var height: Int)\n
"},{"location":"kotlin-serialization.html#_5","title":"\u5e38\u7528\u914d\u7f6e","text":"

\u4ee5\u4e0b\u4e3a\u53cd\u5e8f\u5217\u5316Json\u5e38\u7528\u914d\u7f6e

val jsonDecoder = Json {\nignoreUnknownKeys = true // \u6570\u636e\u7c7b\u53ef\u4ee5\u4e0d\u7528\u58f0\u660eJson\u7684\u6240\u6709\u5b57\u6bb5\ncoerceInputValues = true // \u5982\u679cJson\u5b57\u6bb5\u662fNull\u5219\u4f7f\u7528\u6570\u636e\u7c7b\u5b57\u6bb5\u9ed8\u8ba4\u503c\n}\n

\u6570\u636e\u7c7b\u4f7f\u7528\u9ed8\u8ba4\u503c

@Serializable\ndata class Data(var name:String = \"\", var age:Int = 0)\n

"},{"location":"kotlin-serialization.html#_6","title":"\u542f\u7528\u9ed8\u8ba4\u503c","text":"

\u5f53coerceInputValues = true\u65f6, json\u5b57\u6bb5\u4e3anull\u6570\u636e\u7c7b\u5b57\u6bb5\u4e3a\u975e\u7a7a\u7c7b\u578b\u60c5\u51b5\u4e0b\u91c7\u7528\u5b57\u6bb5\u9ed8\u8ba4\u503c, \u6ca1\u6709\u9ed8\u8ba4\u503c\u8bf7explicitNulls = false\u5219\u8d4b\u503c\u4e3anull

\u540c\u65f6\u5f53\u51fa\u73b0\u672a\u77e5\u7684\u679a\u4e3e\u7c7b\u578b\u4e5f\u4f1a\u4f7f\u7528\u9ed8\u8ba4\u503c

"},{"location":"kotlin-serialization.html#_7","title":"\u5b57\u6bb5\u7f3a\u5931","text":"

\u901a\u8fc7explicitNulls\u6765\u914d\u7f6e\u5b57\u6bb5\u7f3a\u65f6\u5904\u7406\u65b9\u5f0f

  • \u53cd\u5e8f\u5217\u5316\u65f6, \u5982\u679c\u6570\u636e\u7c7b\u7f3a\u5931\u5b57\u6bb5, \u4f7f\u7528ignoreUnknownKeys = true\u5c31\u4f1a\u81ea\u52a8\u4f7f\u7528\u9ed8\u8ba4\u503c, \u6ca1\u6709\u9ed8\u8ba4\u503c\u8bf7explicitNulls = false\u8d4b\u503c\u4e3anull
  • \u5e8f\u5217\u5316\u65f6, \u6570\u636e\u7c7b\u5982\u679c\u5b57\u6bb5\u4e3anull\u4e5f\u4f1a\u88ab\u8d4b\u503c\u5230json\u4e2d, explicitNulls = false\u53ef\u4ee5\u5ffd\u7565\u6389
"},{"location":"kotlin-serialization.html#_8","title":"\u81ea\u52a8\u751f\u6210","text":"

\u624b\u52a8\u5199\u9ed8\u8ba4\u503c\u592a\u9ebb\u70e6, \u63a8\u8350\u4f7f\u7528\u63d2\u4ef6\u751f\u6210\u9ed8\u8ba4\u503c

\u63d2\u4ef6\u5177\u4f53\u914d\u7f6e\u4f7f\u7528\u8bf7\u67e5\u770b: \u6570\u636e\u6a21\u578b\u751f\u6210\u63d2\u4ef6

"},{"location":"log-notice.html","title":"\u65e5\u5fd7\u901a\u77e5","text":"

\u4f7f\u7528\u4e09\u65b9\u5e93 Chucker \u5728\u901a\u77e5\u680f\u8bb0\u5f55\u7f51\u7edc\u8bf7\u6c42\u65e5\u5fd7

Chucker

\u4f9d\u8d56

implementation \"com.github.chuckerteam.chucker:library:3.5.2\"\n

\u6dfb\u52a0\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\n// ...\nif (BuildConfig.DEBUG) {\naddInterceptor(\nChuckerInterceptor.Builder(this@App)\n.collector(ChuckerCollector(this@App))\n.maxContentLength(250000L)\n.redactHeaders(emptySet())\n.alwaysReadResponseBody(false)\n.build()\n)\n}\n}\n

\u81ea\u5b9a\u4e49\u529f\u80fd\u6d4f\u89c8 Chucker \u5b98\u7f51

"},{"location":"log-recorder.html","title":"\u65e5\u5fd7\u63d2\u4ef6","text":"

\u4e24\u79cd\u65e5\u5fd7\u63d2\u4ef6

Okhttp Profiler Profiler \u5217\u8868\u663e\u793a \u52a8\u6001\u66f2\u7ebf\u56fe \u8981\u6c42\u6dfb\u52a0LogRecordInterceptor \u53ef\u67e5\u770b\u6240\u6709OkHttp\u7684\u8bf7\u6c42 \u539f\u7406\u662f\u63d2\u4ef6\u6355\u83b7LogCat\u65e5\u5fd7, \u7ebf\u4e0a\u73af\u5883\u8bf7\u5173\u95ed \u65e0\u6cd5\u6355\u83b7\u542f\u52a8\u4e00\u77ac\u95f4\u7684\u8bf7\u6c42"},{"location":"log-recorder.html#logrecordinterceptor","title":"LogRecordInterceptor","text":"

\u6dfb\u52a0\u65e5\u5fd7\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\naddInterceptor(LogRecordInterceptor(BuildConfig.DEBUG))\n}\n
\u6784\u9020\u53c2\u6570 \u63cf\u8ff0 enabled \u662f\u5426\u542f\u7528\u65e5\u5fd7 requestByteCount \u8bf7\u6c42\u65e5\u5fd7\u4fe1\u606f\u6700\u5927\u5b57\u8282\u6570, \u9ed8\u8ba41MB responseByteCount \u54cd\u5e94\u65e5\u5fd7\u4fe1\u606f\u6700\u5927\u5b57\u8282\u6570, \u9ed8\u8ba44MB

\u6b64\u65f6\u4ec5LogCat\u8f93\u51fa\u65e5\u5fd7, \u8981\u9884\u89c8\u8bf7\u5b89\u88c5\u63d2\u4ef6

"},{"location":"log-recorder.html#_1","title":"\u5b89\u88c5\u63d2\u4ef6","text":""},{"location":"log-recorder.html#1","title":"1. \u5b89\u88c5\u63d2\u4ef6","text":"

\u5728\u63d2\u4ef6\u5e02\u573a\u641c\u7d22: \"Okhttp Profiler\"

"},{"location":"log-recorder.html#2","title":"2. \u6253\u5f00\u7a97\u53e3","text":"

\u5b89\u88c5\u4ee5\u540e\u5728AndroidStudio\u53f3\u4e0b\u89d2\u6253\u5f00\u7a97\u53e3

\u4e0d\u663e\u793a\u65e5\u5fd7

\u8bf7\u5728\u8bf7\u6c42\u524d\u786e\u4fdd\u6709\u6253\u5f00\u8fc7\u63d2\u4ef6\u7a97\u53e3, \u5982\u679c\u4f9d\u7136\u4e0d\u663e\u793a\u53ef\u4ee5\u53cd\u590d\u6253\u5f00/\u5173\u95ed\u7a97\u53e3

\u6bcf\u6b21AS\u66f4\u65b0\u90fd\u9700\u8981\u8be5\u63d2\u4ef6\u4f5c\u8005\u9002\u914d, \u53ef\u80fd\u5b58\u5728beta\u7248\u672c\u4f5c\u8005\u6ca1\u6709\u9002\u914d\u60c5\u51b5

\u4f7f\u7528\u6548\u679c

\u6807\u9898 \u63cf\u8ff0 Device \u9009\u62e9\u8c03\u8bd5\u8bbe\u5907 Process \u9009\u62e9\u5c55\u793a\u8bb0\u5f55\u7684\u8fdb\u7a0b \u6293\u53d6 \u4e00\u822c\u60c5\u51b5\u4e0d\u9700\u8981\u4f7f\u7528, \u5047\u8bbe\u6ca1\u6709\u53ca\u65f6\u66f4\u65b0\u8bf7\u70b9\u51fb\u56fe\u6807 \u6e05\u7a7a \u6e05\u7a7a\u8bb0\u5f55"},{"location":"log-recorder.html#_2","title":"\u81ea\u5b9a\u4e49\u65e5\u5fd7","text":"

\u7ee7\u627fLogRecordInterceptor\u590d\u5199\u51fd\u6570\u5b9e\u73b0\u81ea\u5b9a\u4e49

  1. \u590d\u5199getRequestLog\u8fd4\u56de\u89e3\u5bc6\u8bf7\u6c42\u53c2\u6570
  2. \u590d\u5199getResponseLog\u8fd4\u56de\u89e3\u5bc6\u54cd\u5e94\u53c2\u6570

\u521d\u59cb\u5316\u65f6\u6dfb\u52a0\u81ea\u5df1\u7684\u62e6\u622a\u5668

NetConfig.initialize(Api.HOST, this) {\naddInterceptor(MyLogRecordInterceptor(BuildConfig.DEBUG))\n}\n
"},{"location":"log-recorder.html#_3","title":"\u65e5\u5fd7\u8fc7\u6ee4","text":"

\u4e0d\u60f3\u7f51\u7edc\u65e5\u5fd7\u5f71\u54cd\u5176\u4ed6\u65e5\u5fd7\u67e5\u770b, \u53ef\u4ee5\u6dfb\u52a0OKPREL_\u4e3a\u65e5\u5fd7\u6298\u53e0\u89c4\u5219

"},{"location":"log-recorder.html#_4","title":"\u5176\u4ed6\u7f51\u7edc\u6846\u67b6","text":"

LogRecordInterceptor\u5c5e\u4e8eOkHttp\u62e6\u622a\u5668, \u5176\u4ed6\u7f51\u7edc\u8bf7\u6c42\u6846\u67b6\u4e5f\u53ef\u4ee5\u4f7f\u7528

\u751a\u81f3\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528LogRecorder\u8f93\u51fa\u65e5\u5fd7

LogRecorder \u63cf\u8ff0 generateId \u4ea7\u751f\u4e00\u4e2a\u552f\u4e00\u6807\u8bc6\u7b26, \u7528\u4e8e\u5224\u65ad\u4e3a\u540c\u4e00\u7f51\u7edc\u8bf7\u6c42 recordRequest \u8bb0\u5f55\u8bf7\u6c42\u4fe1\u606f recordResponse \u8bb0\u5f55\u54cd\u5e94\u4fe1\u606f recordException \u8bb0\u5f55\u8bf7\u6c42\u5f02\u5e38\u4fe1\u606f"},{"location":"model-generate.html","title":"\u6570\u636e\u7c7b\u751f\u6210\u63d2\u4ef6","text":"

\u5e94\u8be5\u6ca1\u4eba\u4f1a\u5b8c\u5168\u624b\u5199\u6570\u636e\u6a21\u578b\u5427? \u5efa\u8bae\u4f7f\u7528JSON To Kotlin Class \u63d2\u4ef6\u5b8c\u6210

"},{"location":"model-generate.html#_1","title":"\u5b89\u88c5\u63d2\u4ef6","text":"

\u5728Plugins\u91cc\u9762\u641c\u7d22kotlin\u5173\u952e\u8bcd\u4e0b\u8f7d\u5b89\u88c5

"},{"location":"model-generate.html#_2","title":"\u4f7f\u7528\u63d2\u4ef6","text":"

\u9009\u4e2d\u5206\u5305\u540e, \u4f7f\u7528\u5feb\u6377\u952e\u6216\u8005\u9f20\u6807\u53f3\u952e\u6253\u5f00\u586b\u5199Json\u754c\u9762

\u6dfb\u52a0Json\u7136\u540e\u70b9\u51fbGenerate\u751f\u6210

\u7136\u540e\u5c31\u4f1a\u5728\u9009\u4e2d\u7684\u5206\u5305\u4e0b\u751f\u6210\u4e00\u4e2a\u6570\u636e\u6a21\u578b\u7c7b\u4e86

\u4e0d\u8981\u751f\u6210\u6570\u7ec4

\u4e0d\u8981\u8f93\u5165JSON\u6570\u7ec4\u751f\u6210(\u5426\u5219\u751f\u6210\u7684\u7c7b\u4f1a\u7ee7\u627fArrayList), \u8f93\u5165JSON\u5bf9\u8c61, \u8bf7\u6c42\u4f7f\u7528Get<List<\u5bf9\u8c61>>

"},{"location":"model-generate.html#_3","title":"\u9ad8\u7ea7\u8bbe\u7f6e","text":"

\u70b9\u51fbAdvanced\u6253\u5f00\u8bbe\u7f6e\u754c\u9762

"},{"location":"model-generate.html#_4","title":"\u53ef\u7a7a\u9009\u9879","text":"

\u622a\u56fe\u5373\u4e3a\u6211\u7684\u63a8\u8350\u914d\u7f6e

  1. Keyword \u521b\u5efa\u7684\u6570\u636e\u6a21\u578b\u7684\u5b57\u6bb5\u662f Val\u8fd8\u662fVar
  2. Type \u5b57\u6bb5\u662f\u5426\u662f\u53ef\u7a7a\u7c7b\u578b, \u6700\u540e\u9009\u9879\u8868\u793a\u6839\u636eJson\u7684\u503c\u5224\u65ad\u662f\u5426\u53ef\u7a7a
  3. \u9ed8\u8ba4\u503c\u7684\u7b56\u7565, \u65e0\u6cd5\u9009\u62e9\u4e0d\u4ecb\u7ecd
"},{"location":"model-generate.html#_5","title":"\u4f7f\u7528\u7684\u6846\u67b6","text":"

\u751f\u6210\u6570\u636e\u6a21\u578b\u65f6\u4f1a\u517c\u5bb9\u4f60\u4f7f\u7528\u7684\u6846\u67b6, \u4f8b\u5982Moshi\u548cks\u53ef\u80fd\u9700\u8981\u6ce8\u89e3, \u7136\u540e\u4f1a\u81ea\u52a8\u751f\u6210SerialName\u8fd9\u4e9b\u540d\u79f0\u6ce8\u89e3

"},{"location":"model-generate.html#_6","title":"\u5176\u4ed6","text":"

\u622a\u56fe\u5373\u4e3a\u6211\u7684\u63a8\u8350\u914d\u7f6e

  1. \u662f\u5426\u4f7f\u7528\u6ce8\u91ca, \u65e2\u4f1a\u5c06Json\u5b57\u7b26\u4e32\u4f5c\u4e3a\u6ce8\u91ca\u4fdd\u7559\u5728\u6570\u636e\u6a21\u578b\u7c7b\u4e2d
  2. \u6839\u636e\u5b57\u6bcd\u6392\u5e8f\u6570\u636e\u6a21\u578b\u7684\u5b57\u6bb5
  3. \u4f7f\u7528\u5185\u90e8\u7c7b. \u4f8b\u5982Json\u4e2d\u7684Json\u5bf9\u8c61\u4f1a\u4f5c\u4e3a\u5185\u90e8\u7c7b\u88ab\u521b\u5efa\u5728\u6570\u636e\u6a21\u578b\u7c7b\u4e2d (\u63a8\u8350\u5f00\u542f, \u4fdd\u6301\u9ad8\u5185\u805a\u4f4e\u8026\u5408)
  4. \u5982\u679cJson\u5bf9\u8c61\u7684\u5b57\u6bb5\u90fd\u662f\u539f\u59cb\u7c7b\u578b\u5219\u4f7f\u7528Map\u6765\u8868\u793a
  5. \u53ea\u5728\u9700\u8981\u65f6\u521b\u5efa\u6ce8\u89e3
  6. \u81ea\u52a8\u9a8c\u8bc1Json\u6b63\u786e\u6027(\u5728\u586b\u5199\u65f6)
  7. Json\u683c\u5f0f\u5316\u65f6\u4f7f\u7528\u7684\u7a7a\u683c\u6570\u91cf
  8. \u6307\u5b9a\u4e00\u4e2a\u7c7b\u4f5c\u4e3a\u7236\u7c7b\u6a21\u677f(\u65e2\u521b\u5efa\u7684\u6570\u636e\u6a21\u578b\u90fd\u4f1a\u7ee7\u627f\u8be5\u7c7b)
"},{"location":"model-generate.html#_7","title":"\u6269\u5c55","text":"

\u622a\u56fe\u5373\u4e3a\u6211\u7684\u63a8\u8350\u914d\u7f6e

  1. \u6dfb\u52a0@Keep\u6ce8\u89e3, \u4e3a\u9632\u6b62\u88ab\u4ee3\u7801\u6df7\u6dc6
  2. \u6ce8\u89e3\u548c\u5b57\u6bb5\u5904\u4e8e\u540c\u4e00\u884c, \u4fbf\u4e8e\u7f8e\u89c2
  3. \u4f7f\u7528Parcelable\u5e8f\u5217\u5316
  4. \u4e3a\u5b57\u6bb5\u6dfb\u52a0\u524d\u7f00/\u540e\u7f00
  5. \u4e3a\u6570\u636e\u6a21\u578b\u7c7b\u6dfb\u52a0\u524d\u7f00/\u540e\u7f00
"},{"location":"okhttp-client.html","title":"OkHttpClient","text":"

Net\u5168\u5c40\u6301\u6709\u4e00\u4e2aOkHttpClient\u5bf9\u8c61\u53d1\u8d77\u8bf7\u6c42

object NetConfig {\nvar okHttpClient: OkHttpClient\n}\n
"},{"location":"okhttp-client.html#_1","title":"\u5168\u5c40","text":"
NetConfig.initialize(Api.HOST, this) {\n// \u6b64\u5904this\u5373\u4e3aOkHttpClient.Builder\n}\n
"},{"location":"okhttp-client.html#_2","title":"\u5355\u4f8b","text":"

\u53ef\u4ee5\u5355\u72ec\u6307\u5b9a\u5f53\u524d\u8bf7\u6c42\u5ba2\u6237\u7aef

\u4fee\u6539\u5168\u5c40\u5ba2\u6237\u7aef\u521b\u5efa\u65b0\u5ba2\u6237\u7aef

scopeNetLife {\ntv_response.text = Get<String>(Api.PATH) {\nsetClient {\n// \u6b64\u5904this\u5373\u4e3aOkHttpClient.Builder\ntrustCertificate()\n}\n}.await()\n}\n
\u5728\u5168\u5c40OkHttpClient\u57fa\u7840\u4e0a\u4fee\u6539

scopeNetLife {\ntv_response.text = Get<String>(Api.PATH) {\nokHttpClient = OkHttpClient.Builder().build()\n}.await()\n}\n
\u521b\u5efa\u65b0\u7684OkHttpClient, \u4e00\u822c\u4e0d\u4f7f\u7528, \u56e0\u4e3a\u65b0OkHttpClient\u4f1a\u91cd\u65b0\u521b\u5efa\u7ebf\u7a0b\u6c60/\u8fde\u63a5\u6c60\u7b49\u9020\u6210\u5185\u5b58\u6d88\u8017

"},{"location":"progress.html","title":"\u8fdb\u5ea6\u76d1\u542c","text":"

Net\u652f\u6301\u4e0a\u4f20/\u4e0b\u8f7d\u7684\u8fdb\u5ea6\u76d1\u542c, \u4e14\u5177\u5907\u5b8c\u5584\u7684\u8fdb\u5ea6\u4fe1\u606f

"},{"location":"progress.html#_1","title":"\u4e0a\u4f20\u8fdb\u5ea6\u76d1\u542c","text":"
scopeNetLife {\nPost<String>(Api.UPLOAD) {\nparam(\"file\", assetsFile())\naddUploadListener(object : ProgressListener() {\noverride fun onProgress(p: Progress) {\nseek.post {\nseek.progress = p.progress()\ntvProgress.text =\n\"\u4e0a\u4f20\u8fdb\u5ea6: ${p.progress()}% \u4e0a\u4f20\u901f\u5ea6: ${p.speedSize()}     \" +\n\"\\n\\n\u6587\u4ef6\u5927\u5c0f: ${p.totalSize()}  \u5df2\u4e0a\u4f20: ${p.currentSize()}  \u5269\u4f59\u5927\u5c0f: ${p.remainSize()}\" +\n\"\\n\\n\u5df2\u4f7f\u7528\u65f6\u95f4: ${p.useTime()}  \u5269\u4f59\u65f6\u95f4: ${p.remainTime()}\"\n}\n}\n})\n}.await()\n}\n
"},{"location":"progress.html#_2","title":"\u4e0b\u8f7d\u8fdb\u5ea6\u76d1\u542c","text":"
scopeNetLife {\nval file =\nGet<File>(\"https://github.com/liangjingkanji/Net/releases/latest/download/net-sample.apk\") {\nsetDownloadFileName(\"net.apk\")\nsetDownloadDir(requireContext().filesDir)\naddDownloadListener(object : ProgressListener() {\noverride fun onProgress(p: Progress) {\nseek?.post {\nval progress = p.progress()\nseek.progress = progress\ntvProgress.text =\n\"\u4e0b\u8f7d\u8fdb\u5ea6: $progress% \u4e0b\u8f7d\u901f\u5ea6: ${p.speedSize()}     \" +\n\"\\n\\n\u6587\u4ef6\u5927\u5c0f: ${p.totalSize()}  \u5df2\u4e0b\u8f7d: ${p.currentSize()}  \u5269\u4f59\u5927\u5c0f: ${p.remainSize()}\" +\n\"\\n\\n\u5df2\u4f7f\u7528\u65f6\u95f4: ${p.useTime()}  \u5269\u4f59\u65f6\u95f4: ${p.remainTime()}\"\n}\n}\n})\n}.await()\n}\n

\u76d1\u542c\u4efb\u4f55\u8fdb\u5ea6

\u4e0d\u4ec5\u662f\u6cdb\u578b\u4e3aFile\u624d\u6709\u6548, \u4efb\u4f55\u8bf7\u6c42/\u54cd\u5e94\u90fd\u53ef\u4ee5\u76d1\u542c\u8fdb\u5ea6

"},{"location":"progress.html#_3","title":"\u76d1\u542c\u5668","text":"

\u5b9e\u73b0ProgressListener\u76d1\u542c\u8fdb\u5ea6\u4fe1\u606f. \u8fdb\u5ea6\u4fe1\u606f\u4e3aProgress

"},{"location":"progress.html#_4","title":"\u8fdb\u5ea6\u95f4\u9694\u65f6\u95f4","text":"

ProgressListener\u7684\u6784\u9020\u53c2\u6570interval\u63a7\u5236\u89e6\u53d1\u8fdb\u5ea6\u76d1\u542c\u5668\u7684\u95f4\u9694\u65f6\u95f4

"},{"location":"progress.html#_5","title":"\u8fdb\u5ea6\u4fe1\u606f","text":"\u51fd\u6570 \u63cf\u8ff0 currentBytes \u5df2\u5b8c\u6210\u5b57\u8282\u6570 totalBytes \u5168\u90e8\u5927\u5c0f\u5b57\u8282\u6570 intervalBytes \u8fdb\u5ea6\u95f4\u9694\u65f6\u95f4\u5185\u5b8c\u6210\u7684\u5b57\u8282\u6570 intervalTime \u8ddd\u79bb\u4e0a\u6b21\u8fdb\u5ea6\u53d8\u5316\u95f4\u9694\u65f6\u95f4 startElapsedRealtime \u5f00\u59cb\u4e0b\u8f7d\u65f6\u95f4(\u8be5\u65f6\u95f4\u503c\u5f00\u673a\u5230\u73b0\u5728\u7684\u6beb\u79d2\u6570) speedBytes \u6bcf\u79d2\u4e0b\u8f7d\u5b57\u8282\u6570 progress \u8fdb\u5ea6, 1-100 finish \u6b64\u6b21\u4e0b\u8f7d/\u4e0a\u4f20\u662f\u5426\u5b8c\u6210 useTimeSeconds \u5df2\u7ecf\u4f7f\u7528\u65f6\u95f4, \u5355\u4f4d\u79d2 remainTimeSeconds \u4f30\u7b97\u7684\u5269\u4f59\u65f6\u95f4, \u5355\u4f4d\u79d2"},{"location":"progress.html#_6","title":"\u683c\u5f0f\u5316\u5b57\u7b26\u4e32","text":"\u51fd\u6570 \u63cf\u8ff0 currentSize \u5df2\u5b8c\u6210\u5927\u5c0f, \u4f8b\u5982: 120kB \u6216\u8005 1.5MB totalSize \u5168\u90e8\u5927\u5c0f remainSize \u5269\u4f59\u5927\u5c0f speedSize \u6bcf\u79d2\u4e0b\u8f7d\u5927\u5c0f useTime \u5df2\u4f7f\u7528\u65f6\u95f4, \u683c\u5f0f\u4e3a: 01:23:04 remainTime \u4f30\u7b97\u7684\u5269\u4f59\u65f6\u95f4, \u683c\u5f0f\u4e3a: 01:23:04"},{"location":"repeat-request.html","title":"\u91cd\u590d\u8bf7\u6c42","text":"

\u5e38\u7528\u4e8e\u7b5b\u9009\u5217\u8868\u8bf7\u6c42, \u9009\u62e9\u65b0\u7684\u7b5b\u9009\u6761\u4ef6\u65f6\u5e94\u5c06\u4e0a\u6b21\u672a\u5b8c\u6210\u7684\u53d6\u6d88\u540e\u518d\u53d1\u8d77\u8bf7\u6c42

\u5728Net\u7981\u6b62\u91cd\u590d\u8bf7\u6c42\u4ec52\u884c\u4ee3\u7801

var scope: AndroidScope? = null\nbtnFilter.setOnClickListener {\nscope?.cancel()\nscope = scopeNetLife {\nval result = Post<String>(\"api\").await()\n}\n}\n

\u5f53scope\u4e0d\u4e3a\u7a7a\u65f6\u8868\u793a\u5b58\u5728\u65e7\u8bf7\u6c42, \u65e0\u8bba\u65e7\u8bf7\u6c42\u662f\u5426\u5b8c\u6210\u90fd\u53ef\u4ee5\u8c03\u7528cancel()\u4fdd\u8bc1\u53d6\u6d88\u5373\u53ef

  1. \u53d6\u6d88\u8bf7\u6c42
  2. \u9650\u5236\u65f6\u95f4\u5f3a\u5236\u4f7f\u7528\u7f13\u5b58, \u914d\u7f6e\u7f13\u5b58\u6709\u6548\u671f
"},{"location":"request.html","title":"\u8bf7\u6c42\u53c2\u6570","text":"

\u8bf7\u6c42\u53c2\u6570

\u6839\u636e\u8bf7\u6c42\u65b9\u5f0f\u4e0d\u540c\u8bf7\u6c42\u53c2\u6570\u5206\u4e3a\u4e24\u7c7b

UrlRequest: GET, HEAD, OPTIONS, TRACE // Query(\u8bf7\u6c42\u53c2\u6570\u4f4d\u4e8eUrl\u4e2d) BodyRequest: POST, DELETE, PUT, PATCH // Body(\u8bf7\u6c42\u4f53\u4e3a\u6d41)

\u4f7f\u7528\u793a\u4f8b

scopeNetLife {\nval userInfo = Post<UserInfoModel>(Api.LOGIN) {\nparam(\"username\", \"\u7528\u6237\u540d\")\nparam(\"password\", \"6f2961eb44b12123393fff7e449e50b9de2499c6\")\n}.await()\n}\n
\u51fd\u6570 \u63cf\u8ff0 param Url\u8bf7\u6c42\u65f6\u4e3aQuery, Body\u8bf7\u6c42\u65f6\u4e3a\u8868\u5355/\u6587\u4ef6 json JSON\u5b57\u7b26\u4e32 setQuery/addQuery Url\u4e2d\u7684Query\u53c2\u6570, \u5982\u679c\u5f53\u4e3aUrl\u8bf7\u6c42\u5219\u8be5\u51fd\u6570\u7b49\u6548param setHeader/addHeader \u8bbe\u7f6e/\u6dfb\u52a0\u8bf7\u6c42\u5934"},{"location":"request.html#json","title":"JSON","text":"

\u4e09\u79cd\u53c2\u6570\u7c7b\u578b\u4e0a\u4f20JSON\u793a\u4f8b, \u66f4\u591a\u8bf7\u9605\u8bfb\u65b9\u6cd5\u6ce8\u91ca

\u952e\u503c\u5bf9JSONObject\u81ea\u5b9a\u4e49RequestBody
val name = \"\u91d1\u57ce\u6b66\"\nval age = 29\nval measurements = listOf(100, 100, 100)\nscopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\n// \u53ea\u652f\u6301\u57fa\u7840\u7c7b\u578b\u7684\u503c, \u5982\u679c\u503c\u4e3a\u5bf9\u8c61\u6216\u8005\u5305\u542b\u5bf9\u8c61\u7684\u96c6\u5408/\u6570\u7ec4\u4f1a\u5bfc\u81f4\u5176\u503c\u4e3anull\njson(\"name\" to name, \"age\" to age, \"measurements\" to measurements)\n}.await()\n}\n
val name = \"\u91d1\u57ce\u6b66\"\nval age = 29\nval measurements = listOf(100, 100, 100) // \u53ea\u652f\u6301\u57fa\u7840\u7c7b\u578b\u7684\u503c, \u5982\u679c\u503c\u4e3a\u5bf9\u8c61\u6216\u8005\u5305\u542b\u5bf9\u8c61\u7684\u96c6\u5408/\u6570\u7ec4\u4f1a\u5bfc\u81f4\u5176\u503c\u4e3anull\nscopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\njson(JSONObject().run {\nput(\"name\", name)\nput(\"age\", age)\nput(\"measurements\", JSONArray(measurements))\n})\n}.await()\n}\n
val name = \"\u91d1\u57ce\u6b66\"\nval age = 29\nval measurements = listOf(100, 100, 100)\nscopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\nbody = CustomizerJSONBody(name, age, measurements)\n}.await()\n}\n

\u5982\u679cJSON\u9700\u8981\u5168\u5c40\u53c2\u6570

  1. \u81ea\u5b9a\u4e49RequestBody\u6dfb\u52a0\u5168\u5c40\u53c2\u6570
  2. \u4f7f\u7528\u8bf7\u6c42\u62e6\u622a\u5668\u6765\u6dfb\u52a0\u5168\u5c40\u53c2\u6570 RequestInterceptor
"},{"location":"request.html#_1","title":"\u81ea\u5b9a\u4e49\u6269\u5c55\u51fd\u6570","text":"

\u7531\u4e8ejson()\u4e0d\u80fd\u4f20\u5bf9\u8c61, \u56e0\u4e3a\u4f7f\u7528\u7684org.json.JSONObject\u5176\u4e0d\u652f\u6301\u6620\u5c04\u5bf9\u8c61\u5b57\u6bb5

\u4f46\u53ef\u521b\u5efa\u6269\u5c55\u51fd\u6570\u6765\u4f7f\u7528\u5c04\u5bf9\u8c61\u5e8f\u5217\u5316\u6846\u67b6\u6765\u89e3\u6790, \u5982\u4e0b

GsonFastJson
fun BodyRequest.gson(vararg body: Pair<String, Any?>) {\nthis.body = Gson().toJson(body.toMap()).toRequestBody(MediaConst.JSON)\n}\n
fun BodyRequest.fastJson(vararg body: Pair<String, Any?>) {\nthis.body = JSON.toJSON(body.toMap()).toRequestBody(MediaConst.JSON)\n}\n

\u4f7f\u7528

scopeNetLife {\ntvFragment.text = Post<String>(\"api\") {\ngson(\"name\" to name, \"model\" to Model()) // \u53c2\u6570\u652f\u6301Gson\u53ef\u89e3\u6790\u7684\u5bf9\u8c61\n// fastJson(\"name\" to name, \"model\" to Model()) // \u4f7f\u7528FastJson\n}.await()\n}\n
"},{"location":"request.html#_2","title":"\u5168\u5c40\u8bf7\u6c42\u53c2\u6570","text":"

\u4f7f\u7528RequestInterceptor\u8bf7\u6c42\u62e6\u622a\u5668\u6dfb\u52a0\u5168\u5c40\u53c2\u6570/\u8bf7\u6c42\u5934, \u66f4\u590d\u6742\u8bf7\u5b9e\u73b0Interceptor

class GlobalHeaderInterceptor : RequestInterceptor {\n// \u6bcf\u6b21\u8bf7\u6c42\u90fd\u4f1a\u56de\u8c03, \u53ef\u4ee5\u662f\u52a8\u6001\u53c2\u6570\noverride fun interceptor(request: BaseRequest) {\nrequest.setHeader(\"client\", \"Android\")\nrequest.setHeader(\"token\", UserConfig.token)\n}\n}\n
NetConfig.initialize(Api.HOST, this) {\nsetRequestInterceptor(GlobalHeaderInterceptor())\n}\n

\u66f4\u591a\u8bf7\u6c42\u53c2\u6570\u76f8\u5173\u8bf7\u9605\u8bfbApi\u6587\u6863/\u51fd\u6570\u5217\u8868

"},{"location":"scope.html","title":"\u4f5c\u7528\u57df","text":"

\u521b\u5efa\u4e0d\u540c\u534f\u7a0b\u4f5c\u7528\u57df\u53ef\u4ee5\u5b9e\u73b0\u4e0d\u540c\u7684\u529f\u80fd

\u51cf\u5c11\u5d29\u6e83

Net\u6240\u6709\u4f5c\u7528\u57df\u5185\u629b\u51fa\u5f02\u5e38\u90fd\u4f1a\u88ab\u6355\u83b7\u5230, \u53ef\u4ee5\u9632\u6b62\u5e94\u7528\u5d29\u6e83

"},{"location":"scope.html#_1","title":"\u5f02\u6b65\u4efb\u52a1\u7684\u4f5c\u7528\u57df","text":"

\u53ef\u4ee5\u6355\u6349\u5f02\u5e38\u7684\u534f\u7a0b\u4f5c\u7528\u57df, \u7528\u4e8e\u6784\u5efa\u666e\u901a\u5f02\u6b65\u4efb\u52a1

\u51fd\u6570 \u63cf\u8ff0 scope \u521b\u5efa\u6700\u57fa\u7840\u7684\u4f5c\u7528\u57df scopeLife \u521b\u5efa\u8ddf\u968f\u751f\u547d\u5468\u671f\u81ea\u52a8\u53d6\u6d88\u7684\u4f5c\u7528\u57df ViewModel.scopeLife \u521b\u5efa\u8ddf\u968fViewModel\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df, \u5982\u4f55\u5728ViewModel\u521b\u5efa\u4f5c\u7528\u57df"},{"location":"scope.html#_2","title":"\u7f51\u7edc\u8bf7\u6c42\u7684\u4f5c\u7528\u57df","text":"

\u9664\u5f02\u6b65\u4efb\u52a1\u5916\u8fd8\u9002\u7528\u4e8e\u7f51\u7edc\u8bf7\u6c42\u573a\u666f\u7684\u4f5c\u7528\u57df, \u5bf9\u6bd4\u4e0a\u9762\u5f02\u6b65\u4efb\u52a1\u7684\u4f5c\u7528\u57df\u533a\u522b:

  1. \u53d1\u751f\u9519\u8bef\u81ea\u52a8\u5410\u53f8(\u53ef\u4ee5\u81ea\u5b9a\u4e49\u6216\u8005\u53d6\u6d88)
  2. \u53d1\u751f\u9519\u8bef\u4f1a\u89e6\u53d1\u5168\u5c40\u9519\u8bef\u5904\u7406NetErrorHandler
  3. \u5177\u5907\u4e00\u4e9b\u7279\u6b8a\u573a\u666f\u529f\u80fd, \u6bd4\u5982\u6839\u636e\u7f51\u7edc\u8bf7\u6c42\u7ed3\u679c\u81ea\u52a8\u5904\u7406\u4e0b\u62c9\u5237\u65b0/\u4e0a\u62c9\u52a0\u8f7d/\u7f3a\u7701\u9875/\u52a0\u8f7d\u6846\u7684\u72b6\u6001
\u51fd\u6570 \u63cf\u8ff0 scopeNet \u521b\u5efa\u81ea\u52a8\u5904\u7406\u7f51\u7edc\u9519\u8bef\u7684\u4f5c\u7528\u57df scopeNetLife \u521b\u5efa\u81ea\u52a8\u5904\u7406\u7f51\u7edc\u9519\u8bef\u7684\u4f5c\u7528\u57df, \u4e14\u5305\u542b\u8ddf\u968fActivity\u6216\u8005Fragment\u751f\u547d\u5468\u671f scopeDialog \u521b\u5efa\u81ea\u52a8\u52a0\u8f7d\u5bf9\u8bdd\u6846\u7684\u4f5c\u7528\u57df, \u751f\u547d\u5468\u671f\u8ddf\u968f\u5bf9\u8bdd\u6846 ViewModel.scopeNetLife \u521b\u5efa\u8ddf\u968fViewModel\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df, \u5982\u4f55\u5728ViewModel\u521b\u5efa\u4f5c\u7528\u57df PageRefreshLayout.scope \u521b\u5efa\u8ddf\u968fPageRefreshLayout\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df StateLayout.scope \u521b\u5efa\u8ddf\u968fStateLayout\u751f\u547d\u5468\u671f\u7684\u4f5c\u7528\u57df

\u533a\u5206\u51fd\u6570\u63a5\u53d7\u8005

\u6ce8\u610fStateLayout.scope\u7b49\u5b58\u5728\u51fd\u6570\u63a5\u53d7\u8005\u7684\u65b9\u6cd5\u548cscope\u5c5e\u4e8e\u4e24\u4e2a\u65b9\u6cd5, \u4e25\u7981\u6df7\u7528

\u7b2c\u4e09\u65b9\u5e93\u652f\u6301

PageRefreshLayout/StateLayout \u5c5e\u4e8e\u7b2c\u4e09\u65b9\u5f00\u6e90\u9879\u76ee BRV \u6846\u67b6\u4e2d\u7684\u5e03\u5c40, \u53ef\u7528\u4e8e\u652f\u6301\u81ea\u52a8\u5316\u7f3a\u7701\u9875/\u4e0b\u62c9\u5237\u65b0

\u5982\u679c\u60f3\u66f4\u4e86\u89e3\u534f\u7a0b\u4f7f\u7528\u65b9\u5f0f, \u53ef\u4ee5\u9605\u8bfb\u4e00\u7bc7\u6587\u7ae0: \u6700\u5168\u9762\u7684Kotlin\u534f\u7a0b: Coroutine/Channel/Flow \u4ee5\u53ca\u5b9e\u9645\u5e94\u7528

"},{"location":"scope.html#_3","title":"\u5d4c\u5957\u4f5c\u7528\u57df","text":"

\u6709\u65f6\u5019\u53ef\u80fd\u9762\u4e34\u5185\u5d4cscopeXX\u51fd\u6570(\u5d4c\u5957\u4f5c\u7528\u57df), \u8fd9\u65f6\u5019\u751f\u547d\u5468\u671f\u5982\u4e0b

scopeNetLife {\nval task = Post<String>(\"api0\").await()\nscopeNetLife {\nval task = Post<String>(\"api0\").await() // \u6b64\u65f6\u53d1\u751f\u8bf7\u6c42\u9519\u8bef\n}.catch {\n// A\n}\n}.catch {\n// B\n}\n
  • \u9519\u8bef\u5c06\u5728A\u5904\u53ef\u4ee5\u83b7\u53d6\u5230, \u4e14\u4e0d\u5f71\u54cd\u5916\u90e8scopeNetLife\u7684\u8bf7\u6c42
  • \u4e24\u4e2ascopeNetLife\u7684\u5f02\u5e38\u629b\u51fa\u548c\u6355\u83b7\u4e92\u4e0d\u5f71\u54cd
  • scopeXX()\u7b49\u51fd\u6570\u540c\u7406
"},{"location":"scope.html#_4","title":"\u5b50\u4f5c\u7528\u57df","text":"
scopeNet {\nval await = Post<String>(\"api\").await()\nlaunch {\nval task = Post<String>(\"api0\").await()  // \u6b64\u65f6\u53d1\u751f\u8bf7\u6c42\u9519\u8bef\n}.invokeOnCompletion {\n// A\n}\n}.catch {\n// B\n}\n
  • \u8fd9\u79cd\u60c5\u51b5 \u5148\u6267\u884cA\u7136\u540e\u6267\u884cB, \u5e76\u4e14\u90fd\u80fd\u6355\u83b7\u5f02\u5e38.
  • \u540c\u65f6scopeNet\u53d1\u751f\u9519\u8bef\u4e5f\u4f1a\u5bfc\u81f4launch\u5185\u7684\u8bf7\u6c42\u88ab\u53d6\u6d88, launch\u53d1\u751f\u9519\u8bef\u4e5f\u4f1a\u5bfc\u81f4scopeNet\u53d1\u751f\u9519\u8bef
"},{"location":"sync-request.html","title":"\u540c\u6b65\u8bf7\u6c42","text":"

Net\u652f\u6301\u5728\u5f53\u524d\u7ebf\u7a0b\u6267\u884c\u963b\u585e\u7ebf\u7a0b\u7684\u540c\u6b65\u8bf7\u6c42

\u4ec0\u4e48\u662f\u540c\u6b65\u8bf7\u6c42

\u5373\u4e0a\u4e2a\u8bf7\u6c42\u7ed3\u675f\u624d\u4f1a\u53d1\u8d77\u4e0b\u4e2a\u8bf7\u6c42, \u5b9e\u9645\u4e0a\u534f\u7a0b\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u4f46\u662f\u4ed6\u4e0d\u4f1a\u963b\u585e\u7ebf\u7a0b

\u540c\u6b65\u8bf7\u6c42\u5e94\u7528\u573a\u666f\u4e00\u822c\u662f\u5728\u62e6\u622a\u5668(\u6267\u884c\u5728\u5b50\u7ebf\u7a0b)\u4e2d\u4f7f\u7528

\u56e0\u4e3aAndroid\u4e3b\u7ebf\u7a0b\u4e0d\u5141\u8bb8\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42, \u8fd9\u91cc\u521b\u5efa\u4e00\u4e2a\u5b50\u7ebf\u7a0b\u6765\u6f14\u793a

\u8fd4\u56de\u6570\u636e\u8fd4\u56deResult
thread {\nval result = Net.post(\"api\").execute<String>() // \u7f51\u7edc\u8bf7\u6c42\u4e0d\u5141\u8bb8\u5728\u4e3b\u7ebf\u7a0b\ntvFragment?.post {\ntvFragment?.text = result  // view\u8981\u6c42\u5728\u4e3b\u7ebf\u7a0b\u66f4\u65b0\n}\n}\n
thread {\nval result = Net.post(\"api\").toResult<String>().getOrDefault(\"\u8bf7\u6c42\u53d1\u751f\u9519\u8bef, \u6211\u662f\u9ed8\u8ba4\u503c\")\ntvFragment?.post {\ntvFragment?.text = result  // view\u8981\u6c42\u5728\u4e3b\u7ebf\u7a0b\u66f4\u65b0\n}\n}\n
  1. execute\u5728\u8bf7\u6c42\u9519\u8bef\u65f6\u4f1a\u76f4\u63a5\u629b\u51fa\u5f02\u5e38
  2. toResult\u4e0d\u4f1a\u629b\u51fa\u5f02\u5e38, \u53efgetOrThrow/exceptionOrNull\u7b49\u8fd4\u56de\u5f02\u5e38\u5bf9\u8c61
"},{"location":"tag.html","title":"\u6807\u7b7e/\u989d\u5916","text":"

Net\u652f\u6301\u4e24\u79cd\u65b9\u5f0f\u643a\u5e26\u6570\u636e, \u8d2f\u7a7f\u6574\u4e2a\u8bf7\u6c42\u6d41\u7a0b(\u8bf7\u6c42/\u62e6\u622a\u5668/\u8f6c\u6362\u5668)

  • tag: HashMap<Class<*>, Any?> \u6807\u7b7e
  • extra: HashMap<String, Any?> \u989d\u5916\u6570\u636e

\u4e24\u8005\u533a\u522b\u4e3a\u5b58\u50a8\u65f6key\u662fClass\u8fd8\u662fString, \u81ea\u7531\u9009\u62e9

"},{"location":"tag.html#_1","title":"\u6807\u7b7e\u4f7f\u7528","text":""},{"location":"tag.html#1","title":"1. \u5199\u5165\u6807\u7b7e","text":"
scopeNetLife {\ntvFragment.text = Get<String>(\"api\", \"\u6807\u7b7eA\"){ // \u4f7f\u7528Any::class.java\u4f5c\u4e3a\u952e\u540d\n// tag(\"\u6807\u7b7eA\") \u7b49\u6548\u4e0a\u4e00\u884c\u7684\u53c2\u6570 \"\u6807\u7b7eA\"\nsetExtra(\"tagName\", \"\u6807\u7b7eB\") // \u5199\u5165\u989d\u5916\u6570\u636e\n}.await()\n}\n
"},{"location":"tag.html#2","title":"2. \u62e6\u622a\u5668\u4e2d\u8bfb\u53d6\u6807\u7b7e","text":"
class MyInterceptor : Interceptor {\noverride fun intercept(chain: Chain): Response {\nval request = chain.request()\nrequest.tag()?.let {\n// \u8bfb\u53d6\u6807\u7b7e\n}\nrequest.extra(\"tagName\")?.let {\n// \u8bfb\u53d6\u989d\u5916\u6570\u636e\n}\nreturn chain.proceed(request)\n}\n}\n
"},{"location":"tag.html#3","title":"3. \u8f6c\u6362\u5668\u4e2d\u8bfb\u53d6\u6807\u7b7e","text":"
class MyConvert : NetConvert {\noverride fun <R> onConvert(succeed: Type, response: Response ): R? {\nresponse.request.tag()?.let{\n// \u8bfb\u53d6\u6807\u7b7e\n}\n}\n}\n

\u901a\u8fc7Request\u53ef\u4ee5\u8bfb\u5199\u6570\u636e

\u65b9\u6cd5 \u63cf\u8ff0 setExtra \u5199\u5165\u989d\u5916\u6570\u636e extra \u8bfb\u53d6\u989d\u5916\u6570\u636e extras \u5168\u90e8\u989d\u5916\u6570\u636e tag \u8bfb\u53d6/\u5199\u5165\u6807\u7b7e tagOf \u8bfb\u53d6/\u5199\u5165\u6807\u7b7e, \u4e3atag()\u7684\u6cdb\u578b\u66ff\u4ee3 tags \u5168\u90e8\u6807\u7b7e"},{"location":"tag.html#_2","title":"\u591a\u4e2a\u6807\u7b7e","text":"
scopeNetLife {\nGet<String>(\"api\"){\nsetExtra(\"person\", Person()) // \u4f7f\u7528Request.extra(\"person\")\u8bfb\u53d6\ntag(User()) // \u7b49\u540c\u4e8etag(Any::class.java, User()), \u4f7f\u7528Request.tag()\u8bfb\u53d6\ntag(User::class.java, User()) // \u4f7f\u7528Request.tag(User::class.java)\u8bfb\u53d6\n}.await()\n}\n

\u5f97\u5230\u6807\u7b7e

class MyInterceptor : Interceptor {\noverride fun intercept(chain: Chain): Response {\nval request = chain.request()\nrequest.extra(\"person\")?.let {\n// it\u65e2\u4e3aPerson\u5bf9\u8c61\n}\nrequest.tagOf<User>() // \u7ed3\u679c\u4e3aUser()\nrequest.tag() // \u7ed3\u679c\u4e3aUser()\nreturn chain.proceed(request)\n}\n}\n
"},{"location":"thread.html","title":"\u5207\u6362\u7ebf\u7a0b","text":"

\u6240\u6709scopeXX\u4f5c\u7528\u57df\u5185\u4e3a\u4e3b\u7ebf\u7a0b, \u53ef\u76f4\u63a5\u66f4\u65b0\u89c6\u56fe

\u8c03\u5ea6\u5668

\u534f\u7a0b\u4e2d\u7684\u8c03\u5ea6\u5668\u5b9e\u9645\u4e0a\u4e3a\u7ebf\u7a0b\u6c60, \u901a\u8fc7\u5207\u6362\u8c03\u5ea6\u5668\u53ef\u4ee5\u5207\u6362\u5230\u4e0d\u540c\u7ebf\u7a0b\u4e0a

"},{"location":"thread.html#_1","title":"\u5207\u6362\u8c03\u5ea6\u5668","text":"
scopeNetLife(dispatcher = Dispatchers.IO) {\nbinding.tvFragment.text = Get<String>(\"api\").await()\n}\n
"},{"location":"thread.html#_2","title":"\u4f5c\u7528\u57df\u5185\u90e8\u5207\u6362","text":"

\u6709\u65f6\u9700\u5f00\u542f\u65b0\u7684\u7ebf\u7a0b\u5904\u7406\u8017\u65f6\u4efb\u52a1

\u4e3b\u7ebf\u7a0b\u4f5c\u7528\u57df\u5185\u5207\u6362\u5b50\u7ebf\u7a0b\u5b50\u7ebf\u7a0b\u4f5c\u7528\u57df\u5185\u5207\u6362\u4e3b\u7ebf\u7a0b
scopeNetLife {\nbinding.tvFragment.text = withIO {\n// \u5047\u8bbe\u6b64\u5904\u662f\u4e00\u4e2aIO\u8bfb\u5199\u963b\u585e\u4efb\u52a1\nreturn \"\u8bfb\u51fa\u7ed3\u679c\"\n}\n}\n
scopeNetLife(dispatcher = Dispatchers.IO) {\nbinding.tvFragment.text = withMain {\n// \u5047\u8bbe\u6b64\u5904\u662f\u4e00\u4e2aIO\u8bfb\u5199\u963b\u585e\u4efb\u52a1\nreturn \"\u8bfb\u51fa\u7ed3\u679c\"\n}\n}\n
\u51fd\u6570 \u63cf\u8ff0 withMain \u5207\u6362\u5230\u4e3b\u7ebf\u7a0b withIO \u5207\u6362\u5230IO\u7ebf\u7a0b withDefault \u5207\u6362\u5230\u5b50\u7ebf\u7a0b withUnconfined \u5207\u6362\u5230\u65e0\u9650\u5236\u8c03\u5ea6\u5668, \u5176\u53d6\u51b3\u4e8e\u4e0a\u4e00\u4e2a\u6267\u884c\u7684\u7ebf\u7a0b\u5207\u6362 launch \u65e0\u8fd4\u56de\u503c\u7684\u6302\u8d77\u51fd\u6570, \u53ef\u6307\u5b9a\u7ebf\u7a0b async \u6709\u8fd4\u56de\u503c\u7684\u6302\u8d77\u51fd\u6570, \u901a\u8fc7await()\u8fd4\u56de\u503c, \u53ef\u6307\u5b9a\u7ebf\u7a0b runMain \u5207\u6362\u5230\u4e3b\u7ebf\u7a0b, \u8be5\u51fd\u6570\u4e0d\u5c5e\u4e8e\u534f\u7a0b\u53ef\u4ee5\u5728\u4efb\u4f55\u5730\u65b9\u8c03\u7528
  • withXX() \u534f\u7a0b\u963b\u585e\u6302\u8d77
  • launch()/async() \u975e\u963b\u585e\u6267\u884c, \u4e24\u8005\u533a\u522b\u662f\u6709\u65e0\u8fd4\u56de\u503c
"},{"location":"timing.html","title":"\u9650\u65f6/\u5b9a\u65f6\u8bf7\u6c42","text":"

\u4ee5\u4e0b\u4e3a\u63d0\u4f9b\u5b9e\u73b0\u5b9a\u65f6/\u9650\u65f6\u8bf7\u6c42\u601d\u8def, \u5e76\u4e0d\u9650\u5b9a\u53ea\u6709\u4ee5\u4e0b\u65b9\u5f0f

"},{"location":"timing.html#_1","title":"\u9650\u65f6\u8bf7\u6c42","text":"

\u5373\u8d85\u8fc7\u6307\u5b9a\u65f6\u95f4\u540e\u7acb\u5373\u53d6\u6d88\u8bf7\u6c42

scopeDialog {\n// \u5f53\u63a5\u53e3\u8bf7\u6c42\u5728100\u6beb\u79d2\u5185\u6ca1\u6709\u5b8c\u6210\u4f1a\u629b\u51fa\u5f02\u5e38TimeoutCancellationException\nwithTimeout(100) {\nGet<String>(Api.PATH).await()\n}\n}.catch {\nLog.e(\"\u65e5\u5fd7\", \"\u8bf7\u6c42\u9519\u8bef\", it) // catch\u65e0\u6cd5\u63a5\u6536\u5230CancellationException\u5f02\u5e38\n}.finally {\nLog.e(\"\u65e5\u5fd7\", \"\u8bf7\u6c42\u5b8c\u6210\", it) // TimeoutCancellationException\u5c5e\u4e8eCancellationException\u5b50\u7c7b\u6545\u53ea\u4f1a\u88abfinally\u63a5\u6536\u5230\nif (it is TimeoutCancellationException) {\ntoast(\"\u7531\u4e8e\u672a\u5728\u6307\u5b9a\u65f6\u95f4\u5b8c\u6210\u8bf7\u6c42\u5219\u53d6\u6d88\u8bf7\u6c42\")\n}\n}\n
"},{"location":"timing.html#_2","title":"\u5b9a\u65f6\u8bf7\u6c42","text":"

\u6307\u5b9a\u8bf7\u6c4210\u6b21

scopeNetLife {\n// \u6bcf\u4e24\u79d2\u8bf7\u6c42\u4e00\u6b21, \u603b\u5171\u6267\u884c10\u6b21\nrepeat(20) {\ndelay(1000)\nval data = Get<String>(Api.PATH).await()\nif(it = 10) {\nreturn@repeat\n}\n}\n}\n

\u65e0\u9650\u5faa\u73af\u8bf7\u6c42, \u53ef\u4ee5\u6839\u636e\u67d0\u4e2a\u6761\u4ef6break\u9000\u51fa

scopeNetLife {\nwhile (true) {\ndelay(1.toDuration(DurationUnit.SECONDS))\nval data = Get<CONFIG>(Api.PATH).await()\nif(data.type = 3) {\nbreak\n}\n}\n}\n
"},{"location":"track.html","title":"\u5f02\u5e38\u8ffd\u8e2a","text":"

Net\u4e2d\u7f51\u7edc\u8bf7\u6c42\u5f02\u5e38\u4f1aLogCat\u8f93\u51fa, \u9664\u975e\u5f00\u53d1\u8005\u4fee\u6539\u5168\u5c40\u9519\u8bef\u5904\u7406

\u6f14\u793a\u8bbf\u95ee\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u8bf7\u6c42\u8def\u5f84

scopeNetLife {\ntvFragment.text = Get<String>(\"https://error.com/Net/\").await()\n}\n

LogCat\u53ef\u4ee5\u770b\u5230\u5f02\u5e38\u5806\u6808\u4fe1\u606f, \u5305\u542b\u5177\u4f53Url\u548c\u4ee3\u7801\u4f4d\u7f6e

"},{"location":"track.html#_1","title":"\u5173\u95ed\u65e5\u5fd7","text":"

\u53ef\u4ee5\u5173\u95ed\u65e5\u5fd7\u6253\u5370

NetConfig.initialize(Api.HOST, this) {\nsetDebug(false) // \u5173\u95ed\u65e5\u5fd7, \u4e00\u822c\u4f7f\u7528 BuildConfig.DEBUG\n}\n
"},{"location":"updates.html","title":"\u66f4\u65b0\u65e5\u5fd7","text":""},{"location":"updates.html#361","title":"3.6.1","text":"
  • fix: #197 \u4fee\u590dscopeDialog\u7684\u53ef\u53d6\u6d88\u5bf9\u8bdd\u6846\u9ed8\u8ba4\u503c
"},{"location":"updates.html#360","title":"3.6.0","text":"
  • pref: Optimize code
  • feat: contentLength\u672a\u77e5\u7684\u4e0a\u4f20\u5bf9\u8c61finish\u4e5f\u6709\u6548
  • pref: RunningCalls\u904d\u5386\u4f18\u5316
  • pref: \u8003\u8651\u5230Uri.toRequestBody\u8bfb\u53d6\u4e0d\u5230\u6587\u4ef6\u6216\u957f\u5ea6
  • refactor: \u5220\u9664\u5e9f\u5f03\u51fd\u6570
  • refactor: \u4e0b\u8f7d\u4e34\u65f6\u6587\u4ef6\u540d\u540e\u7f00\u6539\u6210.downloading
  • refactor: \u5220\u9664param(RequestBody, Header)
  • refactor: LogRecordInterceptor.kt
  • refactor: \u5220\u9664\u6709\u95ee\u9898\u7684\u53d6\u6d88\u8bf7\u6c42\u51fd\u6570
  • refactor: peekBytes\u7684\u9ed8\u8ba4\u8bfb\u53d6\u5927\u5c0f\u7edf\u4e00\u4e3a1MB
  • fix: \u4fee\u590d\u83b7\u53d6\u8bf7\u6c42\u5bf9\u8c61\u83b7\u53d6ID/Group\u9519\u8bef
  • fix: \u5168\u5c40\u53d6\u6d88\u8bf7\u6c42\u65f6\u53d1\u751fConvertException\u9519\u8bef\u63d0\u793a
  • fix: #187 \u4e0a\u4f20\u8fdb\u5ea6\u76d1\u542cfinish\u5b57\u6bb5\u65e0\u6548
"},{"location":"updates.html#359","title":"3.5.9","text":"
  • fix: \u4fee\u590dJava\u57fa\u7840\u7c7b\u578b\u6cdb\u578b\u89e3\u6790
"},{"location":"updates.html#358","title":"3.5.8","text":"
  • fix: \u5220\u9664\u6743\u9650 ACCESS_NETWORK_STATE, \u89e3\u51b3\u4e2a\u522b\u673a\u578b\u91cd\u590d\u7533\u8bf7\u95ee\u9898
  • upgrade: BRV 1.4.0
"},{"location":"updates.html#357","title":"3.5.7","text":"
  • fix: #165 \u6cdb\u578b\u64e6\u9664
"},{"location":"updates.html#356","title":"3.5.6","text":"
  • feat: \u65b0\u589e BaseRequest.execute \u975e\u5185\u8054\u51fd\u6570\u91cd\u8f7d
  • feat: Net.kt\u652f\u6301Java\u9759\u6001\u8c03\u7528
  • refactor: LogRecordInterceptor @JvmOverloads
  • fix: Interval.onlyResumed \u7ed3\u675f\u8f6e\u8be2
  • pref: \u5220\u9664\u8f6c\u6362\u5668\u83b7\u53d6\u7684\u53cd\u5c04\u8c03\u7528
"},{"location":"updates.html#355","title":"3.5.5","text":"
  • fix: #157 \u65e5\u5fd7\u62e6\u622a\u5668\u5931\u6548
"},{"location":"updates.html#354","title":"3.5.4","text":"
  • refactor: peekString rename to peekBytes, remove logString
  • fix: \u53ef\u80fd\u5b58\u5728\u7684\u5185\u5b58\u6cc4\u6f0f
"},{"location":"updates.html#353","title":"3.5.3","text":"
  • feat: \u9ed8\u8ba4\u4f7f\u7528NetDialogFactory\u7684setCancelable\u914d\u7f6e
  • fix: #150 scopeDialog\u9884\u89c8\u6a21\u5f0f
"},{"location":"updates.html#352","title":"3.5.2","text":"
  • fix: #135 Content-MD5\u672a\u4f7f\u7528Base64\u89e3\u7801
  • feat: \u65b0\u589e BaseRequest.headers
"},{"location":"updates.html#351","title":"3.5.1","text":"
  • feat: \u65b0\u589eparam\u65b9\u6cd5\u53c2\u6570Uri
  • feat: \u65b0\u589eaddQuery\u65b9\u6cd5
  • pref: \u4e0d\u6df7\u6dc6exception\u5305
  • fix: #129 \u8bf7\u6c42URL\u4e0d\u540c\u5bfc\u81f4setCacheKey\u65e0\u6548
"},{"location":"updates.html#350","title":"3.5.0","text":"
  • refactor: \u5220\u9664\u6743\u9650REQUEST_INSTALL_PACKAGES(\u8c37\u6b4c\u5546\u5e97\u6743\u9650\u8981\u6c42)
  • refactor: \u5220\u9664File.install
  • pref: \u6539\u4e3a\u4f7f\u7528AppStartup\u9ed8\u8ba4\u521d\u59cb\u5316
"},{"location":"updates.html#3414","title":"3.4.14","text":"
  • fix: Fragment\u672a\u521d\u59cb\u5316View\u6267\u884cscopeNetLife\u5bfc\u81f4\u7a7a\u6307\u9488
"},{"location":"updates.html#3413","title":"3.4.13","text":"
  • fix: #110 \u7f13\u5b58\u6a21\u5f0f\u4e0bRequest\u4fe1\u606f\u4e22\u5931
"},{"location":"updates.html#3412","title":"3.4.12","text":"
  • fix: FlowUtils.kt #102
"},{"location":"updates.html#3411","title":"3.4.11","text":"
  • fix: \u7f3a\u5931trace\u8bf7\u6c42\u65b9\u5f0f #99
"},{"location":"updates.html#3410","title":"3.4.10","text":"
  • fix: #91 \u4fee\u590dViewPager2\u7684\u89c6\u56fe\u751f\u547d\u5468\u671f\u5bfc\u81f4\u7f51\u7edc\u8bf7\u6c42\u88ab\u53d6\u6d88
  • fix: LogCat\u9519\u8bef\u53d1\u751f\u4f4d\u7f6e\u9ad8\u4eae
  • feat: brv 1.3.76
  • pref: DialogCoroutineScope
"},{"location":"updates.html#348","title":"3.4.8","text":"
  • fix: \u4e0d\u63d0\u4ea4null\u8bf7\u6c42\u53c2\u6570
"},{"location":"updates.html#347","title":"3.4.7","text":"
  • \u5347\u7ea7\u4f9d\u8d56
  • \u652f\u6301\u534f\u7a0b1.6.0
  • optimize Interval
  • EditText.debounce\u4e8b\u4ef6\u7c7b\u578b\u6539\u4e3aEditable
"},{"location":"updates.html#346","title":"3.4.6","text":"
  • \u65b0\u589e\u5f3a\u5236\u7f13\u5b58\u6709\u6548\u671f
"},{"location":"updates.html#345","title":"3.4.5","text":"
  • Fixed #88
  • Interval.life(Fragment)\u6539\u4e3aonDestroyView\u65f6\u9500\u6bc1
"},{"location":"updates.html#344","title":"3.4.4","text":"
  • \u65b0\u589eCookie\u7ba1\u7406
"},{"location":"updates.html#343","title":"3.4.3","text":"
  • \u4fee\u590dgzip\u5bfc\u81f4\u7684\u5f3a\u5236\u7f13\u5b58\u8bfb\u53d6\u5931\u8d25
  • \u4fee\u590dNoCacheException\u65e0\u6cd5\u6355\u83b7
  • \u54cd\u5e94\u53ef\u4ee5\u5224\u65ad\u662f\u5426\u6765\u81ea\u4e8e\u7f13\u5b58
  • \u4f18\u5316\u7f13\u5b58\u76f8\u5173\u4ee3\u7801
"},{"location":"updates.html#342","title":"3.4.2","text":"
  • \u4fee\u590dHttp\u7f13\u5b58\u534f\u8bae\u65e0\u6548
  • \u65e5\u5fd7\u62e6\u622a\u5668\u9519\u8bef\u4fe1\u606f\u7b80\u7565
"},{"location":"updates.html#341","title":"3.4.1","text":"
  • \u7981\u7528\u5931\u8d25\u7f13\u5b58
"},{"location":"updates.html#340","title":"3.4.0","text":"
  • \u65b0\u589e\u5f3a\u5236\u7f13\u5b58\u6a21\u5f0f
  • \u65b0\u589e\u9884\u89c8\u6a21\u5f0f(\u53ef\u5b9e\u73b0\u7f13\u5b58+\u7f51\u7edc)
"},{"location":"updates.html#331","title":"3.3.1","text":"
  • \u5e9f\u5f03\u90e8\u5206\u65e5\u5fd7\u76f8\u5173\u51fd\u6570
  • \u65b0\u589eNet.debug\u65e5\u5fd7\u8f93\u51fa\u51fd\u6570
  • \u4fee\u590dQuery\u7f16\u7801\u95ee\u9898
"},{"location":"updates.html#330","title":"3.3.0","text":"
  • \u5220\u9664Callback/onResult(\u7834\u574f\u6027\u8fc1\u79fb)
  • \u5220\u9664requestById/requestByGroup(\u7834\u574f\u6027\u8fc1\u79fb)
  • Add View.scopeNetLife
  • \u7f51\u7edc\u8bf7\u6c42\u5f02\u5e38\u4f4d\u7f6e\u8ffd\u8e2a
"},{"location":"updates.html#322","title":"3.2.2","text":"
  • Fixed #77
  • \u4fee\u590dgzip\u542f\u7528\u60c5\u51b5\u4e0b\u8f7d\u8fdb\u5ea6\u59cb\u7ec8\u4e3a0
  • Progress.finish()\u65b9\u6cd5\u6539\u4e3a\u5c5e\u6027
"},{"location":"updates.html#321","title":"3.2.1","text":"
  • Fixed #76
  • RequestBody?.peekString()\u51fd\u6570\u63a5\u53d7\u8005\u6539\u4e3a\u975e\u53ef\u7a7a\u7c7b\u578b
"},{"location":"updates.html#320","title":"3.2.0","text":"
  • \u66f4\u6539tag\u76f8\u5173\u51fd\u6570
  • \u66f4\u6539NetConfig.app\u7c7b\u578b\u6539\u4e3aContext
  • \u5220\u9664\u654f\u611f\u6743\u9650(\u5916\u90e8\u5b58\u50a8\u8bfb\u5199)
  • \u5220\u9664\u5e9f\u5f03\u51fd\u6570/\u63d0\u9ad8\u51fd\u6570\u5e9f\u5f03\u7b49\u7ea7
  • \u5e9f\u5f03NetConfig.init
  • \u5220\u9664fastest\u51fd\u6570\u63a5\u53d7\u8005
  • \u5220\u9664logRecord\u5c5e\u6027
  • \u4f18\u5316\u57df\u540d\u89e3\u6790\u9519\u8bef\u5f02\u5e38\u4fe1\u606f
  • \u65b0\u589e\u65e0\u7f51\u7edc\u4e0d\u53ef\u7528\u5f02\u5e38NetworkingException
  • \u65b0\u589e\u8f93\u51faMultiPart\u53c2\u6570\u65e5\u5fd7
  • \u66f4\u6539RetryInterceptor/LogRecordInterceptor\u5c5e\u6027\u8bbf\u95ee\u6743\u9650
"},{"location":"updates.html#312","title":"3.1.2","text":"
  • \u5347\u7ea7BRV\u81f31.3.51, \u5176\u5185\u90e8\u5347\u7ea7SmartRefreshLayout\u81f32.0.5. SmartRefreshLayout\u76f8\u5173\u4f9d\u8d56\u9700\u8981\u8fc1\u79fb
  • Interval\u6dfb\u52a0onlyResumed\u51fd\u6570
  • Interval\u4fee\u6539life\u51fd\u6570\u53c2\u6570\u4e3aFragmentActivity\u60c5\u51b5\u4e0b\u7684\u81ea\u52a8\u53d6\u6d88\u8f6e\u8be2\u5668\u7684\u751f\u547d\u5468\u671f
"},{"location":"updates.html#311","title":"3.1.1","text":"

\u5185\u5d4c\u6df7\u6dc6\u89c4\u5219, \u4e0d\u9700\u8981\u624b\u52a8\u6dfb\u52a0

"},{"location":"updates.html#310","title":"3.1.0","text":"
  • \u4fee\u590d\u90e8\u5206\u5b50\u7ebf\u7a0b\u5f00\u542f\u4f5c\u7528\u57df\u5d29\u6e83
  • \u7f51\u7edc\u5f02\u5e38\u5806\u6808\u4f7f\u7528 NetConfig.TAG \u4f5c\u4e3a\u6807\u7b7e, \u4f7f\u7528debug\u65e5\u5fd7\u7c7b\u578b\u8f93\u51fa
  • \u9ed8\u8ba4\u8f6c\u6362\u5668\u73b0\u5728\u8981\u6c42HTTP\u72b6\u6001\u7801\u4e3a\u6210\u529f\u624d\u8fd4\u56de\u6570\u636e(\u6cdb\u578bResponse\u8bf7\u6c42\u5b8c\u6210\u90fd\u8fd4\u56de)
  • \u5f00\u542f\u7f16\u8bd1\u5668\u5f3a\u5236\u66ff\u6362\u5e9f\u5f03\u51fd\u6570(\u53ef\u67e5\u770b\u51fd\u6570\u6ce8\u91ca\u66ff\u6362\u89c4\u5219)
  • \u7981\u6b62\u66b4\u9732\u5197\u4f59\u51fd\u6570
"},{"location":"updates.html#3027","title":"3.0.27","text":"
  • setDownloadDir\u51fd\u6570\u540c\u65f6\u652f\u6301\u5b8c\u6574\u8def\u5f84(\u5373\u5305\u542b\u6587\u4ef6\u540d\u79f0)\u548c\u4e0b\u8f7d\u76ee\u5f55
"},{"location":"updates.html#3026","title":"3.0.26","text":"
  • \u4f18\u5316\u8fd4\u56deByteArray\u7c7b\u578b\u6027\u80fd
  • setQuery\u51fd\u6570\u652f\u6301Number/Boolean\u7c7b\u578b
  • \u65b0\u589e\u4e00\u4e2a\u9519\u8bef\u63d0\u793a HttpFailureException
"},{"location":"updates.html#3025","title":"3.0.25","text":"
  • \u8f6e\u8be2\u5668\u652f\u6301ViewModel\u53d6\u6d88
  • \u4fee\u590d\u65e0\u6cd5\u8fd4\u56deByteArray\u7c7b\u578b\u95ee\u9898
  • \u95f4\u63a5\u4f9d\u8d56 update brv 1.3.37
  • \u66f4\u65b0\u51fd\u6570\u6ce8\u91ca
"},{"location":"updates.html#3024","title":"3.0.24","text":"

\u4fee\u590d\u4e0a\u4f20\u6587\u4ef6\u5305\u542b\u53c2\u6570\u65f6, \u7f16\u7801\u95ee\u9898\u5bfc\u81f4\u7684\u53c2\u6570\u9519\u8bef

"},{"location":"updates.html#3023","title":"3.0.23","text":"
  • \u4fee\u590d\u8f6e\u8be2\u5668\u91cd\u590dstart\u65e0\u6548\u95ee\u9898
  • Interval\u5176\u4ed6\u4f18\u5316
"},{"location":"updates.html#3021","title":"3.0.21","text":"
  • Interval\u6dfb\u52a0cancel\u51fd\u6570\u7528\u4e8e\u53d6\u6d88\u8ba1\u65f6\u5668, \u53d6\u6d88\u5b8c\u6210\u4e0d\u4f1a\u8c03\u7528finish
"},{"location":"updates.html#3020","title":"3.0.20","text":"
  • \u65b0\u589eHttpFailureException\u53ca\u5176\u5b50\u7c7b\u8868\u793a\u8bf7\u6c42\u5931\u8d25\u5f02\u5e38
  • \u65b0\u589eHttpResponseException\u53ca\u5176\u5b50\u7c7b\u8868\u793a\u8bf7\u6c42\u6210\u529f\u540e\u53d1\u751f\u7684\u5f02\u5e38
  • \u66f4\u65b0\u4f9d\u8d56\u5e93BRV\u81f31.3.31
"},{"location":"updates.html#3019","title":"3.0.19","text":"
  • \u66f4\u65b0\u4f9d\u8d56\u5e93BRV\u81f31.3.30
"},{"location":"updates.html#3018","title":"3.0.18","text":"
  • \u4fee\u590dResponse\u6d41\u5f02\u5e38\u5173\u95ed\u95ee\u9898
"},{"location":"updates.html#3017","title":"3.0.17","text":"
  • \u4fee\u590dProfiler\u5bfc\u81f4\u7684\u8bf7\u6c42\u95ee\u9898
"},{"location":"updates.html#3016","title":"3.0.16","text":"
  • \u65e5\u5fd7\u8bb0\u5f55\u5668\u4e2d\u8bf7\u6c42\u53c2\u6570\u9ed8\u8ba4\u4f7f\u7528URLDecoder\u89e3\u7801
"},{"location":"updates.html#3015","title":"3.0.15","text":"
  • \u4fee\u590dFileProvider\u51b2\u7a81
  • \u4e0a\u4f20\u6587\u4ef6\u65f6\u9ed8\u8ba4\u751f\u6210filename(\u5f53\u4f60\u672a\u6307\u5b9a\u6587\u4ef6\u540d\u60c5\u51b5\u4e0b)
  • NetCallback\u7f51\u7edc\u8bf7\u6c42\u88ab\u53d6\u6d88\u4e0d\u4f1a\u56de\u8c03onError
  • \u4e3aNetCallback\u6dfb\u52a0Request\u5bf9\u8c61
  • \u5220\u9664\u5185\u90e8Tooltip\u4f9d\u8d56
"},{"location":"updates.html#3014","title":"3.0.14","text":"
  • \u4fee\u590dKType\u7c7b\u578b\u95ee\u9898
  • \u652f\u6301File.install\u51fd\u6570\u5b89\u88c5\u5e94\u7528
"},{"location":"updates.html#3013","title":"3.0.13","text":"
  • \u4f18\u5316\u6807\u7b7e\u76f8\u5173\u51fd\u6570. \u6574\u4e2a\u7f51\u7edc\u751f\u547d\u5468\u671f\u53ef\u4ee5\u5b8c\u7f8e\u4f20\u9012\u53c2\u6570
  • NetCallback\u5177\u5907\u8ddf\u968f\u751f\u547d\u5468\u671f\u81ea\u52a8\u53d6\u6d88\u7f51\u7edc\u8bf7\u6c42
  • \u6269\u5c55NetCallback\u6765\u6dfb\u52a0DialogCallback/StateCallback/PageCallback
  • \u5e9f\u5f03\u90e8\u5206\u51fd\u6570, \u4f8b\u5982onDialog\u88ab\u5e9f\u5f03, \u73b0\u5728\u7531NetConfig.dialogFactory\u6784\u5efa\u5168\u5c40\u52a0\u8f7d\u5bf9\u8bdd\u6846
  • initNet\u73b0\u5728\u5e9f\u5f03, \u7531NetConfig.initialize\u53d6\u4ee3. \u6240\u6709\u914d\u7f6e\u4fe1\u606f\u7531NetConfig\u627f\u8f7d
  • RequestParamsException\u6dfb\u52a0\u9519\u8bef\u7801\u4fe1\u606f
"},{"location":"updates.html#3012","title":"3.0.12","text":"
  • \u4fee\u590d\u8f6c\u6362\u5668\u629b\u51fa\u7684\u5f02\u5e38\u5168\u90e8\u88abConvertException\u5305\u88f9\u7684\u95ee\u9898
  • NetException\u5b50\u7c7b\u4e0d\u4f1a\u88abConvertException\u5305\u88f9, \u6240\u4ee5\u8981\u6355\u83b7\u8f6c\u6362\u5668\u4e2d\u7684\u81ea\u5b9a\u4e49\u5f02\u5e38\u8bf7\u5176\u7ee7\u627fNetException
"},{"location":"updates.html#3011","title":"3.0.11","text":"
  • \u4fee\u590d\u4e34\u65f6\u4e0b\u8f7d\u6587\u4ef6\u9519\u8bef\u95ee\u9898
  • \u4fee\u590dViewModel\u4f5c\u7528\u57df\u590d\u7528\u95ee\u9898
"},{"location":"updates.html#3010","title":"3.0.10","text":"
  • \u5347\u7ea7Tooltip\u4f9d\u8d56, \u89e3\u51b3\u4f7f\u7528Tooltip_V1.1.1\u4f9d\u8d56\u65f6Net\u5b58\u5728\u5d29\u6e83\u95ee\u9898
"},{"location":"updates.html#309","title":"3.0.9","text":"
  • \u4f18\u5316\u8f6c\u6362\u5668\u5f02\u5e38\u5904\u7406
  • \u8f6c\u6362\u5668\u652f\u6301\u975e\u56fa\u5b9a\u683c\u5f0fJson\u89e3\u6790
"},{"location":"updates.html#307","title":"3.0.7","text":"
  • \u4fee\u590d\u672a\u77e5\u7684TypeToken\u8bbf\u95ee\u6743\u9650\u95ee\u9898
"},{"location":"updates.html#306","title":"3.0.6","text":"
  • \u6240\u6709Json\u89e3\u6790\u6846\u67b6\u90fd\u53ef\u4ee5\u89e3\u6790List<UserModel>\u7b49\u5d4c\u5957\u6cdb\u578b\u6570\u636e\u7ed3\u6784
"},{"location":"updates.html#305","title":"3.0.5","text":"
  • \u4fee\u590dPath\u7f16\u7801\u95ee\u9898
  • \u4e0a\u4f20File\u81ea\u52a8\u8bc6\u522bMediaType
"},{"location":"updates.html#304","title":"3.0.4","text":"
  • \u6dfb\u52a0MediaConst\u8868\u793a\u5e38\u7528MediaType
  • OkHttpBuilder\u6dfb\u52a0setErrorHandler\u53d6\u4ee3onError/onStateError: \u5168\u5c40\u9519\u8bef\u5904\u7406
  • \u63d0\u4f9b\u517c\u5bb9Android4.4(API level 19)\u7684\u7248\u672c: Net-okhttp3
"},{"location":"updates.html#303","title":"3.0.3","text":"
  • \u6dfb\u52a0onResult\u51fd\u6570\u6765\u6267\u884c\u961f\u5217\u8bf7\u6c42: \u961f\u5217\u8bf7\u6c42
  • \u6dfb\u52a0toResult\u51fd\u6570\u6765\u6267\u884c\u540c\u6b65\u8bf7\u6c42: \u540c\u6b65\u8bf7\u6c42
  • \u8bf7\u6c42\u4f53\u65e5\u5fd7\u652f\u6301JSON/\u6587\u672c\u7c7b\u578b
  • LogRecordInterceptor\u66b4\u9732requestString/responseString\u5b9e\u73b0\u51fd\u6570\u7528\u4e8e\u7ee7\u627f\u5b9e\u73b0\u81ea\u5b9a\u4e49\u9700\u6c42
"},{"location":"updates.html#302","title":"3.0.2","text":"

\u4fee\u590d\u591a\u6e20\u9053\u65e0\u6cd5\u5b89\u88c5\u95ee\u9898

"},{"location":"updates.html#301","title":"3.0.1","text":"
  • \u8f6c\u6362\u5668\u652f\u6301KType, \u89e3\u51b3JAVA\u6cdb\u578b\u64e6\u9664\u95ee\u9898
  • \u652f\u6301kotlin-serialization\u8f6c\u6362\u5668
  • \u4fee\u590dJSON\u8bf7\u6c42\u53c2\u6570\u7c7b\u578b\u95ee\u9898
"},{"location":"updates.html#30","title":"3.0","text":"
  • \u91cd\u6784\u4ee3\u7801, \u63d0\u5347\u7a33\u5b9a\u6027\u548c\u5b89\u5168\u6027.
  • \u652f\u6301OkHttp\u7684\u6240\u6709\u51fd\u6570/\u7ec4\u4ef6, \u53ef\u72ec\u7acb\u5347\u7ea7OkHttp\u7248\u672c
  • \u66f4\u52a0\u5f3a\u5927\u7684\u4e0b\u8f7d\u529f\u80fd
  • \u6240\u6709IO\u8bfb\u5199\u4f7f\u7528OKIO
  • \u66f4\u52a0\u4f18\u96c5\u7684\u51fd\u6570\u8bbe\u8ba1
"},{"location":"upload-file.html","title":"\u4e0a\u4f20\u6587\u4ef6","text":"
scopeNetLife {\nPost<String>(Api.UPLOAD) {\nparam(\"fileName\", assetsFile())\n}.await()\n}\n

\u4f7f\u7528addUploadListener\u6dfb\u52a0\u4e0a\u4f20\u8fdb\u5ea6\u76d1\u542c\u5668, \u9605\u8bfb\u8fdb\u5ea6\u76d1\u542c\u7ae0\u8282

"},{"location":"upload-file.html#_1","title":"\u6307\u5b9a\u7c7b\u578b","text":"

\u9ed8\u8ba4\u6839\u636e\u6587\u4ef6\u540e\u7f00\u540d\u751f\u6210MediaType, \u5982\u679c\u60f3\u81ea\u5b9a\u4e49MediaType\u53ef\u4ee5\u76f4\u63a5\u521b\u5efaRequestBody

scopeNetLife {\nPost<String>(Api.UPLOAD) {\nparam(\"file\", assetsFile().toRequestBody(\"image/webp\".toMediaType()))\n}.await()\n}\n
"},{"location":"upload-file.html#_2","title":"\u4e0a\u4f20\u7c7b\u578b","text":"

\u81ea\u5b9a\u4e49RequestBody\u53ef\u4ee5\u5b9e\u73b0\u4efb\u4f55\u6570\u636e\u7c7b\u578b\u7684\u4e0a\u4f20, \u4f46\u662fNet\u63d0\u4f9b\u5e38\u7528\u51fd\u6570\u7b80\u5316Uri/File\u4e0a\u4f20

scopeNetLife {\nPost<String>(Api.UPLOAD) {\n// MultiPart \u4e0a\u4f20\nparam(\"file\", Uri)\nparam(\"file\", File)\n// \u81ea\u5b9a\u4e49\u8bf7\u6c42\u4f53, \u4f1a\u8986\u76d6\u4ee5\u4e0a\u6240\u6709\u8bf7\u6c42\u5185\u5bb9\nbody = CustomizerRequestBody()\n}.await()\n}\n

\u76f4\u63a5\u4e0a\u4f20InputStream\u8f93\u5165\u6d41\u5c5e\u4e8e\u4e0d\u5b89\u5168\u884c\u4e3a, \u5efa\u8bae\u4f60\u4fdd\u5b58\u5230\u6587\u4ef6\u540e\u4e0a\u4f20, \u8be6\u7ec6\u8bf7\u9605\u8bfb: \u4f7f\u7528\u6587\u4ef6\u6d41\u4e0a\u4f20\u6587\u4ef6

"},{"location":"view-model.html","title":"ViewModel","text":"

Net\u652f\u6301\u5728ViewModel\u4e2d\u521b\u5efa\u7f51\u7edc\u8bf7\u6c42/\u5f02\u6b65\u4efb\u52a1

\u4e0d\u63a8\u8350

  1. \u7f51\u7edc\u8bf7\u6c42\u4e0d\u4e00\u5b9a\u8981\u5199\u5728ViewModel
  2. \u7f51\u7edc\u8bf7\u6c42\u4e0d\u8981\u5199\u63a5\u53e3\u56de\u8c03
  3. \u53ef\u4ee5\u5728Activity\u4e2d\u76f4\u63a5\u8fd4\u56de\u8bf7\u6c42\u7ed3\u679c
"},{"location":"view-model.html#_1","title":"\u81ea\u52a8\u751f\u547d\u5468\u671f","text":"
  • \u793a\u4f8b\u4ee3\u7801

\u4f7f\u7528scopeXXLife()\u521b\u5efa\u4f5c\u7528\u57df, \u5728ViewModel\u88ab\u9500\u6bc1\u65f6\u81ea\u52a8\u53d6\u6d88\u8bf7\u6c42

class UserViewModel : ViewModel() {\n// \u7528\u6237\u4fe1\u606f\nprivate var userInfo: MutableLiveData<String> = MutableLiveData()\n/**\n     * \u4f7f\u7528LiveData\u63a5\u53d7\u8bf7\u6c42\u7ed3\u679c, \u5c06\u8be5liveData\u76f4\u63a5\u4f7f\u7528DataBinding\u7ed1\u5b9a\u5230\u9875\u9762\u4e0a, \u4f1a\u5728\u8bf7\u6c42\u6210\u529f\u81ea\u52a8\u66f4\u65b0\u89c6\u56fe\n     */\nfun fetchUserInfo() = scopeNetLife {\nuserInfo.value = Get<String>(Api.GAME).await()\n}\n/**\n     * \u5f00\u59cb\u975e\u963b\u585e\u5f02\u6b65\u4efb\u52a1\n     *  \u8fd4\u56deDeferred, \u8c03\u7528await()\u624d\u4f1a\u8fd4\u56de\u7ed3\u679c\n     */\nfun fetchList(scope: CoroutineScope) = scope.Get<String>(Api.TEST)\n/**\n     * \u5f00\u59cb\u963b\u585e\u5f02\u6b65\u4efb\u52a1\n     * \u76f4\u63a5\u8fd4\u56de\u7ed3\u679c\n     */\nsuspend fun fetchPrecessData() = coroutineScope {\nval response = Get<String>(Api.TEST).await()\nresponse + \"\u5904\u7406\u6570\u636e\"\n}\n}\n
"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..0f8724efd --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..e44561ac8bb5513250633c274ae17e56752763ce GIT binary patch literal 127 zcmV-_0D%7=iwFof%-m!G|8r?{Wo=<_E_iKh04<9_3V)_WXo8&M?ytk3HC}0~zlG)Vu + + + + + + + + + + + + + + + + + + + + + + + + 同步请求 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

同步请求

+ +

Net支持在当前线程执行阻塞线程的同步请求

+
+

什么是同步请求

+

即上个请求结束才会发起下个请求, 实际上协程也可以实现但是他不会阻塞线程

+

同步请求应用场景一般是在拦截器(执行在子线程)中使用

+
+

因为Android主线程不允许发起网络请求, 这里创建一个子线程来演示

+
+
+
+
thread {
+    val result = Net.post("api").execute<String>() // 网络请求不允许在主线程
+    tvFragment?.post {
+        tvFragment?.text = result  // view要求在主线程更新
+    }
+}
+
+
+
+
thread {
+    val result = Net.post("api").toResult<String>().getOrDefault("请求发生错误, 我是默认值")
+    tvFragment?.post {
+        tvFragment?.text = result  // view要求在主线程更新
+    }
+}
+
+
+
+
+
    +
  1. execute在请求错误时会直接抛出异常
  2. +
  3. toResult不会抛出异常, 可getOrThrow/exceptionOrNull等返回异常对象
  4. +
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/tag.html b/tag.html new file mode 100644 index 000000000..1cfe8a522 --- /dev/null +++ b/tag.html @@ -0,0 +1,1379 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 标签/额外 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

标签/额外

+ +

Net支持两种方式携带数据, 贯穿整个请求流程(请求/拦截器/转换器)

+
    +
  • tag: HashMap<Class<*>, Any?> 标签
  • +
  • extra: HashMap<String, Any?> 额外数据
  • +
+

两者区别为存储时key是Class还是String, 自由选择

+

标签使用

+

1. 写入标签

+
scopeNetLife {
+    tvFragment.text = Get<String>("api", "标签A"){ // 使用Any::class.java作为键名
+        // tag("标签A") 等效上一行的参数 "标签A"
+        setExtra("tagName", "标签B") // 写入额外数据
+    }.await()
+}
+
+

2. 拦截器中读取标签

+
class MyInterceptor : Interceptor {
+    override fun intercept(chain: Chain): Response {
+        val request = chain.request()
+        request.tag()?.let {
+            // 读取标签
+        }
+        request.extra("tagName")?.let {
+           // 读取额外数据
+        }
+        return chain.proceed(request)
+    }
+}
+
+

3. 转换器中读取标签

+
class MyConvert : NetConvert {
+
+    override fun <R> onConvert(succeed: Type, response: Response ): R? {
+        response.request.tag()?.let{
+            // 读取标签
+        }
+    }
+}
+
+


+

通过Request可以读写数据

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
方法描述
setExtra写入额外数据
extra读取额外数据
extras全部额外数据
tag读取/写入标签
tagOf读取/写入标签, 为tag()的泛型替代
tags全部标签
+

多个标签

+
scopeNetLife {
+    Get<String>("api"){
+        setExtra("person", Person()) // 使用Request.extra("person")读取
+        tag(User()) // 等同于tag(Any::class.java, User()), 使用Request.tag()读取
+        tag(User::class.java, User()) // 使用Request.tag(User::class.java)读取
+    }.await()
+}
+
+

得到标签

+
class MyInterceptor : Interceptor {
+    override fun intercept(chain: Chain): Response {
+        val request = chain.request()
+        request.extra("person")?.let {
+            // it既为Person对象
+        }
+        request.tagOf<User>() // 结果为User()
+        request.tag() // 结果为User()
+        return chain.proceed(request)
+    }
+}
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/thread.html b/thread.html new file mode 100644 index 000000000..04d7ffc1b --- /dev/null +++ b/thread.html @@ -0,0 +1,1304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 切换线程 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

切换线程

+ +

所有scopeXX作用域内为主线程, 可直接更新视图

+
+

调度器

+

协程中的调度器实际上为线程池, 通过切换调度器可以切换到不同线程上

+
+

切换调度器

+
scopeNetLife(dispatcher = Dispatchers.IO) {
+    binding.tvFragment.text = Get<String>("api").await()
+}
+
+

作用域内部切换

+

有时需开启新的线程处理耗时任务

+
+
+
+
scopeNetLife {
+    binding.tvFragment.text = withIO {
+        // 假设此处是一个IO读写阻塞任务
+        return "读出结果"
+    }
+}
+
+
+
+
scopeNetLife(dispatcher = Dispatchers.IO) {
+    binding.tvFragment.text = withMain {
+        // 假设此处是一个IO读写阻塞任务
+        return "读出结果"
+    }
+}
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
withMain切换到主线程
withIO切换到IO线程
withDefault切换到子线程
withUnconfined切换到无限制调度器, 其取决于上一个执行的线程切换
launch无返回值的挂起函数, 可指定线程
async有返回值的挂起函数, 通过await()返回值, 可指定线程
runMain切换到主线程, 该函数不属于协程可以在任何地方调用
+
    +
  • withXX() 协程阻塞挂起
  • +
  • launch()/async() 非阻塞执行, 两者区别是有无返回值
  • +
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/timing.html b/timing.html new file mode 100644 index 000000000..132c9f89a --- /dev/null +++ b/timing.html @@ -0,0 +1,1269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 限时/定时请求 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

限时/定时请求

+ +

以下为提供实现定时/限时请求思路, 并不限定只有以下方式

+

限时请求

+

即超过指定时间后立即取消请求

+
scopeDialog {
+    // 当接口请求在100毫秒内没有完成会抛出异常TimeoutCancellationException
+    withTimeout(100) {
+        Get<String>(Api.PATH).await()
+    }
+}.catch {
+    Log.e("日志", "请求错误", it) // catch无法接收到CancellationException异常
+}.finally {
+    Log.e("日志", "请求完成", it) // TimeoutCancellationException属于CancellationException子类故只会被finally接收到
+    if (it is TimeoutCancellationException) {
+        toast("由于未在指定时间完成请求则取消请求")
+    }
+}
+
+

定时请求

+

指定请求10次

+
scopeNetLife {
+    // 每两秒请求一次, 总共执行10次
+    repeat(20) {
+        delay(1000)
+        val data = Get<String>(Api.PATH).await()
+        if(it = 10) {
+            return@repeat
+        }
+    }
+}
+
+

无限循环请求, 可以根据某个条件break退出

+
scopeNetLife {
+    while (true) {
+        delay(1.toDuration(DurationUnit.SECONDS))
+        val data = Get<CONFIG>(Api.PATH).await()
+        if(data.type = 3) {
+            break
+        }
+    }
+}
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/track.html b/track.html new file mode 100644 index 000000000..9d4b5c3c8 --- /dev/null +++ b/track.html @@ -0,0 +1,1228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 异常追踪 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

异常追踪

+ +

Net中网络请求异常会LogCat输出, 除非开发者修改全局错误处理

+

演示访问一个不存在的请求路径 +

scopeNetLife {
+    tvFragment.text = Get<String>("https://error.com/Net/").await()
+}
+

+

LogCat可以看到异常堆栈信息, 包含具体Url和代码位置

+

+

关闭日志

+

可以关闭日志打印

+
NetConfig.initialize(Api.HOST, this) {
+    setDebug(false) // 关闭日志, 一般使用 BuildConfig.DEBUG
+}
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/updates.html b/updates.html new file mode 100644 index 000000000..1e4c22a81 --- /dev/null +++ b/updates.html @@ -0,0 +1,2368 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 更新日志 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

更新日志

+ +

3.6.1

+
    +
  • fix: #197 修复scopeDialog的可取消对话框默认值
  • +
+

3.6.0

+
    +
  • pref: Optimize code
  • +
  • feat: contentLength未知的上传对象finish也有效
  • +
  • pref: RunningCalls遍历优化
  • +
  • pref: 考虑到Uri.toRequestBody读取不到文件或长度
  • +
  • refactor: 删除废弃函数
  • +
  • refactor: 下载临时文件名后缀改成.downloading
  • +
  • refactor: 删除param(RequestBody, Header)
  • +
  • refactor: LogRecordInterceptor.kt
  • +
  • refactor: 删除有问题的取消请求函数
  • +
  • refactor: peekBytes的默认读取大小统一为1MB
  • +
  • fix: 修复获取请求对象获取ID/Group错误
  • +
  • fix: 全局取消请求时发生ConvertException错误提示
  • +
  • fix: #187 上传进度监听finish字段无效
  • +
+

3.5.9

+
    +
  • fix: 修复Java基础类型泛型解析
  • +
+

3.5.8

+
    +
  • fix: 删除权限 ACCESS_NETWORK_STATE, 解决个别机型重复申请问题
  • +
  • upgrade: BRV 1.4.0
  • +
+

3.5.7

+
    +
  • fix: #165 泛型擦除
  • +
+

3.5.6

+
    +
  • feat: 新增 BaseRequest.execute 非内联函数重载
  • +
  • feat: Net.kt支持Java静态调用
  • +
  • refactor: LogRecordInterceptor @JvmOverloads
  • +
  • fix: Interval.onlyResumed 结束轮询
  • +
  • pref: 删除转换器获取的反射调用
  • +
+

3.5.5

+
    +
  • fix: #157 日志拦截器失效
  • +
+

3.5.4

+
    +
  • refactor: peekString rename to peekBytes, remove logString
  • +
  • fix: 可能存在的内存泄漏
  • +
+

3.5.3

+
    +
  • feat: 默认使用NetDialogFactory的setCancelable配置
  • +
  • fix: #150 scopeDialog预览模式
  • +
+

3.5.2

+
    +
  • fix: #135 Content-MD5未使用Base64解码
  • +
  • feat: 新增 BaseRequest.headers
  • +
+

3.5.1

+
    +
  • feat: 新增param方法参数Uri
  • +
  • feat: 新增addQuery方法
  • +
  • pref: 不混淆exception包
  • +
  • fix: #129 请求URL不同导致setCacheKey无效
  • +
+

3.5.0

+
    +
  • refactor: 删除权限REQUEST_INSTALL_PACKAGES(谷歌商店权限要求)
  • +
  • refactor: 删除File.install
  • +
  • pref: 改为使用AppStartup默认初始化
  • +
+

3.4.14

+
    +
  • fix: Fragment未初始化View执行scopeNetLife导致空指针
  • +
+

3.4.13

+
    +
  • fix: #110 缓存模式下Request信息丢失
  • +
+

3.4.12

+
    +
  • fix: FlowUtils.kt #102
  • +
+

3.4.11

+
    +
  • fix: 缺失trace请求方式 #99
  • +
+

3.4.10

+
    +
  • fix: #91 修复ViewPager2的视图生命周期导致网络请求被取消
  • +
  • fix: LogCat错误发生位置高亮
  • +
  • feat: brv 1.3.76
  • +
  • pref: DialogCoroutineScope
  • +
+

3.4.8

+
    +
  • fix: 不提交null请求参数
  • +
+

3.4.7

+
    +
  • 升级依赖
  • +
  • 支持协程1.6.0
  • +
  • optimize Interval
  • +
  • EditText.debounce事件类型改为Editable
  • +
+

3.4.6

+
    +
  • 新增强制缓存有效期
  • +
+

3.4.5

+
    +
  • Fixed #88
  • +
  • Interval.life(Fragment)改为onDestroyView时销毁
  • +
+

3.4.4

+
    +
  • 新增Cookie管理
  • +
+

3.4.3

+
    +
  • 修复gzip导致的强制缓存读取失败
  • +
  • 修复NoCacheException无法捕获
  • +
  • 响应可以判断是否来自于缓存
  • +
  • 优化缓存相关代码
  • +
+

3.4.2

+
    +
  • 修复Http缓存协议无效
  • +
  • 日志拦截器错误信息简略
  • +
+

3.4.1

+
    +
  • 禁用失败缓存
  • +
+

3.4.0

+ +

3.3.1

+
    +
  • 废弃部分日志相关函数
  • +
  • 新增Net.debug日志输出函数
  • +
  • 修复Query编码问题
  • +
+

3.3.0

+
    +
  • 删除Callback/onResult(破坏性迁移)
  • +
  • 删除requestById/requestByGroup(破坏性迁移)
  • +
  • Add View.scopeNetLife
  • +
  • 网络请求异常位置追踪
  • +
+

3.2.2

+
    +
  • Fixed #77
  • +
  • 修复gzip启用情况下载进度始终为0
  • +
  • Progress.finish()方法改为属性
  • +
+

3.2.1

+
    +
  • Fixed #76
  • +
  • RequestBody?.peekString()函数接受者改为非可空类型
  • +
+

3.2.0

+
    +
  • 更改tag相关函数
  • +
  • 更改NetConfig.app类型改为Context
  • +
  • 删除敏感权限(外部存储读写)
  • +
  • 删除废弃函数/提高函数废弃等级
  • +
  • 废弃NetConfig.init
  • +
  • 删除fastest函数接受者
  • +
  • 删除logRecord属性
  • +
  • 优化域名解析错误异常信息
  • +
  • 新增无网络不可用异常NetworkingException
  • +
  • 新增输出MultiPart参数日志
  • +
  • 更改RetryInterceptor/LogRecordInterceptor属性访问权限
  • +
+

3.1.2

+
    +
  • 升级BRV至1.3.51, 其内部升级SmartRefreshLayout至2.0.5. SmartRefreshLayout相关依赖需要迁移
  • +
  • Interval添加onlyResumed函数
  • +
  • Interval修改life函数参数为FragmentActivity情况下的自动取消轮询器的生命周期
  • +
+

3.1.1

+

内嵌混淆规则, 不需要手动添加

+

3.1.0

+
    +
  • 修复部分子线程开启作用域崩溃
  • +
  • 网络异常堆栈使用 NetConfig.TAG 作为标签, 使用debug日志类型输出
  • +
  • 默认转换器现在要求HTTP状态码为成功才返回数据(泛型Response请求完成都返回)
  • +
  • 开启编译器强制替换废弃函数(可查看函数注释替换规则)
  • +
  • 禁止暴露冗余函数
  • +
+

3.0.27

+
    +
  • setDownloadDir函数同时支持完整路径(即包含文件名称)和下载目录
  • +
+

3.0.26

+
    +
  • 优化返回ByteArray类型性能
  • +
  • setQuery函数支持Number/Boolean类型
  • +
  • 新增一个错误提示 HttpFailureException
  • +
+

3.0.25

+
    +
  • 轮询器支持ViewModel取消
  • +
  • 修复无法返回ByteArray类型问题
  • +
  • 间接依赖 update brv 1.3.37
  • +
  • 更新函数注释
  • +
+

3.0.24

+

修复上传文件包含参数时, 编码问题导致的参数错误

+

3.0.23

+
    +
  • 修复轮询器重复start无效问题
  • +
  • Interval其他优化
  • +
+

3.0.21

+
    +
  • Interval添加cancel函数用于取消计时器, 取消完成不会调用finish
  • +
+

3.0.20

+
    +
  • 新增HttpFailureException及其子类表示请求失败异常
  • +
  • 新增HttpResponseException及其子类表示请求成功后发生的异常
  • +
  • 更新依赖库BRV至1.3.31
  • +
+

3.0.19

+
    +
  • 更新依赖库BRV至1.3.30
  • +
+

3.0.18

+
    +
  • 修复Response流异常关闭问题
  • +
+

3.0.17

+
    +
  • 修复Profiler导致的请求问题
  • +
+

3.0.16

+
    +
  • 日志记录器中请求参数默认使用URLDecoder解码
  • +
+

3.0.15

+
    +
  • 修复FileProvider冲突
  • +
  • 上传文件时默认生成filename(当你未指定文件名情况下)
  • +
  • NetCallback网络请求被取消不会回调onError
  • +
  • 为NetCallback添加Request对象
  • +
  • 删除内部Tooltip依赖
  • +
+

3.0.14

+
    +
  • 修复KType类型问题
  • +
  • 支持File.install函数安装应用
  • +
+

3.0.13

+
    +
  • 优化标签相关函数. 整个网络生命周期可以完美传递参数
  • +
  • NetCallback具备跟随生命周期自动取消网络请求
  • +
  • 扩展NetCallback来添加DialogCallback/StateCallback/PageCallback
  • +
  • 废弃部分函数, 例如onDialog被废弃, 现在由NetConfig.dialogFactory构建全局加载对话框
  • +
  • initNet现在废弃, 由NetConfig.initialize取代. 所有配置信息由NetConfig承载
  • +
  • RequestParamsException添加错误码信息
  • +
+

3.0.12

+
    +
  • 修复转换器抛出的异常全部被ConvertException包裹的问题
  • +
  • NetException子类不会被ConvertException包裹, 所以要捕获转换器中的自定义异常请其继承NetException
  • +
+

3.0.11

+
    +
  • 修复临时下载文件错误问题
  • +
  • 修复ViewModel作用域复用问题
  • +
+

3.0.10

+
    +
  • 升级Tooltip依赖, 解决使用Tooltip_V1.1.1依赖时Net存在崩溃问题
  • +
+

3.0.9

+
    +
  • 优化转换器异常处理
  • +
  • 转换器支持非固定格式Json解析
  • +
+

3.0.7

+
    +
  • 修复未知的TypeToken访问权限问题
  • +
+

3.0.6

+
    +
  • 所有Json解析框架都可以解析List<UserModel>等嵌套泛型数据结构
  • +
+

3.0.5

+
    +
  • 修复Path编码问题
  • +
  • 上传File自动识别MediaType
  • +
+

3.0.4

+
    +
  • 添加MediaConst表示常用MediaType
  • +
  • OkHttpBuilder添加setErrorHandler取代onError/onStateError: 全局错误处理
  • +
  • 提供兼容Android4.4(API level 19)的版本: Net-okhttp3
  • +
+

3.0.3

+
    +
  • 添加onResult函数来执行队列请求: 队列请求
  • +
  • 添加toResult函数来执行同步请求: 同步请求
  • +
  • 请求体日志支持JSON/文本类型
  • +
  • LogRecordInterceptor暴露requestString/responseString实现函数用于继承实现自定义需求
  • +
+

3.0.2

+

修复多渠道无法安装问题

+

3.0.1

+
    +
  • 转换器支持KType, 解决JAVA泛型擦除问题
  • +
  • 支持kotlin-serialization转换器
  • +
  • 修复JSON请求参数类型问题
  • +
+

3.0

+
    +
  • 重构代码, 提升稳定性和安全性.
  • +
  • 支持OkHttp的所有函数/组件, 可独立升级OkHttp版本
  • +
  • 更加强大的下载功能
  • +
  • 所有IO读写使用OKIO
  • +
  • 更加优雅的函数设计
  • +
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/upload-file.html b/upload-file.html new file mode 100644 index 000000000..8dd260c34 --- /dev/null +++ b/upload-file.html @@ -0,0 +1,1258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 上传文件 - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

上传文件

+ +
scopeNetLife {
+    Post<String>(Api.UPLOAD) {
+        param("fileName", assetsFile())
+    }.await()
+}
+
+

使用addUploadListener添加上传进度监听器, 阅读进度监听章节

+

指定类型

+

默认根据文件后缀名生成MediaType, 如果想自定义MediaType可以直接创建RequestBody

+
scopeNetLife {
+    Post<String>(Api.UPLOAD) {
+        param("file", assetsFile().toRequestBody("image/webp".toMediaType()))
+    }.await()
+}
+
+

上传类型

+

自定义RequestBody可以实现任何数据类型的上传, 但是Net提供常用函数简化Uri/File上传

+
scopeNetLife {
+    Post<String>(Api.UPLOAD) {
+        // MultiPart 上传
+        param("file", Uri)
+        param("file", File)
+
+        // 自定义请求体, 会覆盖以上所有请求内容
+        body = CustomizerRequestBody()
+    }.await()
+}
+
+

直接上传InputStream输入流属于不安全行为, 建议你保存到文件后上传, +详细请阅读: 使用文件流上传文件

+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/view-model.html b/view-model.html new file mode 100644 index 000000000..47e9bdcaf --- /dev/null +++ b/view-model.html @@ -0,0 +1,1256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ViewModel - Net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + 跳转至 + + +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + +

ViewModel

+ +

Net支持在ViewModel中创建网络请求/异步任务

+
+

不推荐

+
    +
  1. 网络请求不一定要写在ViewModel
  2. +
  3. 网络请求不要写接口回调
  4. +
  5. 可以在Activity中直接返回请求结果
  6. +
+
+

自动生命周期

+ +

使用scopeXXLife()创建作用域, 在ViewModel被销毁时自动取消请求

+
class UserViewModel : ViewModel() {
+
+    // 用户信息
+    private var userInfo: MutableLiveData<String> = MutableLiveData()
+
+    /**
+     * 使用LiveData接受请求结果, 将该liveData直接使用DataBinding绑定到页面上, 会在请求成功自动更新视图
+     */
+    fun fetchUserInfo() = scopeNetLife {
+        userInfo.value = Get<String>(Api.GAME).await()
+    }
+
+    /**
+     * 开始非阻塞异步任务
+     *  返回Deferred, 调用await()才会返回结果
+     */
+    fun fetchList(scope: CoroutineScope) = scope.Get<String>(Api.TEST)
+
+    /**
+     * 开始阻塞异步任务
+     * 直接返回结果
+     */
+    suspend fun fetchPrecessData() = coroutineScope {
+        val response = Get<String>(Api.TEST).await()
+        response + "处理数据"
+    }
+}
+
+ + + + + + +
+
+ + +
+ + + +
+ + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file