- }
- }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttp.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttp.kt
deleted file mode 100644
index 776f4207..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttp.kt
+++ /dev/null
@@ -1,542 +0,0 @@
-package rxhttp.wrapper.`param`
-
-import com.example.httpsender.RxHttpManager.fastJsonConverter
-import com.example.httpsender.RxHttpManager.simpleClient
-import com.example.httpsender.RxHttpManager.xmlConverter
-import com.example.httpsender.`param`.GetEncryptParam
-import com.example.httpsender.`param`.PostEncryptFormParam
-import com.example.httpsender.`param`.PostEncryptJsonParam
-import com.example.httpsender.`param`.PostEncryptJsonParam1
-import com.example.httpsender.entity.Url.baseUrl
-import java.lang.Class
-import java.util.concurrent.TimeUnit
-import kotlin.Any
-import kotlin.Boolean
-import kotlin.Long
-import kotlin.String
-import kotlin.Suppress
-import kotlin.collections.List
-import kotlin.collections.Map
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmOverloads
-import kotlin.jvm.JvmStatic
-import okhttp3.CacheControl
-import okhttp3.Call
-import okhttp3.Headers
-import okhttp3.Headers.Builder
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import rxhttp.RxHttpPlugins
-import rxhttp.wrapper.cache.CacheMode
-import rxhttp.wrapper.cache.CacheStrategy
-import rxhttp.wrapper.callback.IConverter
-import rxhttp.wrapper.callback.OutputStreamFactory
-import rxhttp.wrapper.entity.DownloadOffSize
-import rxhttp.wrapper.intercept.CacheInterceptor
-import rxhttp.wrapper.intercept.LogInterceptor
-import rxhttp.wrapper.intercept.RangeInterceptor
-import rxhttp.wrapper.utils.LogUtil
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- * https://github.com/liujingxing/rxhttp/wiki/FAQ
- * https://github.com/liujingxing/rxhttp/wiki/更新日志
- */
-public open class RxHttp, R : RxHttp
> protected constructor(
- public val `param`: P,
-) : BaseRxHttp() {
- private var connectTimeoutMillis: Long = 0L
-
- private var readTimeoutMillis: Long = 0L
-
- private var writeTimeoutMillis: Long = 0L
-
- private var converter: IConverter = RxHttpPlugins.getConverter()
-
- private var okClient: OkHttpClient = RxHttpPlugins.getOkHttpClient()
-
- public var request: Request? = null
-
- @get:JvmName("getUrl")
- public val url: String
- get() {
- addDefaultDomainIfAbsent()
- return param.url
- }
-
- @get:JvmName("getSimpleUrl")
- public val simpleUrl: String
- get() = param.simpleUrl
-
- @get:JvmName("getHeaders")
- public val headers: Headers
- get() = param.headers
-
- @get:JvmName("getHeadersBuilder")
- public val headersBuilder: Headers.Builder
- get() = param.headersBuilder
-
- @get:JvmName("getCacheStrategy")
- public val cacheStrategy: CacheStrategy
- get() = param.cacheStrategy
-
- private var _okHttpClient: OkHttpClient? = null
-
- @get:JvmName("getOkHttpClient")
- public val okHttpClient: OkHttpClient
- get() {
- if (_okHttpClient != null) return _okHttpClient!!
- val okClient = this.okClient
- var builder: OkHttpClient.Builder? = null
-
- if (LogUtil.isDebug()) {
- val b = builder ?: okClient.newBuilder().also { builder = it }
- b.addInterceptor(LogInterceptor(okClient))
- }
-
- if (connectTimeoutMillis != 0L) {
- val b = builder ?: okClient.newBuilder().also { builder = it }
- b.connectTimeout(connectTimeoutMillis, TimeUnit.MILLISECONDS)
- }
-
- if (readTimeoutMillis != 0L) {
- val b = builder ?: okClient.newBuilder().also { builder = it }
- b.readTimeout(readTimeoutMillis, TimeUnit.MILLISECONDS)
- }
-
- if (writeTimeoutMillis != 0L) {
- val b = builder ?: okClient.newBuilder().also { builder = it }
- b.writeTimeout(writeTimeoutMillis, TimeUnit.MILLISECONDS)
- }
-
- if (param.cacheMode != CacheMode.ONLY_NETWORK) {
- val b = builder ?: okClient.newBuilder().also { builder = it }
- b.addInterceptor(CacheInterceptor(cacheStrategy))
- }
-
- _okHttpClient = builder?.build() ?: okClient
- return _okHttpClient!!
- }
-
- public fun connectTimeout(connectTimeout: Long): R {
- connectTimeoutMillis = connectTimeout
- return self()
- }
-
- public fun readTimeout(readTimeout: Long): R {
- readTimeoutMillis = readTimeout
- return self()
- }
-
- public fun writeTimeout(writeTimeout: Long): R {
- writeTimeoutMillis = writeTimeout
- return self()
- }
-
- public fun setUrl(url: String): R {
- param.url = url
- return self()
- }
-
- /**
- * For example:
- *
- * ```
- * RxHttp.get("/service/{page}/...")
- * .addPath("page", 1)
- * ...
- * ```
- * url = /service/1/...
- */
- public fun addPath(name: String, `value`: Any): R {
- param.addPath(name, value)
- return self()
- }
-
- public fun addEncodedPath(name: String, `value`: Any): R {
- param.addEncodedPath(name, value)
- return self()
- }
-
- @JvmOverloads
- public fun setQuery(
- key: String,
- `value`: Any?,
- add: Boolean = true,
- ): R {
- if (add) param.setQuery(key, value)
- return self()
- }
-
- @JvmOverloads
- public fun setEncodedQuery(
- key: String,
- `value`: Any?,
- add: Boolean = true,
- ): R {
- if (add) param.setEncodedQuery(key, value)
- return self()
- }
-
- public fun removeAllQuery(key: String): R {
- param.removeAllQuery(key)
- return self()
- }
-
- public fun addQuery(key: String): R {
- param.addQuery(key, null)
- return self()
- }
-
- public fun addEncodedQuery(key: String): R {
- param.addEncodedQuery(key, null)
- return self()
- }
-
- @JvmOverloads
- public fun addQuery(
- key: String,
- `value`: Any?,
- add: Boolean = true,
- ): R {
- if (add) param.addQuery(key, value)
- return self()
- }
-
- @JvmOverloads
- public fun addEncodedQuery(
- key: String,
- `value`: Any?,
- add: Boolean = true,
- ): R {
- if (add) param.addEncodedQuery(key, value)
- return self()
- }
-
- public fun addAllQuery(key: String, list: List<*>): R {
- param.addAllQuery(key, list)
- return self()
- }
-
- public fun addAllEncodedQuery(key: String, list: List<*>): R {
- param.addAllEncodedQuery(key, list)
- return self()
- }
-
- public fun addAllQuery(map: Map): R {
- param.addAllQuery(map)
- return self()
- }
-
- public fun addAllEncodedQuery(map: Map): R {
- param.addAllEncodedQuery(map)
- return self()
- }
-
- @JvmOverloads
- public fun addHeader(line: String, add: Boolean = true): R {
- if (add) param.addHeader(line)
- return self()
- }
-
- /**
- * Add a header with the specified name and value. Does validation of header names, allowing non-ASCII values.
- */
- public fun addNonAsciiHeader(key: String, `value`: String): R {
- param.addNonAsciiHeader(key, value)
- return self()
- }
-
- /**
- * Set a header with the specified name and value. Does validation of header names, allowing non-ASCII values.
- */
- public fun setNonAsciiHeader(key: String, `value`: String): R {
- param.setNonAsciiHeader(key, value)
- return self()
- }
-
- @JvmOverloads
- public fun addHeader(
- key: String,
- `value`: String,
- add: Boolean = true,
- ): R {
- if (add) param.addHeader(key, value)
- return self()
- }
-
- public fun addAllHeader(headers: Map): R {
- param.addAllHeader(headers)
- return self()
- }
-
- public fun addAllHeader(headers: Headers): R {
- param.addAllHeader(headers)
- return self()
- }
-
- public fun setHeader(key: String, `value`: String): R {
- param.setHeader(key, value)
- return self()
- }
-
- public fun setAllHeader(headers: Map): R {
- param.setAllHeader(headers)
- return self()
- }
-
- @JvmOverloads
- public fun setRangeHeader(startIndex: Long, endIndex: Long = -1L): R = setRangeHeader(startIndex, endIndex, false)
-
- public fun setRangeHeader(startIndex: Long, connectLastProgress: Boolean): R = setRangeHeader(startIndex, -1, connectLastProgress)
-
- /**
- * 设置断点下载开始/结束位置
- * @param startIndex 断点下载开始位置
- * @param endIndex 断点下载结束位置,默认为-1,即默认结束位置为文件末尾
- * @param connectLastProgress 是否衔接上次的下载进度,该参数仅在带进度断点下载时生效
- */
- public fun setRangeHeader(
- startIndex: Long,
- endIndex: Long,
- connectLastProgress: Boolean,
- ): R {
- param.setRangeHeader(startIndex, endIndex)
- if (connectLastProgress && startIndex >= 0)
- param.tag(DownloadOffSize::class.java, DownloadOffSize(startIndex))
- return self()
- }
-
- public fun removeAllHeader(key: String): R {
- param.removeAllHeader(key)
- return self()
- }
-
- public fun setHeadersBuilder(builder: Headers.Builder): R {
- param.headersBuilder = builder
- return self()
- }
-
- /**
- * 设置单个接口是否需要添加公共参数,
- * 即是否回调[RxHttpPlugins.setOnParamAssembly]方法设置的接口, 默认为true
- */
- public fun setAssemblyEnabled(enabled: Boolean): R {
- param.isAssemblyEnabled = enabled
- return self()
- }
-
- /**
- * 设置单个接口是否需要对Http返回的数据进行解码/解密,
- * 即是否回调[RxHttpPlugins.setResultDecoder]方法设置的接口, 默认为true
- */
- public fun setDecoderEnabled(enabled: Boolean): R {
- param.addHeader(Param.DATA_DECRYPT, enabled.toString())
- return self()
- }
-
- public fun isAssemblyEnabled(): Boolean = param.isAssemblyEnabled
-
- public fun getHeader(key: String): String = param.getHeader(key)
-
- public fun tag(tag: Any): R {
- param.tag(tag)
- return self()
- }
-
- public override fun tag(type: Class, tag: T): R {
- param.tag(type, tag)
- if (type === OutputStreamFactory::class.java) {
- okClient = okClient.newBuilder()
- .addInterceptor(RangeInterceptor())
- .build()
- }
- return self()
- }
-
- public fun cacheControl(cacheControl: CacheControl): R {
- param.cacheControl(cacheControl)
- return self()
- }
-
- public fun setCacheKey(cacheKey: String): R {
- param.cacheKey = cacheKey
- return self()
- }
-
- public fun setCacheValidTime(cacheValidTime: Long): R {
- param.cacheValidTime = cacheValidTime
- return self()
- }
-
- public fun setCacheMode(cacheMode: CacheMode): R {
- param.cacheMode = cacheMode
- return self()
- }
-
- public override fun newCall(): Call {
- val request = buildRequest()
- return okHttpClient.newCall(request)
- }
-
- public fun buildRequest(): Request {
- if (request == null) {
- doOnStart()
- request = param.buildRequest()
- }
- return request!!
- }
-
- /**
- * 请求开始前内部调用,用于添加默认域名等操作
- */
- private fun doOnStart() {
- setConverterToParam(converter)
- addDefaultDomainIfAbsent()
- }
-
- public fun setXmlConverter(): R = setConverter(xmlConverter)
-
- public fun setFastJsonConverter(): R = setConverter(fastJsonConverter)
-
- public fun setConverter(converter: IConverter): R {
- this.converter = converter
- return self()
- }
-
- /**
- * 给Param设置转换器,此方法会在请求发起前,被RxHttp内部调用
- */
- private fun setConverterToParam(converter: IConverter) {
- param.tag(IConverter::class.java, converter)
- }
-
- public fun setOkClient(okClient: OkHttpClient): R {
- this.okClient = okClient
- return self()
- }
-
- public fun setSimpleClient(): R = setOkClient(simpleClient)
-
- /**
- * 给Param设置默认域名(如果缺席的话),此方法会在请求发起前,被RxHttp内部调用
- */
- private fun addDefaultDomainIfAbsent() {
- val originUrl = param.simpleUrl
- if (originUrl.startsWith("http")) return
- setDomainIfAbsent(baseUrl)
- }
-
- public fun setDomainIfAbsent(domain: String): R {
- val newUrl = addDomainIfAbsent(param.simpleUrl, domain)
- param.url = newUrl
- return self()
- }
-
- private fun addDomainIfAbsent(url: String, domain: String): String =
- if (url.startsWith("http")) {
- url
- } else if (url.startsWith("/")) {
- val finalUrl = if (domain.endsWith("/")) url.substring(1) else url
- "$domain$finalUrl"
- } else if (domain.endsWith("/")) {
- "$domain$url"
- } else {
- "$domain/$url"
- }
-
- @Suppress("UNCHECKED_CAST")
- private fun self(): R = this as R
-
- public companion object {
- /**
- * For example:
- *
- * ```
- * RxHttp.get("/service/%d/...", 1)
- * .addQuery("size", 20)
- * ...
- * ```
- * url = /service/1/...?size=20
- */
- @JvmStatic
- public fun `get`(url: String, vararg formatArgs: Any?): RxHttpNoBodyParam = RxHttpNoBodyParam(Param.get(format(url, *formatArgs)))
-
- @JvmStatic
- public fun head(url: String, vararg formatArgs: Any?): RxHttpNoBodyParam = RxHttpNoBodyParam(Param.head(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttpBodyParam(Param.postBody(format(url, *formatArgs)))
-
- @JvmStatic
- public fun putBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttpBodyParam(Param.putBody(format(url, *formatArgs)))
-
- @JvmStatic
- public fun patchBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttpBodyParam(Param.patchBody(format(url, *formatArgs)))
-
- @JvmStatic
- public fun deleteBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttpBodyParam(Param.deleteBody(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttpFormParam(Param.postForm(format(url, *formatArgs)))
-
- @JvmStatic
- public fun putForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttpFormParam(Param.putForm(format(url, *formatArgs)))
-
- @JvmStatic
- public fun patchForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttpFormParam(Param.patchForm(format(url, *formatArgs)))
-
- @JvmStatic
- public fun deleteForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttpFormParam(Param.deleteForm(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttpJsonParam(Param.postJson(format(url, *formatArgs)))
-
- @JvmStatic
- public fun putJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttpJsonParam(Param.putJson(format(url, *formatArgs)))
-
- @JvmStatic
- public fun patchJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttpJsonParam(Param.patchJson(format(url, *formatArgs)))
-
- @JvmStatic
- public fun deleteJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttpJsonParam(Param.deleteJson(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttpJsonArrayParam(Param.postJsonArray(format(url, *formatArgs)))
-
- @JvmStatic
- public fun putJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttpJsonArrayParam(Param.putJsonArray(format(url, *formatArgs)))
-
- @JvmStatic
- public fun patchJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttpJsonArrayParam(Param.patchJsonArray(format(url, *formatArgs)))
-
- @JvmStatic
- public fun deleteJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttpJsonArrayParam(Param.deleteJsonArray(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postEncryptJson(url: String, vararg formatArgs: Any?): RxHttpPostEncryptJsonParam = RxHttpPostEncryptJsonParam(PostEncryptJsonParam(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postEncryptForm(url: String, vararg formatArgs: Any?): RxHttpPostEncryptFormParam = RxHttpPostEncryptFormParam(PostEncryptFormParam(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postEncryptForm(
- url: String,
- method: Method,
- vararg formatArgs: Any?,
- ): RxHttpPostEncryptFormParam = RxHttpPostEncryptFormParam(PostEncryptFormParam(format(url, *formatArgs), method))
-
- @JvmStatic
- public fun getEncrypt(url: String, vararg formatArgs: Any?): RxHttpGetEncryptParam = RxHttpGetEncryptParam(GetEncryptParam(format(url, *formatArgs)))
-
- @JvmStatic
- public fun postEncryptJson1(url: String, vararg formatArgs: Any?): RxHttpPostEncryptJsonParam1 = RxHttpPostEncryptJsonParam1(PostEncryptJsonParam1(format(url, *formatArgs)))
-
- /**
- * Returns a formatted string using the specified format string and arguments.
- */
- private fun format(url: String, vararg formatArgs: Any?): String = if(formatArgs.isEmpty()) url else String.format(url, *formatArgs)
- }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpAbstractBodyParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpAbstractBodyParam.kt
deleted file mode 100644
index a68bc7d7..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpAbstractBodyParam.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package rxhttp.wrapper.param
-
-import rxhttp.wrapper.BodyParamFactory
-import rxhttp.wrapper.param.AbstractBodyParam
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- * https://github.com/liujingxing/rxhttp/wiki/FAQ
- * https://github.com/liujingxing/rxhttp/wiki/更新日志
- */
-open class RxHttpAbstractBodyParam, R : RxHttpAbstractBodyParam
>
-protected constructor(
- param: P
-) : RxHttp
(param), BodyParamFactory {
-
-}
\ No newline at end of file
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpBodyParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpBodyParam.kt
deleted file mode 100644
index ab63d872..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpBodyParam.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package rxhttp.wrapper.param
-
-import android.content.Context
-import android.net.Uri
-import rxhttp.wrapper.entity.UriRequestBody
-
-import okhttp3.MediaType
-import okhttp3.RequestBody
-import okio.ByteString
-import rxhttp.wrapper.param.BodyParam
-import rxhttp.wrapper.OkHttpCompat
-import rxhttp.wrapper.entity.FileRequestBody
-import rxhttp.wrapper.utils.BuildUtil
-import java.io.File
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- */
-open class RxHttpBodyParam(param: BodyParam) : RxHttpAbstractBodyParam(param) {
-
- fun setBody(content: String, contentType: MediaType? = null) =
- setBody(OkHttpCompat.create(contentType, content))
-
- fun setBody(content: ByteString, contentType: MediaType? = null) =
- setBody(OkHttpCompat.create(contentType, content))
-
- @JvmOverloads
- fun setBody(
- content: ByteArray,
- contentType: MediaType? = null,
- offset: Int = 0,
- byteCount: Int = content.size,
- ) = setBody(OkHttpCompat.create(contentType, content, offset, byteCount))
-
- @JvmOverloads
- fun setBody(
- file: File,
- contentType: MediaType? = BuildUtil.getMediaType(file.name),
- ) = setBody(FileRequestBody(file, 0, contentType))
-
- @JvmOverloads
- fun setBody(
- context: Context,
- uri: Uri,
- contentType: MediaType? = BuildUtil.getMediaTypeByUri(context, uri),
- ) = setBody(UriRequestBody(context, uri, 0, contentType))
-
- //Content-Type: application/json; charset=utf-8
- fun setBody(any: Any) = apply { param.setBody(any) }
-
- fun setBody(requestBody: RequestBody) = apply { param.setBody(requestBody) }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpExtension.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpExtension.kt
deleted file mode 100644
index de90f36f..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpExtension.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package rxhttp.wrapper.`param`
-
-import kotlin.collections.List
-import rxhttp.toAwait
-import rxhttp.toFlow
-import rxhttp.wrapper.CallFactory
-import rxhttp.wrapper.coroutines.CallAwait
-import rxhttp.wrapper.coroutines.CallFlow
-import rxhttp.wrapper.utils.javaTypeOf
-
-public inline fun BaseRxHttp.executeList(): List = executeClass>()
-
-public inline fun BaseRxHttp.executeClass(): T = executeClass(javaTypeOf())
-
-public inline fun BaseRxHttp.toObservableList(): ObservableCall> = toObservable>()
-
-public inline fun BaseRxHttp.toObservable(): ObservableCall = toObservable(javaTypeOf())
-
-public inline fun BaseRxHttp.toObservableResponse(): ObservableCall = toObservableResponse(javaTypeOf())
-
-public inline fun CallFactory.toAwaitResponse(): CallAwait = toAwait(BaseRxHttp.wrapResponseParser(javaTypeOf()))
-
-public inline fun CallFactory.toFlowResponse(): CallFlow = toFlow(BaseRxHttp.wrapResponseParser(javaTypeOf()))
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpFormParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpFormParam.kt
deleted file mode 100644
index 0a3b33e2..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpFormParam.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-package rxhttp.wrapper.param
-
-import android.content.Context
-import android.net.Uri
-import rxhttp.wrapper.entity.UriRequestBody
-import okhttp3.Headers
-import okhttp3.MediaType
-import okhttp3.MultipartBody
-import okhttp3.RequestBody
-import rxhttp.wrapper.OkHttpCompat
-import rxhttp.wrapper.entity.FileRequestBody
-import rxhttp.wrapper.entity.UpFile
-import rxhttp.wrapper.param.FormParam
-import rxhttp.wrapper.utils.BuildUtil
-import rxhttp.wrapper.utils.displayName
-import java.io.File
-
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- * https://github.com/liujingxing/rxhttp/wiki/FAQ
- * https://github.com/liujingxing/rxhttp/wiki/更新日志
- */
-open class RxHttpFormParam(param: FormParam) : RxHttpAbstractBodyParam(param) {
-
- @JvmOverloads
- fun add(key: String, value: Any?, add: Boolean = true) = apply {
- if (add) param.add(key, value)
- }
-
- fun addAll(map: Map) = apply { param.addAll(map) }
-
- fun addEncoded(key: String, value: Any?) = apply { param.addEncoded(key, value) }
-
- fun addAllEncoded(map: Map) = apply { param.addAllEncoded(map) }
-
- fun removeAllBody() = apply { param.removeAllBody() }
-
- fun removeAllBody(key: String) = apply { param.removeAllBody(key) }
-
- fun set(key: String, value: Any?) = apply { param[key] = value }
-
- fun setEncoded(key: String, value: Any?) = apply { param.setEncoded(key, value) }
-
- fun addFile(key: String, filePath: String?) =
- if (filePath == null) this else addFile(key, File(filePath))
-
- @JvmOverloads
- fun addFile(key: String, file: File?, filename: String? = file?.name) =
- if (file == null) this else addFile(UpFile(key, file, filename))
-
- fun addFiles(fileList: List) = apply { fileList.forEach { addFile(it) } }
-
- fun addFiles(fileMap: Map) = apply {
- fileMap.forEach { (key, value) -> addFile(key, value) }
- }
-
- fun addFiles(key: String, files: List) = apply {
- files.forEach { addFile(key, it) }
- }
-
- private fun addFile(key: String, file: Any?) {
- if (file is File) {
- addFile(key, file)
- } else if (file is String) {
- addFile(key, file)
- } else if (file != null) {
- throw IllegalArgumentException("Incoming data type exception, it must be String or File")
- }
- }
-
- fun addFile(upFile: UpFile) = apply {
- val requestBody = FileRequestBody(upFile.file, upFile.skipSize, BuildUtil.getMediaType(upFile.filename))
- return addFormDataPart(upFile.key, upFile.filename, requestBody)
- }
-
- @JvmOverloads
- fun addPart(
- content: ByteArray,
- contentType: MediaType? = null,
- offset: Int = 0,
- byteCount: Int = content.size
- ) = addPart(OkHttpCompat.create(contentType, content, offset, byteCount))
-
- @JvmOverloads
- fun addPart(
- context: Context,
- uri: Uri,
- contentType: MediaType? = BuildUtil.getMediaTypeByUri(context, uri)
- ) = addPart(UriRequestBody(context, uri, 0, contentType))
-
- @JvmOverloads
- fun addPart(
- context: Context,
- key: String,
- uri: Uri,
- contentType: MediaType? = BuildUtil.getMediaTypeByUri(context, uri)
- ) = addPart(context, key, uri.displayName(context), uri, contentType)
-
- @JvmOverloads
- fun addPart(
- context: Context,
- key: String,
- filename: String?,
- uri: Uri,
- contentType: MediaType? = BuildUtil.getMediaTypeByUri(context, uri)
- ) = addFormDataPart(key, filename, UriRequestBody(context, uri, 0, contentType))
-
- fun addParts(context: Context, uriMap: Map) = apply {
- uriMap.forEach { (key, value) -> addPart(context, key, value) }
- }
-
- fun addParts(context: Context, uris: List) = apply {
- uris.forEach { addPart(context, it) }
- }
-
- fun addParts(context: Context, uris: List, contentType: MediaType?) = apply {
- uris.forEach { addPart(context, it, contentType) }
- }
-
- fun addParts(context: Context, key: String, uris: List) = apply {
- uris.forEach { addPart(context, key, it) }
- }
-
- fun addParts(context: Context, key: String, uris: List, contentType: MediaType?) = apply {
- uris.forEach { addPart(context, key, it, contentType) }
- }
-
- fun addPart(requestBody: RequestBody) = addPart(OkHttpCompat.part(requestBody))
-
- fun addPart(headers: Headers?, requestBody: RequestBody) =
- addPart(OkHttpCompat.part(headers, requestBody))
-
- fun addFormDataPart(
- key: String,
- fileName: String?,
- requestBody: RequestBody
- ) = addPart(OkHttpCompat.part(key, fileName, requestBody))
-
- fun addPart(key: String, requestBody: RequestBody) = addFormDataPart(key, null, requestBody)
-
- fun addParts(partMap: Map) = apply {
- partMap.forEach { (key, value) -> addPart(key, value) }
- }
-
- fun addPart(part: MultipartBody.Part) = apply { param.addPart(part) }
-
- fun addParts(parts: List) = apply { parts.forEach { addPart(it) } }
-
- //Set content-type to multipart/form-data
- fun setMultiForm() = setMultiType(MultipartBody.FORM)
-
- //Set content-type to multipart/mixed
- fun setMultiMixed() = setMultiType(MultipartBody.MIXED)
-
- //Set content-type to multipart/alternative
- fun setMultiAlternative() = setMultiType(MultipartBody.ALTERNATIVE)
-
- //Set content-type to multipart/digest
- fun setMultiDigest() = setMultiType(MultipartBody.DIGEST)
-
- //Set content-type to multipart/parallel
- fun setMultiParallel() = setMultiType(MultipartBody.PARALLEL)
-
- //Set the MIME type
- fun setMultiType(multiType: MediaType?) = apply { param.multiType = multiType }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpGetEncryptParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpGetEncryptParam.kt
deleted file mode 100644
index 1025384e..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpGetEncryptParam.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package rxhttp.wrapper.`param`
-
-import android.graphics.Point
-import com.example.httpsender.`param`.GetEncryptParam
-import java.io.IOException
-import java.lang.IllegalArgumentException
-import kotlin.Array
-import kotlin.CharSequence
-import kotlin.collections.MutableList
-import kotlin.collections.MutableMap
-import kotlin.jvm.Throws
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- */
-public class RxHttpGetEncryptParam : RxHttpNoBodyParam {
- public constructor(`param`: GetEncryptParam) : super(param)
-
- @Throws(
- IOException::class,
- IllegalArgumentException::class,
- )
- public final fun test(
- a: MutableList,
- map: MutableMap,
- vararg b: Array,
- ): RxHttpGetEncryptParam = apply {
- (param as GetEncryptParam).test(a, map, *b)
- }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpJsonArrayParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpJsonArrayParam.kt
deleted file mode 100644
index 6f17991a..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpJsonArrayParam.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package rxhttp.wrapper.param
-
-import com.google.gson.JsonArray
-import com.google.gson.JsonObject
-
-import rxhttp.wrapper.param.JsonArrayParam
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- * https://github.com/liujingxing/rxhttp/wiki/FAQ
- * https://github.com/liujingxing/rxhttp/wiki/更新日志
- */
-open class RxHttpJsonArrayParam(param: JsonArrayParam) : RxHttpAbstractBodyParam(param) {
-
- @JvmOverloads
- fun add(key: String, value: Any?, add: Boolean = true) = apply {
- if (add) param.add(key, value)
- }
-
- fun addAll(map: Map) = apply { param.addAll(map) }
-
- fun add(any: Any) = apply { param.add(any) }
-
- fun addAll(list: List<*>) = apply { param.addAll(list) }
-
- /**
- * 添加多个对象,将字符串转JsonElement对象,并根据不同类型,执行不同操作,可输入任意非空字符串
- */
- fun addAll(jsonElement: String) = apply { param.addAll(jsonElement) }
-
- fun addAll(jsonArray: JsonArray) = apply { param.addAll(jsonArray) }
-
- /**
- * 将Json对象里面的key-value逐一取出,添加到Json数组中,成为单独的对象
- */
- fun addAll(jsonObject: JsonObject) = apply { param.addAll(jsonObject) }
-
- fun addJsonElement(jsonElement: String) = apply { param.addJsonElement(jsonElement) }
-
- /**
- * 添加一个JsonElement对象(Json对象、json数组等)
- */
- fun addJsonElement(key: String, jsonElement: String) = apply {
- param.addJsonElement(key, jsonElement)
- }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpJsonParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpJsonParam.kt
deleted file mode 100644
index b7f4a2c2..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpJsonParam.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package rxhttp.wrapper.param
-
-import com.google.gson.JsonObject
-
-import rxhttp.wrapper.param.JsonParam
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- * https://github.com/liujingxing/rxhttp/wiki/FAQ
- * https://github.com/liujingxing/rxhttp/wiki/更新日志
- */
-open class RxHttpJsonParam(param: JsonParam) : RxHttpAbstractBodyParam(param) {
-
- @JvmOverloads
- fun add(key: String, value: Any?, add: Boolean = true) = apply {
- if (add) param.add(key, value)
- }
-
- fun addAll(map: Map) = apply { param.addAll(map) }
-
- /**
- * 将Json对象里面的key-value逐一取出,添加到另一个Json对象中,
- * 输入非Json对象将抛出[IllegalStateException]异常
- */
- fun addAll(jsonObject: String) = apply { param.addAll(jsonObject) }
-
- /**
- * 将Json对象里面的key-value逐一取出,添加到另一个Json对象中
- */
- fun addAll(jsonObject: JsonObject) = apply { param.addAll(jsonObject) }
-
- /**
- * 添加一个JsonElement对象(Json对象、json数组等)
- */
- fun addJsonElement(key: String, jsonElement: String) = apply {
- param.addJsonElement(key, jsonElement)
- }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpNoBodyParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpNoBodyParam.kt
deleted file mode 100644
index 3144e3ef..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpNoBodyParam.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package rxhttp.wrapper.param
-
-import rxhttp.wrapper.param.NoBodyParam
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- * https://github.com/liujingxing/rxhttp/wiki/FAQ
- * https://github.com/liujingxing/rxhttp/wiki/更新日志
- */
-open class RxHttpNoBodyParam(param: NoBodyParam) : RxHttp(param) {
-
- @JvmOverloads
- fun add(key: String, value: Any?, add: Boolean = true) = apply {
- if (add) addQuery(key, value)
- }
-
- fun addAll(map: Map) = addAllQuery(map)
-
- fun addEncoded(key: String, value: Any?) = addEncodedQuery(key, value)
-
- fun addAllEncoded(map: Map) = addAllEncodedQuery(map)
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptFormParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptFormParam.kt
deleted file mode 100644
index aa98181d..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptFormParam.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package rxhttp.wrapper.`param`
-
-import com.example.httpsender.`param`.PostEncryptFormParam
-import kotlin.Float
-import kotlin.Int
-import kotlin.Long
-import kotlin.String
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- */
-public class RxHttpPostEncryptFormParam : RxHttpFormParam {
- public constructor(`param`: PostEncryptFormParam) : super(param)
-
- public fun test1(s: String): RxHttpPostEncryptFormParam = apply {
- (param as PostEncryptFormParam).test1(s)
- }
-
- public fun test2(a: Long, b: Float): RxHttpPostEncryptFormParam = apply {
- (param as PostEncryptFormParam).test2(a, b)
- }
-
- public fun add(a: Int, b: Int): Int = (param as PostEncryptFormParam).add(a, b)
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptJsonParam.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptJsonParam.kt
deleted file mode 100644
index a9a9bcee..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptJsonParam.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package rxhttp.wrapper.`param`
-
-import com.example.httpsender.`param`.PostEncryptJsonParam
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- */
-public class RxHttpPostEncryptJsonParam : RxHttpJsonParam {
- public constructor(`param`: PostEncryptJsonParam) : super(param)
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptJsonParam1.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptJsonParam1.kt
deleted file mode 100644
index a7fec587..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxHttpPostEncryptJsonParam1.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package rxhttp.wrapper.`param`
-
-import com.example.httpsender.`param`.PostEncryptJsonParam1
-
-/**
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- */
-public class RxHttpPostEncryptJsonParam1 : RxHttp {
- public constructor(`param`: PostEncryptJsonParam1) : super(param)
-
- public fun test() {
- param.test()
- }
-}
diff --git a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxSimpleHttp.kt b/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxSimpleHttp.kt
deleted file mode 100644
index 53c8bf33..00000000
--- a/app/build/generated/ksp/debug/kotlin/rxhttp/wrapper/param/RxSimpleHttp.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-package rxhttp.wrapper.`param`
-
-import kotlin.Any
-import kotlin.String
-import kotlin.jvm.JvmStatic
-
-/**
- * 本类由@Converter、@Domain、@OkClient注解中的className字段生成 类命名方式: Rx + {className字段值} + Http
- * Github
- * https://github.com/liujingxing/rxhttp
- * https://github.com/liujingxing/rxlife
- * https://github.com/liujingxing/rxhttp/wiki/FAQ
- * https://github.com/liujingxing/rxhttp/wiki/更新日志
- */
-public object RxSimpleHttp {
- /**
- * 本类所有方法都会调用本方法
- */
- private fun > R.wrapper(): R {
- setSimpleClient()
- return this
- }
-
- @JvmStatic
- public fun `get`(url: String, vararg formatArgs: Any?): RxHttpNoBodyParam = RxHttp.get(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun head(url: String, vararg formatArgs: Any?): RxHttpNoBodyParam = RxHttp.head(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttp.postBody(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun putBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttp.putBody(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun patchBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttp.patchBody(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun deleteBody(url: String, vararg formatArgs: Any?): RxHttpBodyParam = RxHttp.deleteBody(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttp.postForm(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun putForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttp.putForm(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun patchForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttp.patchForm(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun deleteForm(url: String, vararg formatArgs: Any?): RxHttpFormParam = RxHttp.deleteForm(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttp.postJson(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun putJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttp.putJson(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun patchJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttp.patchJson(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun deleteJson(url: String, vararg formatArgs: Any?): RxHttpJsonParam = RxHttp.deleteJson(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttp.postJsonArray(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun putJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttp.putJsonArray(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun patchJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttp.patchJsonArray(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun deleteJsonArray(url: String, vararg formatArgs: Any?): RxHttpJsonArrayParam = RxHttp.deleteJsonArray(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postEncryptJson(url: String, vararg formatArgs: Any?): RxHttpPostEncryptJsonParam = RxHttp.postEncryptJson(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postEncryptForm(url: String, vararg formatArgs: Any?): RxHttpPostEncryptFormParam = RxHttp.postEncryptForm(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postEncryptForm(
- url: String,
- method: Method,
- vararg formatArgs: Any?,
- ): RxHttpPostEncryptFormParam = RxHttp.postEncryptForm(url, method, *formatArgs).wrapper()
-
- @JvmStatic
- public fun getEncrypt(url: String, vararg formatArgs: Any?): RxHttpGetEncryptParam = RxHttp.getEncrypt(url, *formatArgs).wrapper()
-
- @JvmStatic
- public fun postEncryptJson1(url: String, vararg formatArgs: Any?): RxHttpPostEncryptJsonParam1 = RxHttp.postEncryptJson1(url, *formatArgs).wrapper()
-}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index a390ba34..30cb0f6c 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -20,50 +20,8 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
--keepclassmembers class com.example.httpsender.entity.** {
- (); #R8 full mode下, 默认构造方法不保留
- !transient ;
-}
-# With R8 full mode generic signatures are stripped for classes that are not kept.
--keep,allowobfuscation,allowshrinking class com.example.httpsender.entity.Response
--keep,allowobfuscation,allowshrinking class com.example.httpsender.entity.PageList
-
-
-#依赖simple-xml后打包失败,需加入以下规则
--dontwarn android.content.res.**
-
-#依赖fastjson后打包失败,需加入以下规则
--dontwarn javax.ws.rs.**
-
-# Please add these rules to your existing keep rules in order to suppress warnings.
-# This is generated automatically by the Android Gradle plugin.
--dontwarn com.google.common.collect.ArrayListMultimap
--dontwarn com.google.common.collect.Multimap
--dontwarn java.awt.Color
--dontwarn java.awt.Font
--dontwarn java.awt.Point
--dontwarn java.awt.Rectangle
--dontwarn javax.money.CurrencyUnit
--dontwarn javax.money.Monetary
--dontwarn javax.ws.rs.Consumes
--dontwarn javax.ws.rs.Produces
--dontwarn javax.ws.rs.core.Response
--dontwarn javax.ws.rs.core.StreamingOutput
--dontwarn javax.ws.rs.ext.MessageBodyReader
--dontwarn javax.ws.rs.ext.MessageBodyWriter
--dontwarn javax.ws.rs.ext.Provider
--dontwarn org.glassfish.jersey.internal.spi.AutoDiscoverable
--dontwarn org.javamoney.moneta.Money
--dontwarn org.joda.time.DateTime
--dontwarn org.joda.time.DateTimeZone
--dontwarn org.joda.time.Duration
--dontwarn org.joda.time.Instant
--dontwarn org.joda.time.LocalDate
--dontwarn org.joda.time.LocalDateTime
--dontwarn org.joda.time.LocalTime
--dontwarn org.joda.time.Period
--dontwarn org.joda.time.ReadablePartial
--dontwarn org.joda.time.format.DateTimeFormat
--dontwarn org.joda.time.format.DateTimeFormatter
--dontwarn springfox.documentation.spring.web.json.Json
\ No newline at end of file
+#RxHttp
+-keep class rxhttp.**{*;}
+#RxLife
+-keep class com.rxjava.rxlife.**{*;}
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/example/httpsender/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/httpsender/ExampleInstrumentedTest.java
deleted file mode 100644
index e73af3a0..00000000
--- a/app/src/androidTest/java/com/example/httpsender/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.example.httpsender;
-
-import android.content.Context;
-import android.util.Log;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import io.reactivex.rxjava3.disposables.Disposable;
-import rxhttp.wrapper.param.RxHttp;
-
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
- Disposable subscribe = RxHttp.get("https://www.wanandroid.com/article/list/0/json")
- .toObservableString()
- .subscribe(s -> {
- System.out.println(s);
- }, throwable -> {
- Log.e("LJX", "useAppContext");
- });
-
- while (!subscribe.isDisposed()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 01ec62d9..b7c8726a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
-
+
@@ -7,23 +8,22 @@
-
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/AppHolder.java b/app/src/main/java/com/example/httpsender/AppHolder.java
index 706f587f..3a6e84e7 100644
--- a/app/src/main/java/com/example/httpsender/AppHolder.java
+++ b/app/src/main/java/com/example/httpsender/AppHolder.java
@@ -10,7 +10,6 @@
* Date: 2019/3/31
* Time: 09:11
*/
-//@HiltAndroidApp
public class AppHolder extends Application {
private static AppHolder instance;
diff --git a/app/src/main/java/com/example/httpsender/DownloadMultiActivity.java b/app/src/main/java/com/example/httpsender/DownloadMultiActivity.java
new file mode 100644
index 00000000..ce1cbaa3
--- /dev/null
+++ b/app/src/main/java/com/example/httpsender/DownloadMultiActivity.java
@@ -0,0 +1,185 @@
+package com.example.httpsender;
+
+import android.os.Bundle;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.RecyclerView;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+import com.example.httpsender.DownloadMultiAdapter.OnItemClickListener;
+import com.example.httpsender.entity.DownloadInfo;
+import com.rxjava.rxlife.RxLife;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import rxhttp.wrapper.param.RxHttp;
+
+/**
+ * 多任务下载
+ * User: ljx
+ * Date: 2019-06-07
+ * Time: 11:02
+ */
+public class DownloadMultiActivity extends AppCompatActivity implements OnItemClickListener {
+
+ public static final int MAX_TASK_COUNT = 3; //最大并发数
+
+ private DownloadMultiAdapter mAdapter;
+
+ private String[] downloadUrl = {
+ "http://update.9158.com/miaolive/Miaolive.apk",//喵播
+ "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk",//探探
+ "https://o8g2z2sa4.qnssl.com/android/momo_8.18.5_c1.apk",//陌陌
+ "http://s9.pstatp.com/package/apk/aweme/app_aweGW_v6.6.0_2905d5c.apk"//抖音
+ };
+
+ private List waitTask = new ArrayList<>(); //等待下载的任务
+ private List downloadingTask = new ArrayList<>(); //等待下载的任务
+
+ private List downloadInfos = new ArrayList<>();
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.download_multi_activity);
+
+ for (int i = 0; i < 20; i++) {
+ DownloadInfo downloadInfo = new DownloadInfo(downloadUrl[i % downloadUrl.length]);
+ downloadInfo.setTaskId(i);
+ downloadInfos.add(downloadInfo);
+ }
+ mAdapter = new DownloadMultiAdapter(downloadInfos);
+ mAdapter.setOnItemClickListener(this);
+ mAdapter.setHasStableIds(true);
+
+ RecyclerView recyclerView = findViewById(R.id.recycler_view);
+ recyclerView.setAdapter(mAdapter);
+ }
+
+ public static long lastChangedTime;
+
+ //500毫秒刷新一次列表
+ private void notifyDataSetChanged(boolean force) {
+ long time = System.currentTimeMillis();
+ if (time - lastChangedTime > 500 || force) {
+ mAdapter.notifyDataSetChanged();
+ lastChangedTime = time;
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.download, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.download_all) {
+ if ("全部下载".contentEquals(item.getTitle())) {
+ for (DownloadInfo info : downloadInfos) {
+ download(info);
+ }
+ item.setTitle("全部取消");
+ } else if ("全部取消".contentEquals(item.getTitle())) {
+ Iterator iterator = waitTask.iterator();
+ while (iterator.hasNext()) {
+ DownloadInfo next = iterator.next();
+ next.setState(6);
+ iterator.remove();
+ }
+
+ iterator = downloadingTask.iterator();
+ while (iterator.hasNext()) {
+ DownloadInfo next = iterator.next();
+ iterator.remove();
+ Disposable disposable = next.getDisposable();
+ if (disposable != null && !disposable.isDisposed()) {
+ disposable.dispose();
+ }
+ next.setState(6);
+ }
+ item.setTitle("全部下载");
+ notifyDataSetChanged(true);
+ }
+
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onItemClick(View view, DownloadInfo data, int position) {
+ switch (view.getId()) {
+ case R.id.bt_pause:
+ int state = data.getState();
+ if (state == 0) {
+ download(data);
+ } else if (state == 1) {
+ waitTask.remove(data);
+ data.setState(6);
+ } else if (state == 2) {
+ Disposable disposable = data.getDisposable();
+ if (disposable != null && !disposable.isDisposed()) {
+ disposable.dispose();
+ data.setState(3);
+ notifyDataSetChanged(true);
+ }
+ } else if (state == 3) {
+ download(data);
+ } else if (state == 4) {
+ Tip.show("该任务已完成");
+ } else if (state == 5) {
+ Tip.show("该任务下载失败");
+ } else if (state == 6) {
+ download(data);
+ }
+ break;
+ }
+ }
+
+ private void download(DownloadInfo data) {
+ if (downloadingTask.size() >= MAX_TASK_COUNT) {
+ data.setState(1);
+ waitTask.add(data);
+ return;
+ }
+ String destPath = getExternalCacheDir() + "/" + data.getTaskId() + ".apk";
+ long length = new File(destPath).length();
+ Disposable disposable = RxHttp.get(data.getUrl())
+ .setRangeHeader(length) //设置开始下载位置,结束位置默认为文件末尾
+ .asDownload(destPath, length, progress -> { //如果需要衔接上次的下载进度,则需要传入上次已下载的字节数length
+ //下载进度回调,0-100,仅在进度有更新时才会回调
+ if (!progress.isCompleted()) {
+ data.setProgress(progress.getProgress());//当前进度 0-100
+ data.setCurrentSize(progress.getCurrentSize());//当前已下载的字节大小
+ data.setTotalSize(progress.getTotalSize()); //要下载的总字节大小
+ notifyDataSetChanged(false);
+ }
+ }, AndroidSchedulers.mainThread())
+ .doFinally(() -> {//不管任务成功还是失败,如果还有在等待的任务,都开启下一个任务
+ downloadingTask.remove(data);
+ if (waitTask.size() > 0)
+ download(waitTask.remove(0));
+ })
+ .as(RxLife.as(this)) //加入感知生命周期的观察者
+ .subscribe(s -> { //s为String类型
+ Tip.show("下载完成" + s);
+ data.setState(4);
+ notifyDataSetChanged(true);
+ //下载成功,处理相关逻辑
+ }, (OnError) error -> {
+ data.setState(5);
+ //下载失败,处理相关逻辑
+ });
+ data.setState(2);
+ downloadingTask.add(data);
+ data.setDisposable(disposable);
+ }
+}
diff --git a/app/src/main/java/com/example/httpsender/DownloadMultiAdapter.java b/app/src/main/java/com/example/httpsender/DownloadMultiAdapter.java
index 51199267..9391fc57 100644
--- a/app/src/main/java/com/example/httpsender/DownloadMultiAdapter.java
+++ b/app/src/main/java/com/example/httpsender/DownloadMultiAdapter.java
@@ -1,6 +1,8 @@
package com.example.httpsender;
import android.annotation.SuppressLint;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -8,16 +10,11 @@
import android.widget.ProgressBar;
import android.widget.TextView;
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
import com.example.httpsender.DownloadMultiAdapter.MyViewHolder;
-import com.example.httpsender.entity.DownloadTask;
-import com.example.httpsender.vm.MultiTaskDownloader;
+import com.example.httpsender.entity.DownloadInfo;
import java.text.DecimalFormat;
import java.util.List;
-import java.util.Locale;
/**
* User: ljx
@@ -26,12 +23,12 @@
*/
public class DownloadMultiAdapter extends RecyclerView.Adapter {
- private OnItemClickListener mOnItemClickListener;
+ private OnItemClickListener mOnItemClickListener;
- private List mDownloadTasks;
+ private List mDownloadInfos;
- public DownloadMultiAdapter(List downloadTasks) {
- mDownloadTasks = downloadTasks;
+ public DownloadMultiAdapter(List downloadInfos) {
+ mDownloadInfos = downloadInfos;
}
@NonNull
@@ -44,9 +41,9 @@ public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
@SuppressLint("DefaultLocale")
@Override
public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int i) {
- DownloadTask data = mDownloadTasks.get(i);
- viewHolder.progressBar.setProgress((int) (data.getProgress()*100));
- viewHolder.tvProgress.setText(String.format("%.1f%%", data.getProgress() * 100));
+ DownloadInfo data = mDownloadInfos.get(i);
+ viewHolder.progressBar.setProgress(data.getProgress());
+ viewHolder.tvProgress.setText(String.format("%d%%", data.getProgress()));
viewHolder.btPause.setOnClickListener(v -> {
mOnItemClickListener.onItemClick(v, data, i);
});
@@ -55,64 +52,42 @@ public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int i) {
viewHolder.tvSize.setText(String.format("%sM/%sM", currentSize, totalSize));
int state = data.getState();
- if (state == MultiTaskDownloader.IDLE) {
+ if (state == 0) {
viewHolder.tvWaiting.setText("未开始");
viewHolder.btPause.setText("开始");
- } else if (state == MultiTaskDownloader.WAITING) {
+ } else if (state == 1) {
viewHolder.tvWaiting.setText("等待中..");
viewHolder.btPause.setText("取消");
- } else if (state == MultiTaskDownloader.DOWNLOADING) {
- viewHolder.tvWaiting.setText(getSpeed(data.getSpeed()));
- long remainingTime = data.getRemainingTime();
- if (remainingTime > 0) {
- viewHolder.tvWaiting.append(" 预估还需" + getRemainingTime(remainingTime));
- }
+ } else if (state == 2) {
+ viewHolder.tvWaiting.setText("下载中..");
viewHolder.btPause.setText("暂停");
- } else if (state == MultiTaskDownloader.PAUSED) {
+ } else if (state == 3) {
viewHolder.tvWaiting.setText("已暂停");
- viewHolder.btPause.setText("继续下载");
- } else if (state == MultiTaskDownloader.COMPLETED) {
+ viewHolder.btPause.setText("继续");
+ } else if (state == 4) {
viewHolder.tvWaiting.setText("已完成");
viewHolder.btPause.setText("已完成");
- } else if (state == MultiTaskDownloader.FAIL) {
+ } else if (state == 5) {
viewHolder.tvWaiting.setText("下载失败");
- viewHolder.btPause.setText("重新下载");
- } else if (state == MultiTaskDownloader.CANCEL) {
+ viewHolder.btPause.setText("下载失败");
+ } else if (state == 6) {
viewHolder.tvWaiting.setText("已取消");
- viewHolder.btPause.setText("继续下载");
- }
- }
-
- private String getSpeed(long speed) {
- float kb = speed * 1.0f / 1024;
- if (kb > 1000) {
- return String.format(Locale.getDefault(), "%.2fMB/s", kb / 1024);
- } else {
- return ((int) kb) + "KB/s";
+ viewHolder.btPause.setText("重新下载");
}
- }
- private String getRemainingTime(long time) {
- if (time < 300) {
- return time + "秒";
- } else {
- long minute = time / 60;
- if (time % 60 > 0) minute++;
- return minute + "分";
- }
}
@Override
public int getItemCount() {
- return mDownloadTasks.size();
+ return mDownloadInfos.size();
}
@Override
public long getItemId(int position) {
- return mDownloadTasks.get(position).hashCode();
+ return mDownloadInfos.get(position).hashCode();
}
- static class MyViewHolder extends RecyclerView.ViewHolder {
+ class MyViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
TextView tvProgress;
@@ -132,7 +107,7 @@ static class MyViewHolder extends RecyclerView.ViewHolder {
}
- public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
+ public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
diff --git a/app/src/main/java/com/example/httpsender/ExceptionHelper.java b/app/src/main/java/com/example/httpsender/ExceptionHelper.java
index d3e43e0b..b21519cc 100644
--- a/app/src/main/java/com/example/httpsender/ExceptionHelper.java
+++ b/app/src/main/java/com/example/httpsender/ExceptionHelper.java
@@ -5,6 +5,11 @@
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+import java.util.concurrent.TimeoutException;
+
/**
* 异常处理帮助类
* User: ljx
@@ -13,10 +18,27 @@
*/
public class ExceptionHelper {
- @SuppressWarnings("deprecation")
+ //处理网络异常
+ public static String handleNetworkException(T throwable) {
+ int stringId = -1;
+ if (throwable instanceof UnknownHostException) {
+ if (!isNetworkConnected(AppHolder.getInstance())) {
+ stringId = R.string.network_error;
+ } else {
+ stringId = R.string.notify_no_network;
+ }
+ } else if (throwable instanceof SocketTimeoutException || throwable instanceof TimeoutException) {
+ //前者是通过OkHttpClient设置的超时引发的异常,后者是对单个请求调用timeout方法引发的超时异常
+ stringId = R.string.time_out_please_try_again_later;
+ } else if (throwable instanceof ConnectException) {
+ stringId = R.string.esky_service_exception;
+ }
+ return stringId == -1 ? null : AppHolder.getInstance().getString(stringId);
+ }
+
public static boolean isNetworkConnected(Context context) {
if (context != null) {
- ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ ConnectivityManager mConnectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
diff --git a/app/src/main/java/com/example/httpsender/LoggingEventListener.kt b/app/src/main/java/com/example/httpsender/LoggingEventListener.kt
deleted file mode 100644
index a34a40b2..00000000
--- a/app/src/main/java/com/example/httpsender/LoggingEventListener.kt
+++ /dev/null
@@ -1,159 +0,0 @@
-package com.example.httpsender
-
-import android.util.Log
-import okhttp3.Call
-import okhttp3.Connection
-import okhttp3.EventListener
-import okhttp3.Handshake
-import okhttp3.HttpUrl
-import okhttp3.Protocol
-import okhttp3.Request
-import okhttp3.Response
-import java.io.IOException
-import java.net.InetAddress
-import java.net.InetSocketAddress
-import java.net.Proxy
-import java.util.concurrent.TimeUnit
-
-/**
- * User: ljx
- * Date: 2022/4/22
- * Time: 16:05
- */
-class LoggingEventListener : EventListener() {
- private var startNs: Long = 0
-
- override fun callStart(call: Call) {
- startNs = System.nanoTime()
-
- logWithTime("callStart: ${call.request()}")
- }
-
- override fun proxySelectStart(call: Call, url: HttpUrl) {
- logWithTime("proxySelectStart: $url")
- }
-
- override fun proxySelectEnd(call: Call, url: HttpUrl, proxies: List) {
- logWithTime("proxySelectEnd: $proxies")
- }
-
- override fun dnsStart(call: Call, domainName: String) {
- logWithTime("dnsStart: $domainName")
- }
-
- override fun dnsEnd(call: Call, domainName: String, inetAddressList: List) {
- logWithTime("dnsEnd: $inetAddressList")
- }
-
- override fun connectStart(call: Call, inetSocketAddress: InetSocketAddress, proxy: Proxy) {
- logWithTime("connectStart: $inetSocketAddress $proxy")
- }
-
- override fun secureConnectStart(call: Call) {
- logWithTime("secureConnectStart")
- }
-
- override fun secureConnectEnd(call: Call, handshake: Handshake?) {
- logWithTime("secureConnectEnd: $handshake")
- }
-
- override fun connectEnd(
- call: Call,
- inetSocketAddress: InetSocketAddress,
- proxy: Proxy,
- protocol: Protocol?
- ) {
- logWithTime("connectEnd: $protocol")
- }
-
- override fun connectFailed(
- call: Call,
- inetSocketAddress: InetSocketAddress,
- proxy: Proxy,
- protocol: Protocol?,
- ioe: IOException
- ) {
- logWithTime("connectFailed: $protocol $ioe")
- }
-
- override fun connectionAcquired(call: Call, connection: Connection) {
- logWithTime("connectionAcquired: $connection")
- }
-
- override fun connectionReleased(call: Call, connection: Connection) {
- logWithTime("connectionReleased")
- }
-
- override fun requestHeadersStart(call: Call) {
- logWithTime("requestHeadersStart")
- }
-
- override fun requestHeadersEnd(call: Call, request: Request) {
- logWithTime("requestHeadersEnd")
- }
-
- override fun requestBodyStart(call: Call) {
- logWithTime("requestBodyStart")
- }
-
- override fun requestBodyEnd(call: Call, byteCount: Long) {
- logWithTime("requestBodyEnd: byteCount=$byteCount")
- }
-
- override fun requestFailed(call: Call, ioe: IOException) {
- logWithTime("requestFailed: $ioe")
- }
-
- override fun responseHeadersStart(call: Call) {
- logWithTime("responseHeadersStart")
- }
-
- override fun responseHeadersEnd(call: Call, response: Response) {
- logWithTime("responseHeadersEnd: $response")
- }
-
- override fun responseBodyStart(call: Call) {
- logWithTime("responseBodyStart")
- }
-
- override fun responseBodyEnd(call: Call, byteCount: Long) {
- logWithTime("responseBodyEnd: byteCount=$byteCount")
- }
-
- override fun responseFailed(call: Call, ioe: IOException) {
- logWithTime("responseFailed: $ioe")
- }
-
- override fun callEnd(call: Call) {
- logWithTime("callEnd")
- }
-
- override fun callFailed(call: Call, ioe: IOException) {
- logWithTime("callFailed: $ioe")
- }
-
- override fun canceled(call: Call) {
- logWithTime("canceled")
- }
-
- override fun satisfactionFailure(call: Call, response: Response) {
- logWithTime("satisfactionFailure: $response")
- }
-
- override fun cacheHit(call: Call, response: Response) {
- logWithTime("cacheHit: $response")
- }
-
- override fun cacheMiss(call: Call) {
- logWithTime("cacheMiss")
- }
-
- override fun cacheConditionalHit(call: Call, cachedResponse: Response) {
- logWithTime("cacheConditionalHit: $cachedResponse")
- }
-
- private fun logWithTime(message: String) {
- val timeMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs)
- Log.e("LJX", "[$timeMs ms] $message")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/MainActivity.java b/app/src/main/java/com/example/httpsender/MainActivity.java
index a158c812..43e98b5a 100644
--- a/app/src/main/java/com/example/httpsender/MainActivity.java
+++ b/app/src/main/java/com/example/httpsender/MainActivity.java
@@ -1,123 +1,338 @@
package com.example.httpsender;
-import android.content.Context;
+import android.content.Intent;
import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
+import android.os.Environment;
import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import androidx.activity.EdgeToEdge;
-import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.core.graphics.Insets;
-import androidx.core.view.OnApplyWindowInsetsListener;
-import androidx.core.view.ViewCompat;
-import androidx.core.view.WindowInsetsCompat;
import androidx.databinding.DataBindingUtil;
-import androidx.fragment.app.Fragment;
-import com.example.httpsender.adapter.FragmentPageAdapter;
import com.example.httpsender.databinding.MainActivityBinding;
-import com.example.httpsender.fragment.AwaitFragment;
-import com.example.httpsender.fragment.FlowFragment;
-import com.example.httpsender.fragment.MultiDownloadFragment;
-import com.example.httpsender.fragment.RxJavaFragment;
-import com.example.httpsender.view.ScaleTransitionPagerTitleView;
-
-import net.lucode.hackware.magicindicator.MagicIndicator;
-import net.lucode.hackware.magicindicator.ViewPagerHelper;
-import net.lucode.hackware.magicindicator.buildins.UIUtil;
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator;
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator;
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.SimplePagerTitleView;
+import com.example.httpsender.entity.Article;
+import com.example.httpsender.entity.Location;
+import com.example.httpsender.entity.Name;
+import com.example.httpsender.entity.NewsDataXml;
+import com.google.gson.Gson;
+import com.rxjava.rxlife.RxLife;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import rxhttp.wrapper.param.RxHttp;
+
public class MainActivity extends AppCompatActivity {
private MainActivityBinding mBinding;
- private final List mDataList = new ArrayList<>();
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- EdgeToEdge.enable(this);
mBinding = DataBindingUtil.setContentView(this, R.layout.main_activity);
- ViewCompat.setOnApplyWindowInsetsListener(mBinding.getRoot(), new OnApplyWindowInsetsListener() {
- @NonNull
- @Override
- public WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
- Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
- mBinding.magicIndicator.setPadding(0, systemBars.top, 0, 0);
- LayoutParams layoutParams = mBinding.magicIndicator.getLayoutParams();
- layoutParams.height = (int) (getResources().getDisplayMetrics().density * 50 + systemBars.top);
- mBinding.magicIndicator.setLayoutParams(layoutParams);
- return insets;
- }
- });
- mBinding.viewPager.setOffscreenPageLimit(4);
- mDataList.add("RxJava");
- mDataList.add("Await");
- mDataList.add("Flow");
- mDataList.add("Multi Download");
- List fragments = new ArrayList<>();
- fragments.add(new RxJavaFragment());
- fragments.add(new AwaitFragment());
- fragments.add(new FlowFragment());
- fragments.add(new MultiDownloadFragment());
- mBinding.viewPager.setAdapter(new FragmentPageAdapter(getSupportFragmentManager(), fragments, mDataList));
- initMagicIndicator();
- }
-
- public void initMagicIndicator() {
- MagicIndicator magicIndicator = mBinding.magicIndicator;
- CommonNavigator commonNavigator = new CommonNavigator(this);
- commonNavigator.setAdapter(new CommonNavigatorAdapter() {
- @Override
- public int getCount() {
- return mDataList == null ? 0 : mDataList.size();
- }
-
- @Override
- public IPagerTitleView getTitleView(Context context, final int index) {
- SimplePagerTitleView simplePagerTitleView = new ScaleTransitionPagerTitleView(context);
- simplePagerTitleView.setPadding(dp2px(5), 0, 0, 0);
- simplePagerTitleView.setText(mDataList.get(index));
- simplePagerTitleView.setTextSize(18);
- simplePagerTitleView.setNormalColor(Color.parseColor("#c8e6c9"));
- simplePagerTitleView.setSelectedColor(Color.WHITE);
- simplePagerTitleView.setOnClickListener(v -> mBinding.viewPager.setCurrentItem(index));
- return simplePagerTitleView;
- }
-
- @Override
- public IPagerIndicator getIndicator(Context context) {
- LinePagerIndicator indicator = new LinePagerIndicator(context);
- indicator.setMode(LinePagerIndicator.MODE_EXACTLY);
- indicator.setLineHeight(UIUtil.dip2px(context, 3));
- indicator.setLineWidth(UIUtil.dip2px(context, 30));
- indicator.setRoundRadius(UIUtil.dip2px(context, 3));
- indicator.setStartInterpolator(new AccelerateInterpolator());
- indicator.setYOffset(dp2px(3));
- indicator.setEndInterpolator(new DecelerateInterpolator(2.0f));
- indicator.setColors(Color.WHITE);
- return indicator;
- }
- });
- magicIndicator.setNavigator(commonNavigator);
- ViewPagerHelper.bind(magicIndicator, mBinding.viewPager);
- }
-
- private int dp2px(double dpValue) {
- float density = getResources().getDisplayMetrics().density;
- return (int) (dpValue * density + 0.5);
}
+
+ public void bitmap(View view) {
+ String imageUrl = "http://img2.shelinkme.cn/d3/photos/0/017/022/755_org.jpg@!normal_400_400?1558517697888";
+ RxHttp.get(imageUrl) //Get请求
+ .asBitmap() //这里返回Observable 对象
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(bitmap -> {
+ mBinding.tvResult.setBackground(new BitmapDrawable(bitmap));
+ //成功回调
+ }, (OnError) error -> {
+ mBinding.tvResult.setText(error.getErrorMsg());
+ //失败回调
+ error.show("图片加载失败,请稍后再试!");
+ });
+ }
+
+ //发送Get请求,获取文章列表
+ public void sendGet(View view) {
+ RxHttp.get("/article/list/0/json")
+ .asResponsePageList(Article.class)
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(pageList -> {
+ mBinding.tvResult.setText(new Gson().toJson(pageList));
+ //成功回调
+ }, (OnError) error -> {
+ mBinding.tvResult.setText(error.getErrorMsg());
+ //失败回调
+ error.show("发送失败,请稍后再试!");
+ });
+ }
+
+ //发送Post表单请求,根据关键字查询文章
+ public void sendPostForm(View view) {
+ RxHttp.postForm("/article/query/0/json")
+ .add("k", "性能优化")
+ .asResponsePageList(Article.class)
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(pageList -> {
+ mBinding.tvResult.setText(new Gson().toJson(pageList));
+ //成功回调
+ }, (OnError) error -> {
+ mBinding.tvResult.setText(error.getErrorMsg());
+ //失败回调
+ error.show("发送失败,请稍后再试!");
+ });
+ }
+
+ //发送Post Json请求,此接口不通,仅用于调试参数
+ public void sendPostJson(View view) {
+ //发送以下User对象
+ /*
+ {
+ "name": "张三",
+ "sex": 1,
+ "height": 180,
+ "weight": 70,
+ "interest": [
+ "羽毛球",
+ "游泳"
+ ],
+ "location": {
+ "latitude": 30.7866,
+ "longitude": 120.6788
+ },
+ "address": {
+ "street": "科技园路.",
+ "city": "江苏苏州",
+ "country": "中国"
+ }
+ }
+ */
+ List interestList = new ArrayList<>();//爱好
+ interestList.add("羽毛球");
+ interestList.add("游泳");
+ String address = "{\"street\":\"科技园路.\",\"city\":\"江苏苏州\",\"country\":\"中国\"}";
+
+ RxHttp.postJson("/article/list/0/json")
+ .add("name", "张三")
+ .add("sex", 1)
+ .addAll("{\"height\":180,\"weight\":70}") //通过addAll系列方法添加多个参数
+ .add("interest", interestList) //添加数组对象
+ .add("location", new Location(120.6788, 30.7866)) //添加位置对象
+ .addJsonElement("address", address) //通过字符串添加一个对象
+ .asString()
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(s -> {
+ mBinding.tvResult.setText(s);
+ //成功回调
+ }, (OnError) error -> {
+ mBinding.tvResult.setText(error.getErrorMsg());
+ //失败回调
+ error.show("发送失败,请稍后再试!");
+ });
+ }
+
+
+ //发送Post JsonArray请求,此接口不通,仅用于调试参数
+ public void sendPostJsonArray(View view) {
+ //发送以下Json数组
+ /*
+ [
+ {
+ "name": "张三"
+ },
+ {
+ "name": "李四"
+ },
+ {
+ "name": "王五"
+ },
+ {
+ "name": "赵六"
+ },
+ {
+ "name": "杨七"
+ }
+ ]
+ */
+ List names = new ArrayList<>();
+ names.add(new Name("赵六"));
+ names.add(new Name("杨七"));
+ RxHttp.postJsonArray("/article/list/0/json")
+ .add("name", "张三")
+ .add(new Name("李四"))
+ .addJsonElement("{\"name\":\"王五\"}")
+ .addAll(names)
+ .asString()
+ .as(RxLife.asOnMain(this))
+ .subscribe(s -> {
+ mBinding.tvResult.setText(s);
+ }, (OnError) error -> {
+ mBinding.tvResult.setText(error.getErrorMsg());
+ //失败回调
+ error.show("发送失败,请稍后再试!");
+ });
+ }
+
+ //使用XmlConverter解析数据,此接口返回数据太多,会有点慢
+ public void xmlConverter(View view) {
+ RxHttp.get("http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni")
+ .setXmlConverter()
+ .asObject(NewsDataXml.class)
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(dataXml -> {
+ mBinding.tvResult.setText(new Gson().toJson(dataXml));
+ //成功回调
+ }, (OnError) error -> {
+ mBinding.tvResult.setText(error.getErrorMsg());
+ //失败回调
+ error.show("发送失败,请稍后再试!");
+ });
+ }
+
+ //使用XmlConverter解析数据
+ public void fastJsonConverter(View view) {
+ RxHttp.get("/article/list/0/json")
+ .setFastJsonConverter()
+ .asResponsePageList(Article.class)
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(pageList -> {
+ mBinding.tvResult.setText(new Gson().toJson(pageList));
+ //成功回调
+ }, (OnError) error -> {
+ mBinding.tvResult.setText(error.getErrorMsg());
+ //失败回调
+ error.show("发送失败,请稍后再试!");
+ });
+ }
+
+ //文件下载,不带进度
+ public void download(View view) {
+ String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
+ RxHttp.get("/miaolive/Miaolive.apk")
+ .setDomainToUpdateIfAbsent() //使用指定的域名
+ .asDownload(destPath)
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(s -> {
+ //下载成功,回调文件下载路径
+ }, (OnError) error -> {
+ //下载失败
+ error.show("下载失败,请稍后再试!");
+ });
+ }
+
+ //文件下载,带进度
+ public void downloadAndProgress(View view) {
+ //文件存储路径
+ String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
+ RxHttp.get("/miaolive/Miaolive.apk")
+ .setDomainToUpdateIfAbsent()//使用指定的域名
+ .asDownload(destPath, progress -> {
+ //下载进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,最后一次回调文件存储路径
+ int currentProgress = progress.getProgress(); //当前进度 0-100
+ long currentSize = progress.getCurrentSize(); //当前已下载的字节大小
+ long totalSize = progress.getTotalSize(); //要下载的总字节大小
+ mBinding.tvResult.append("\n" + progress.toString());
+ }, AndroidSchedulers.mainThread()) //指定回调(进度/成功/失败)线程,不指定,默认在请求所在线程回调
+ .as(RxLife.as(this)) //感知生命周期
+ .subscribe(s -> {
+ //下载完成,处理相关逻辑
+ mBinding.tvResult.append("\n下载成功 : " + s);
+ }, (OnError) error -> {
+ mBinding.tvResult.append("\n" + error.getErrorMsg());
+ //下载失败,处理相关逻辑
+ error.show("下载失败,请稍后再试!");
+ });
+ }
+
+ //断点下载
+ public void breakpointDownload(View view) {
+ String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";
+ long length = new File(destPath).length();
+ RxHttp.get("/miaolive/Miaolive.apk")
+ .setDomainToUpdateIfAbsent() //使用指定的域名
+ .setRangeHeader(length) //设置开始下载位置,结束位置默认为文件末尾
+ .asDownload(destPath) //注意这里使用DownloadParser解析器,并传入本地路径
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(s -> {
+ //下载成功,回调文件下载路径
+ }, (OnError) error -> {
+ //下载失败
+ error.show("下载失败,请稍后再试!");
+ });
+ }
+
+ //断点下载,带进度
+ public void breakpointDownloadAndProgress(View view) {
+ String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";
+ long length = new File(destPath).length();
+ RxHttp.get("/miaolive/Miaolive.apk")
+ .setDomainToUpdateIfAbsent()//使用指定的域名
+ .setRangeHeader(length) //设置开始下载位置,结束位置默认为文件末尾
+ .asDownload(destPath, length, progress -> { //如果需要衔接上次的下载进度,则需要传入上次已下载的字节数length
+ //下载进度回调,0-100,仅在进度有更新时才会回调
+ int currentProgress = progress.getProgress(); //当前进度 0-100
+ long currentSize = progress.getCurrentSize(); //当前已下载的字节大小
+ long totalSize = progress.getTotalSize(); //要下载的总字节大小
+ mBinding.tvResult.append("\n" + progress.toString());
+ }, AndroidSchedulers.mainThread()) //指定回调(进度/成功/失败)线程,不指定,默认在请求所在线程回调
+ .as(RxLife.as(this)) //加入感知生命周期的观察者
+ .subscribe(s -> {
+ //下载成功
+ mBinding.tvResult.append("\n下载成功 : " + s);
+ }, (OnError) error -> {
+ //下载失败
+ mBinding.tvResult.append("\n" + error.getErrorMsg());
+ error.show("下载失败,请稍后再试!");
+ });
+ }
+
+
+ //文件上传,不带进度
+ public void upload(View v) {
+ RxHttp.postForm("http://t.xinhuo.com/index.php/Api/Pic/uploadPic")
+ .addFile("uploaded_file", new File(Environment.getExternalStorageDirectory(), "1.jpg"))
+ .asString() //from操作符,是异步操作
+ .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调
+ .subscribe(s -> {
+ mBinding.tvResult.append("\n");
+ mBinding.tvResult.append(s);
+ //成功回调
+ }, (OnError) error -> {
+ mBinding.tvResult.append("\n");
+ mBinding.tvResult.append(error.getErrorMsg());
+ //失败回调
+ error.show("上传失败,请稍后再试!");
+ });
+ }
+
+ //上传文件,带进度
+ public void uploadAndProgress(View v) {
+ RxHttp.postForm("http://t.xinhuo.com/index.php/Api/Pic/uploadPic")
+ .addFile("uploaded_file", new File(Environment.getExternalStorageDirectory(), "1.jpg"))
+ .asUpload(progress -> {
+ //上传进度回调,0-100,仅在进度有更新时才会回调
+ int currentProgress = progress.getProgress(); //当前进度 0-100
+ long currentSize = progress.getCurrentSize(); //当前已上传的字节大小
+ long totalSize = progress.getTotalSize(); //要上传的总字节大小
+ mBinding.tvResult.append("\n" + progress.toString());
+ }, AndroidSchedulers.mainThread()) //指定回调(进度/成功/失败)线程,不指定,默认在请求所在线程回调
+ .as(RxLife.as(this)) //加入感知生命周期的观察者
+ .subscribe(s -> {
+ //上传成功
+ mBinding.tvResult.append("\n上传成功 : " + s);
+ }, (OnError) error -> {
+ //上传失败
+ mBinding.tvResult.append("\n" + error.getErrorMsg());
+ error.show("上传失败,请稍后再试!");
+ });
+ }
+
+ //多任务下载
+ public void multitaskDownload(View view) {
+ startActivity(new Intent(this, DownloadMultiActivity.class));
+ }
+
+ public void clearLog(View view) {
+ mBinding.tvResult.setText("");
+ mBinding.tvResult.setBackgroundColor(Color.TRANSPARENT);
+ }
}
diff --git a/app/src/main/java/com/example/httpsender/MyViewModel.java b/app/src/main/java/com/example/httpsender/MyViewModel.java
new file mode 100644
index 00000000..8f4dfc29
--- /dev/null
+++ b/app/src/main/java/com/example/httpsender/MyViewModel.java
@@ -0,0 +1,30 @@
+package com.example.httpsender;
+
+import android.app.Application;
+import androidx.annotation.NonNull;
+import android.util.Log;
+
+import com.rxjava.rxlife.RxLife;
+import com.rxjava.rxlife.ScopeViewModel;
+
+import java.util.concurrent.TimeUnit;
+
+import io.reactivex.Observable;
+
+/**
+ * User: ljx
+ * Date: 2019-05-31
+ * Time: 21:50
+ */
+public class MyViewModel extends ScopeViewModel {
+
+
+ public MyViewModel(@NonNull Application application) {
+ super(application);
+ Observable.interval(1, 1, TimeUnit.SECONDS)
+ .as(RxLife.asOnMain(this))
+ .subscribe(aLong -> {
+ Log.e("LJX", "MyViewModel aLong=" + aLong);
+ });
+ }
+}
diff --git a/app/src/main/java/com/example/httpsender/MyViewModel.kt b/app/src/main/java/com/example/httpsender/MyViewModel.kt
deleted file mode 100644
index 2b69c2f6..00000000
--- a/app/src/main/java/com/example/httpsender/MyViewModel.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.example.httpsender
-
-import android.app.Application
-import android.util.Log
-import androidx.lifecycle.viewModelScope
-import com.example.httpsender.entity.Article
-import com.example.httpsender.entity.PageList
-import com.rxjava.rxlife.ScopeViewModel
-import com.rxjava.rxlife.lifeOnMain
-import io.reactivex.rxjava3.core.Observable
-import kotlinx.coroutines.TimeoutCancellationException
-import kotlinx.coroutines.launch
-import rxhttp.awaitResult
-import rxhttp.retry
-import rxhttp.timeout
-import rxhttp.wrapper.param.RxHttp
-import rxhttp.wrapper.param.toAwaitResponse
-import java.util.concurrent.TimeUnit
-
-/**
- * User: ljx
- * Date: 2019-05-31
- * Time: 21:50
- */
-class MyViewModel(application: Application) : ScopeViewModel(application) {
-
- fun startInterval() {
- Observable.interval(1, 1, TimeUnit.SECONDS)
- .lifeOnMain(this)
- .subscribe { Log.e("LJX", "MyViewModel aLong=$it") }
- }
-
- fun testRetry() = viewModelScope.launch {
- RxHttp.get("/article/list/0/json")
- .toAwaitResponse>()
- .timeout(100)
- .retry(2, 1000) {
- it is TimeoutCancellationException
- }
- .awaitResult {
- Log.e("LJX", "pageList=$it")
- }
- .onFailure {
- Log.e("LJX", "it=$it")
- }
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/OnError.java b/app/src/main/java/com/example/httpsender/OnError.java
index 5fb27aac..6e113303 100644
--- a/app/src/main/java/com/example/httpsender/OnError.java
+++ b/app/src/main/java/com/example/httpsender/OnError.java
@@ -3,7 +3,7 @@
import com.example.httpsender.entity.ErrorInfo;
-import io.reactivex.rxjava3.functions.Consumer;
+import io.reactivex.functions.Consumer;
/**
diff --git a/app/src/main/java/com/example/httpsender/Presenter.java b/app/src/main/java/com/example/httpsender/Presenter.java
new file mode 100644
index 00000000..f6236aa7
--- /dev/null
+++ b/app/src/main/java/com/example/httpsender/Presenter.java
@@ -0,0 +1,28 @@
+package com.example.httpsender;
+
+import androidx.lifecycle.LifecycleOwner;
+import android.util.Log;
+
+import com.rxjava.rxlife.BaseScope;
+import com.rxjava.rxlife.RxLife;
+
+import java.util.concurrent.TimeUnit;
+
+import io.reactivex.Observable;
+
+/**
+ * User: ljx
+ * Date: 2019-05-26
+ * Time: 15:20
+ */
+public class Presenter extends BaseScope {
+
+ public Presenter(LifecycleOwner owner) {
+ super(owner); //添加生命周期监听
+ Observable.interval(1, 1, TimeUnit.SECONDS)
+ .as(RxLife.as(this)) //这里的this 为Scope接口对象
+ .subscribe(aLong -> {
+ Log.e("LJX", "accept aLong=" + aLong);
+ });
+ }
+}
diff --git a/app/src/main/java/com/example/httpsender/Presenter.kt b/app/src/main/java/com/example/httpsender/Presenter.kt
deleted file mode 100644
index 62735dff..00000000
--- a/app/src/main/java/com/example/httpsender/Presenter.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.example.httpsender
-
-import android.util.Log
-import androidx.lifecycle.LifecycleOwner
-import com.example.httpsender.entity.Article
-import com.example.httpsender.entity.PageList
-import com.rxjava.rxlife.BaseScope
-import com.rxjava.rxlife.life
-import io.reactivex.rxjava3.core.Observable
-import kotlinx.coroutines.*
-import rxhttp.*
-import rxhttp.wrapper.cache.CacheMode
-import rxhttp.wrapper.param.RxHttp
-import rxhttp.wrapper.param.toAwaitResponse
-import java.util.concurrent.TimeUnit
-
-/**
- * User: ljx
- * Date: 2019-05-26
- * Time: 15:20
- */
-class Presenter(owner: LifecycleOwner) : BaseScope(owner) {
-
- fun test() {
- Observable.interval(1, 1, TimeUnit.SECONDS)
- .life(this) //这里的this 为Scope接口对象
- .subscribe { Log.e("LJX", "accept aLong=$it") }
- }
-
- fun testRetry() {
- val coroutineScope: CoroutineScope =
- CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
- coroutineScope.launch {
- RxHttp.postForm("/article/query/0/json")
- .add("k", "性能优化")
- .setCacheMode(CacheMode.ONLY_NETWORK)
- .toAwaitResponse>()
- .delay(100)
- .startDelay(100)
- .onErrorReturnItem(PageList())
- .timeout(1000)
- .retry(2, 1000) {
- it is TimeoutCancellationException
- }
- .awaitResult {
- Log.e("RxHttp", "onNext = $it")
- }.onFailure {
- Log.e("RxHttp", "onError = $it")
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/RxHttpManager.java b/app/src/main/java/com/example/httpsender/RxHttpManager.java
index 81e3955f..ed262388 100644
--- a/app/src/main/java/com/example/httpsender/RxHttpManager.java
+++ b/app/src/main/java/com/example/httpsender/RxHttpManager.java
@@ -6,71 +6,76 @@
import java.io.File;
import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509TrustManager;
+
import okhttp3.OkHttpClient;
-import rxhttp.RxHttpPlugins;
import rxhttp.wrapper.annotation.Converter;
-import rxhttp.wrapper.annotation.OkClient;
import rxhttp.wrapper.callback.IConverter;
import rxhttp.wrapper.converter.FastJsonConverter;
import rxhttp.wrapper.converter.XmlConverter;
import rxhttp.wrapper.cookie.CookieStore;
import rxhttp.wrapper.param.Method;
-import rxhttp.wrapper.ssl.HttpsUtils;
-import rxhttp.wrapper.ssl.HttpsUtils.SSLParams;
+import rxhttp.wrapper.param.RxHttp;
+import rxhttp.wrapper.ssl.SSLSocketFactoryImpl;
+import rxhttp.wrapper.ssl.X509TrustManagerImpl;
/**
- * 本类所有配置都是非必须的,根据自己需求选择就好
* User: ljx
* Date: 2019-11-26
* Time: 20:44
*/
public class RxHttpManager {
- @Converter(name = "XmlConverter") //非必须
- public static IConverter xmlConverter = XmlConverter.create();
- @Converter(name = "FastJsonConverter") //非必须
+ @Converter(name = "FastJsonConverter")
public static IConverter fastJsonConverter = FastJsonConverter.create();
-
- @OkClient(name = "SimpleClient", className = "Simple") //非必须
- public static OkHttpClient simpleClient = new OkHttpClient.Builder().build();
+ @Converter(name = "XmlConverter")
+ public static IConverter xmlConverter = XmlConverter.create();
public static void init(Application context) {
File file = new File(context.getExternalCacheDir(), "RxHttpCookie");
- SSLParams sslParams = HttpsUtils.getSslSocketFactory();
+ X509TrustManager trustAllCert = new X509TrustManagerImpl();
+ SSLSocketFactory sslSocketFactory = new SSLSocketFactoryImpl(trustAllCert);
OkHttpClient client = new OkHttpClient.Builder()
.cookieJar(new CookieStore(file))
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
- .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager) //添加信任证书
+ .sslSocketFactory(sslSocketFactory, trustAllCert) //添加信任证书
.hostnameVerifier((hostname, session) -> true) //忽略host验证
// .followRedirects(false) //禁制OkHttp的重定向操作,我们自己处理重定向
// .addInterceptor(new RedirectInterceptor())
// .addInterceptor(new TokenInterceptor())
.build();
+ //RxHttp初始化,自定义OkHttpClient对象,非必须
+ RxHttp.init(client, BuildConfig.DEBUG);
//设置缓存策略,非必须
-// File cacheFile = new File(context.getExternalCacheDir(), "RxHttpCache");
- //RxHttp初始化,非必须
- RxHttpPlugins.init(client) //自定义OkHttpClient对象
- .setDebug(BuildConfig.DEBUG, false, 2) //调试模式/分段打印/json数据缩进空间
-// .setCache(cacheFile, 1000 * 100, CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE)
-// .setExcludeCacheKeys("time") //设置一些key,不参与cacheKey的组拼
-// .setResultDecoder(s -> s) //设置数据解密/解码器,非必须
-// .setConverter(FastJsonConverter.create()) //设置全局的转换器,非必须
- .setOnParamAssembly(p -> { //设置公共参数,非必须
- //1、可根据不同请求添加不同参数,每次发送请求前都会被回调
- //2、如果希望部分请求不回调这里,发请求前调用RxHttp#setAssemblyEnabled(false)即可
- Method method = p.getMethod();
- if (method.isGet()) {
- p.add("method", "get");
- } else if (method.isPost()) { //Post请求
- p.add("method", "post");
- }
- p.add("versionName", "1.0.0")//添加公共参数
- .add("time", System.currentTimeMillis())
- .addHeader("deviceType", "android"); //添加公共请求头
- });
+// File file = new File(context.getExternalCacheDir(), "RxHttpCache");
+// RxHttpPlugins.setCache(file, 1000 * 100, CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE);
+// RxHttpPlugins.setExcludeCacheKeys("time"); //设置一些key,不参与cacheKey的组拼
+
+ //设置数据解密/解码器,非必须
+// RxHttp.setResultDecoder(s -> s);
+
+ //设置全局的转换器,非必须
+// RxHttp.setConverter(FastJsonConverter.create());
+
+ //设置公共参数,非必须
+ RxHttp.setOnParamAssembly(p -> {
+ /*根据不同请求添加不同参数,子线程执行,每次发送请求前都会被回调
+ 如果希望部分请求不回调这里,发请求前调用Param.setAssemblyEnabled(false)即可
+ */
+ Method method = p.getMethod();
+ if (method.isGet()) { //Get请求
+
+ } else if (method.isPost()) { //Post请求
+
+ }
+ return p.add("versionName", "1.0.0")//添加公共参数
+ .add("time", System.currentTimeMillis())
+ .addHeader("deviceType", "android"); //添加公共请求头
+ });
}
}
diff --git a/app/src/main/java/com/example/httpsender/ToolBarActivity.java b/app/src/main/java/com/example/httpsender/ToolBarActivity.java
deleted file mode 100644
index 53acd96d..00000000
--- a/app/src/main/java/com/example/httpsender/ToolBarActivity.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.example.httpsender;
-
-import android.os.Build;
-import android.view.MenuItem;
-import android.view.ViewGroup;
-
-import androidx.annotation.LayoutRes;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.Toolbar;
-import androidx.databinding.DataBindingUtil;
-import androidx.databinding.ViewDataBinding;
-
-
-/**
- * 需要ToolBar的activity都必须继承本类
- */
-public abstract class ToolBarActivity extends AppCompatActivity {
-
- protected Toolbar toolbar;
- protected ActionBar actionBar;
- private ViewGroup mContainer;
-
- public T bindingInflate(@LayoutRes int layoutResID) {
- initView();
- return DataBindingUtil.inflate(getLayoutInflater(), layoutResID, mContainer, true);
- }
-
- @Override
- public void setContentView(@LayoutRes int layoutResID) {
- initView();
- getLayoutInflater().inflate(layoutResID, mContainer, true);
- }
-
- private void initView() {
- super.setContentView(R.layout.toolbar_activity);
- mContainer = findViewById(R.id.container);
- toolbar = findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int itemId = item.getItemId();
- if (itemId == android.R.id.home) {
- boolean popSuccess = getSupportFragmentManager().popBackStackImmediate();
- if (popSuccess) return true;
- finish();
- }
- return super.onOptionsItemSelected(item);
- }
-
- public void setToolbarColor(int color) {
- toolbar.setBackgroundColor(color);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- getWindow().setStatusBarColor(color);
- }
- }
-
- @Override
- public void setTitle(CharSequence title) {
- super.setTitle(title);
- if (toolbar == null) return;
- toolbar.setTitle(title);
- }
-
- @Override
- public void setTitle(int titleId) {
- super.setTitle(titleId);
- if (toolbar == null) return;
- toolbar.setTitle(titleId);
- }
-
- protected int dp2px(float dpValue) {
- final float scale = getResources().getDisplayMetrics().density;
- return (int) (dpValue * scale + 0.5f);
- }
-}
diff --git a/app/src/main/java/com/example/httpsender/adapter/FragmentPageAdapter.java b/app/src/main/java/com/example/httpsender/adapter/FragmentPageAdapter.java
deleted file mode 100644
index 71be75bf..00000000
--- a/app/src/main/java/com/example/httpsender/adapter/FragmentPageAdapter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.example.httpsender.adapter;
-
-
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentPagerAdapter;
-
-import java.util.Arrays;
-import java.util.List;
-
-
-/**
- * User: ljx
- * Date: 2018/6/9
- * Time: 13:53
- */
-public class FragmentPageAdapter extends FragmentPagerAdapter {
-
- private List extends Fragment> mFragments;
- private List extends CharSequence> mTitles;
-
-
- public FragmentPageAdapter(FragmentManager fm, List extends Fragment> fragments, String[] titles) {
- this(fm, fragments, Arrays.asList(titles));
- }
-
- public FragmentPageAdapter(FragmentManager fm, List extends Fragment> fragments, List extends CharSequence> titles) {
- super(fm);
- mFragments = fragments;
- mTitles = titles;
- }
-
- @Override
- public int getCount() {
- return mFragments.size();
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
- return mTitles.get(position);
- }
-
- @Override
- public Fragment getItem(int position) {
- return mFragments.get(position);
- }
-}
diff --git a/app/src/main/java/com/example/httpsender/entity/Article.java b/app/src/main/java/com/example/httpsender/entity/Article.java
index fe45f4eb..200cf6d6 100644
--- a/app/src/main/java/com/example/httpsender/entity/Article.java
+++ b/app/src/main/java/com/example/httpsender/entity/Article.java
@@ -284,20 +284,4 @@ public void setVisible(int visible) {
public void setZan(int zan) {
this.zan = zan;
}
-
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- Article article = (Article) o;
-
- return id == article.id;
- }
-
- @Override
- public int hashCode() {
- return id;
- }
}
diff --git a/app/src/main/java/com/example/httpsender/entity/DownloadInfo.java b/app/src/main/java/com/example/httpsender/entity/DownloadInfo.java
new file mode 100644
index 00000000..9125773b
--- /dev/null
+++ b/app/src/main/java/com/example/httpsender/entity/DownloadInfo.java
@@ -0,0 +1,88 @@
+package com.example.httpsender.entity;
+
+import io.reactivex.disposables.Disposable;
+
+/**
+ * User: ljx
+ * Date: 2019-06-08
+ * Time: 10:09
+ */
+public class DownloadInfo {
+
+ private int taskId;
+
+ private String url;
+ private int progress;
+
+ private long currentSize;
+ private long totalSize;
+
+ private Disposable mDisposable;
+
+
+ private int state; //0=未开始 1=等待中 2=下载中 3=暂停中 4=已完成 5=下载失败 6=已取消
+
+ public int getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(int taskId) {
+ this.taskId = taskId;
+ }
+
+ public int getState() {
+ return state;
+ }
+
+ public void setState(int state) {
+ this.state = state;
+ }
+
+ public Disposable getDisposable() {
+ return mDisposable;
+ }
+
+ public void setDisposable(Disposable disposable) {
+ mDisposable = disposable;
+ }
+
+ public boolean isDownloading() {
+ return mDisposable != null && !mDisposable.isDisposed();
+ }
+
+ public DownloadInfo(String url) {
+ this.url = url;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public int getProgress() {
+ return progress;
+ }
+
+ public void setProgress(int progress) {
+ this.progress = progress;
+ }
+
+ public long getCurrentSize() {
+ return currentSize;
+ }
+
+ public void setCurrentSize(long currentSize) {
+ this.currentSize = currentSize;
+ }
+
+ public long getTotalSize() {
+ return totalSize;
+ }
+
+ public void setTotalSize(long totalSize) {
+ this.totalSize = totalSize;
+ }
+}
diff --git a/app/src/main/java/com/example/httpsender/entity/DownloadTask.java b/app/src/main/java/com/example/httpsender/entity/DownloadTask.java
deleted file mode 100644
index 3e8106bc..00000000
--- a/app/src/main/java/com/example/httpsender/entity/DownloadTask.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.example.httpsender.entity;
-
-
-
-/**
- * User: ljx
- * Date: 2019-06-08
- * Time: 10:09
- */
-public class DownloadTask {
-
- private String url;
- private String localPath;
-
- private float progress;
- private long currentSize;
- private long totalSize;
-
- private long speed;
- private long remainingTime;
-
- private int state; //0=未开始 1=等待中 2=下载中 3=暂停中 4=已完成 5=下载失败 6=已取消
-
-
- public DownloadTask(String url) {
- this.url = url;
- }
-
- public int getState() {
- return state;
- }
-
- public void setState(int state) {
- this.state = state;
- }
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getLocalPath() {
- return localPath;
- }
-
- public void setLocalPath(String localPath) {
- this.localPath = localPath;
- }
-
- public long getSpeed() {
- return speed;
- }
-
- public void setSpeed(long speed) {
- this.speed = speed;
- }
-
- public long getRemainingTime() {
- return remainingTime;
- }
-
- public void setRemainingTime(long remainingTime) {
- this.remainingTime = remainingTime;
- }
-
- public float getProgress() {
- return progress;
- }
-
- public void setProgress(float progress) {
- this.progress = progress;
- }
-
- public long getCurrentSize() {
- return currentSize;
- }
-
- public void setCurrentSize(long currentSize) {
- this.currentSize = currentSize;
- }
-
- public long getTotalSize() {
- return totalSize;
- }
-
- public void setTotalSize(long totalSize) {
- this.totalSize = totalSize;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- DownloadTask task = (DownloadTask) o;
-
- return url.equals(task.url);
- }
-
- @Override
- public int hashCode() {
- return url.hashCode();
- }
-}
diff --git a/app/src/main/java/com/example/httpsender/entity/ErrorInfo.java b/app/src/main/java/com/example/httpsender/entity/ErrorInfo.java
index 7b76d143..2979a9ea 100644
--- a/app/src/main/java/com/example/httpsender/entity/ErrorInfo.java
+++ b/app/src/main/java/com/example/httpsender/entity/ErrorInfo.java
@@ -4,15 +4,9 @@
import com.example.httpsender.AppHolder;
import com.example.httpsender.ExceptionHelper;
-import com.example.httpsender.R;
import com.example.httpsender.Tip;
import com.google.gson.JsonSyntaxException;
-import java.net.ConnectException;
-import java.net.SocketTimeoutException;
-import java.net.UnknownHostException;
-import java.util.concurrent.TimeoutException;
-
import rxhttp.wrapper.exception.HttpStatusCodeException;
import rxhttp.wrapper.exception.ParseException;
@@ -30,34 +24,19 @@ public class ErrorInfo {
public ErrorInfo(Throwable throwable) {
this.throwable = throwable;
- String errorMsg = null;
- if (throwable instanceof UnknownHostException) {
- if (!ExceptionHelper.isNetworkConnected(AppHolder.getInstance())) {
- errorMsg = getString(R.string.network_error);
- } else {
- errorMsg = getString(R.string.notify_no_network);
- }
- } else if (throwable instanceof SocketTimeoutException || throwable instanceof TimeoutException) {
- //前者是通过OkHttpClient设置的超时引发的异常,后者是对单个请求调用timeout方法引发的超时异常
- errorMsg = getString(R.string.time_out_please_try_again_later);
- } else if (throwable instanceof ConnectException) {
- errorMsg = getString(R.string.esky_service_exception);
- } else if (throwable instanceof HttpStatusCodeException) { //请求失败异常
+ String errorMsg = ExceptionHelper.handleNetworkException(throwable); //网络异常
+ if (throwable instanceof HttpStatusCodeException) { //请求失败异常
String code = throwable.getLocalizedMessage();
if ("416".equals(code)) {
errorMsg = "请求范围不符合要求";
- } else {
- errorMsg = throwable.getMessage();
}
} else if (throwable instanceof JsonSyntaxException) { //请求成功,但Json语法异常,导致解析失败
errorMsg = "数据解析失败,请稍后再试";
} else if (throwable instanceof ParseException) { // ParseException异常表明请求成功,但是数据不正确
String errorCode = throwable.getLocalizedMessage();
- this.errorCode = Integer.parseInt(errorCode);
+ this.errorCode = Integer.valueOf(errorCode);
errorMsg = throwable.getMessage();
if (TextUtils.isEmpty(errorMsg)) errorMsg = errorCode;//errorMsg为空,显示errorCode
- } else {
- errorMsg = throwable.getMessage();
}
this.errorMsg = errorMsg;
}
@@ -94,8 +73,4 @@ public boolean show(int standbyMsg) {
Tip.show(TextUtils.isEmpty(errorMsg) ? AppHolder.getInstance().getString(standbyMsg) : errorMsg);
return true;
}
-
- public String getString(int resId) {
- return AppHolder.getInstance().getString(resId);
- }
}
diff --git a/app/src/main/java/com/example/httpsender/entity/Name.java b/app/src/main/java/com/example/httpsender/entity/Name.java
index 2eadd925..555f090d 100644
--- a/app/src/main/java/com/example/httpsender/entity/Name.java
+++ b/app/src/main/java/com/example/httpsender/entity/Name.java
@@ -12,12 +12,4 @@ public class Name {
public Name(String name) {
this.name = name;
}
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
}
diff --git a/app/src/main/java/com/example/httpsender/entity/PageList.java b/app/src/main/java/com/example/httpsender/entity/PageList.java
index daac1ba6..2306cb71 100644
--- a/app/src/main/java/com/example/httpsender/entity/PageList.java
+++ b/app/src/main/java/com/example/httpsender/entity/PageList.java
@@ -1,7 +1,6 @@
package com.example.httpsender.entity;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -44,7 +43,7 @@ public void setTotal(int total) {
this.total = total;
}
- public void setDatas(ArrayList datas) {
+ public void setDatas(List datas) {
this.datas = datas;
}
}
diff --git a/app/src/main/java/com/example/httpsender/entity/Url.kt b/app/src/main/java/com/example/httpsender/entity/Url.kt
index 73083ab6..71b297b1 100644
--- a/app/src/main/java/com/example/httpsender/entity/Url.kt
+++ b/app/src/main/java/com/example/httpsender/entity/Url.kt
@@ -1,20 +1,22 @@
package com.example.httpsender.entity
+
import rxhttp.wrapper.annotation.DefaultDomain
import rxhttp.wrapper.annotation.Domain
/**
* User: ljx
- * Date: 2020/2/27
- * Time: 23:55
+ * Date: 2019/3/27
+ * Time: 10:36
*/
-object Url {
+class Url {
- @JvmField
- @DefaultDomain //设置为默认域名
- var baseUrl = "https://www.wanandroid.com/"
+ companion object {
+ @Domain(name = "Update")
+ const val update = "http://update.9158.com"
- const val UPLOAD_URL = "http://t.xinhuo.com/index.php/Api/Pic/uploadPic"
+ @DefaultDomain //设置为默认域名
+ const val baseUrl = "https://www.wanandroid.com/"
+ }
- const val DOWNLOAD_URL = "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk"
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/example/httpsender/fragment/AwaitFragment.kt b/app/src/main/java/com/example/httpsender/fragment/AwaitFragment.kt
deleted file mode 100644
index 3ee62c4d..00000000
--- a/app/src/main/java/com/example/httpsender/fragment/AwaitFragment.kt
+++ /dev/null
@@ -1,320 +0,0 @@
-package com.example.httpsender.fragment
-
-import android.graphics.Color
-import android.net.Uri
-import android.os.Bundle
-import android.view.View
-import androidx.lifecycle.lifecycleScope
-import com.example.httpsender.R
-import com.example.httpsender.databinding.AwaitFragmentBinding
-import com.example.httpsender.entity.*
-import com.example.httpsender.kt.errorMsg
-import com.example.httpsender.kt.show
-import com.google.gson.Gson
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.launch
-import rxhttp.*
-import rxhttp.wrapper.param.RxHttp
-import rxhttp.wrapper.param.toAwaitResponse
-import java.io.File
-import java.util.*
-
-/**
- * 使用 协程(RxHttp + Await) 发请求
- *
- * ```
- * val user = RxHttp.postXxx("/service/...")
- * .add("key", "value")
- * .toAwait()
- * .awaitResult {
- * val user = it
- * }.onFailure {
- * val throwable = it
- * }
- *```
- *
- * User: ljx
- * Date: 2020/4/24
- * Time: 18:16
- */
-class AwaitFragment : BaseFragment(), View.OnClickListener {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.await_fragment)
- }
-
- override fun AwaitFragmentBinding.onViewCreated(savedInstanceState: Bundle?) {
- click = this@AwaitFragment
- }
-
- //发送Get请求,获取文章列表
- private suspend fun AwaitFragmentBinding.sendGet(view: View) {
- RxHttp.get("/article/list/0/json")
- .toAwaitResponse>()
- .toAwaitOkResponse()
- .awaitResult {
- val list = it.body()
- val response = it.raw()
- val headers = it.headers()
- tvResult.text = Gson().toJson(list)
- }.onFailure {
- tvResult.text = it.errorMsg
- //失败回调
- it.show()
- }
- }
-
- //发送Post表单请求,根据关键字查询文章
- private suspend fun AwaitFragmentBinding.sendPostForm(view: View) {
- RxHttp.postForm("/article/query/0/json")
- .add("k", "性能优化")
- .toAwaitResponse>()
- .awaitResult {
- tvResult.text = Gson().toJson(it)
- }.onFailure {
- tvResult.text = it.errorMsg
- //失败回调
- it.show()
- }
- }
-
- //发送Post Json请求,此接口不通,通过日志可以看到,发送出去的json对象
- private suspend fun AwaitFragmentBinding.sendPostJson(view: View) {
- /*
- 发送以下User对象
- {"name":"张三","sex":1,"height":180,"weight":70,
- "interest":["羽毛球","游泳"],
- "location":{"latitude":30.7866,"longitude":120.6788},
- "address":{"street":"科技园路.","city":"江苏苏州","country":"中国"}}
- */
- val interestList: MutableList = ArrayList() //爱好
- interestList.add("羽毛球")
- interestList.add("游泳")
- val address = """
- {"street":"科技园路.","city":"江苏苏州","country":"中国"}
- """.trimIndent()
- RxHttp.postJson("/article/list/0/json")
- .add("name", "张三")
- .add("sex", 1)
- .addAll("""{"height":180,"weight":70}""") //通过addAll系列方法添加多个参数
- .add("interest", interestList) //添加数组对象
- .add("location", Location(120.6788, 30.7866)) //添加位置对象
- .addJsonElement("address", address) //通过字符串添加一个对象
- .toAwaitString()
- .awaitResult {
- tvResult.text = it
- }.onFailure {
- tvResult.text = it.errorMsg
- //失败回调
- it.show()
- }
- }
-
- //发送Post JsonArray请求,通过日志可以看到,发送出去的json数组
- private suspend fun AwaitFragmentBinding.sendPostJsonArray(view: View) {
- /*
- 发送以下Json数组
- [{"name":"张三"},{"name":"李四"},{"name":"王五"},{"name":"赵六"},{"name":"杨七"}]
- */
- val names: MutableList = ArrayList()
- names.add(Name("赵六"))
- names.add(Name("杨七"))
- RxHttp.postJsonArray("/article/list/0/json")
- .add("name", "张三")
- .add(Name("李四"))
- .addJsonElement("""{"name":"王五"}""")
- .addAll(names)
- .toAwaitString()
- .awaitResult {
- tvResult.text = it
- }.onFailure {
- tvResult.text = it.errorMsg
- //失败回调
- it.show()
- }
-
- }
-
- //此接口不同,但通过日志可以看到,发送出去的是xml数据,如果收到也是xml数据,则会自动解析为我们指定的对象
- private suspend fun AwaitFragmentBinding.xmlConverter(view: View) {
- RxHttp.postBody("http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni")
- .setBody(Name("张三"))
- .setXmlConverter()
- .toAwait()
- .awaitResult {
- tvResult.text = Gson().toJson(it)
- }.onFailure {
- tvResult.text = it.errorMsg
- //失败回调
- it.show()
- }
- }
-
- /**
- * android 10之前 或 沙盒目录(Android/data/packageName/)下的文件上传
- *
- * 注意:这里并非通过 [Await] 实现的, 而是通过 [Flow] 监听的进度,因为在监听上传进度这块,Flow性能更优,且更简单
- *
- * 如不需要监听进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun AwaitFragmentBinding.upload(v: View) {
- RxHttp.postForm(Url.UPLOAD_URL)
- .addFile("file", File("xxxx/1.png"))
- .toFlow()
- .onProgress {
- //上传进度回调,0-100,仅在进度有更新时才会回调
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已上传的字节大小
- val totalSize = it.totalSize //要上传的总字节大小
- tvResult.append("\n$it")
- }.catch {
- tvResult.append("\n${it.errorMsg}")
- //失败回调
- it.show()
- }.collect {
- tvResult.append("\n上传成功 : $it")
- }
- }
-
- /**
- * android 10 及以上文件上传 ,兼容Android 10以下
- *
- * 注意:这里并非通过 [Await] 实现的, 而是通过 [Flow] 监听的进度,因为在监听上传进度这块,Flow性能更优,且更简单
- *
- * 如不需要监听进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun AwaitFragmentBinding.uploadAndroid10(v: View) {
- //真实环境,需要调用文件选择器,拿到Uri对象
- val uri = Uri.parse("content://media/external/downloads/13417")
- RxHttp.postForm(Url.UPLOAD_URL)
- .addPart(requireContext(), "file", uri)
- .toFlow()
- .onProgress {
- //上传进度回调,0-100,仅在进度有更新时才会回调
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已上传的字节大小
- val totalSize = it.totalSize //要上传的总字节大小
- tvResult.append("\n$it")
- }.catch {
- tvResult.append("\n${it.errorMsg}")
- //失败回调
- it.show()
- }.collect {
- tvResult.append("\n上传成功 : $it")
- }
- }
-
- /**
- * Android 10以下 或 下载文件到沙盒目录下,下载可以直接传入file的绝对路径
- *
- * 如不需要监听下载进度,toDownload 方法不要传进度回调即可
- */
- private suspend fun AwaitFragmentBinding.download(view: View) {
-// val destPath = "${requireContext().externalCacheDir}/${System.currentTimeMillis()}.apk"
-// RxHttp.get(Url.DOWNLOAD_URL)
-// .toDownloadAwait(destPath) {
-// val currentProgress = it.progress //当前进度 0-100
-// val currentSize = it.currentSize //当前已下载的字节大小
-// val totalSize = it.totalSize //要下载的总字节大小
-// tvResult.append(it.toString())
-// }.awaitResult {
-// tvResult.append("\n下载完成, $it")
-// }.onFailure {
-// //异常回调
-// tvResult.append("\n${it.errorMsg}")
-// it.show()
-// }
- }
-
- /**
- * 断点下载
- * Android 10以下 或 下载文件到沙盒目录下,下载可以直接传入file的绝对路径
- * 如不需要监听下载进度,toDownload 方法不要传进度回调即可
- */
- private suspend fun AwaitFragmentBinding.appendDownload(view: View) {
-// val destPath = "${requireContext().externalCacheDir}/Miaobo.apk"
-// RxHttp.get(Url.DOWNLOAD_URL)
-// .toDownloadAwait(destPath, true) {
-// val currentProgress = it.progress //当前进度 0-100
-// val currentSize = it.currentSize //当前已下载的字节大小
-// val totalSize = it.totalSize //要下载的总字节大小
-// tvResult.append(it.toString())
-// }.awaitResult {
-// tvResult.append("\n下载完成, $it")
-// }.onFailure {
-// //异常回调
-// tvResult.append("\n${it.errorMsg}")
-// it.show()
-// }
- }
-
- /**
- * Android 10 及以上下载,兼容Android 10以下
- * 如不需要监听下载进度,toDownload 方法不要传进度回调即可
- */
- private suspend fun AwaitFragmentBinding.downloadAndroid10(view: View) {
-// val factory = Android10DownloadFactory(requireContext(), "miaobo.apk")
-// RxHttp.get(Url.DOWNLOAD_URL)
-// .toDownloadAwait(factory) {
-// val currentProgress = it.progress //当前进度 0-100
-// val currentSize = it.currentSize //当前已下载的字节大小
-// val totalSize = it.totalSize //要下载的总字节大小
-// tvResult.append(it.toString())
-// }.awaitResult {
-// tvResult.append("\n下载完成, $it")
-// }.onFailure {
-// //异常回调
-// tvResult.append("\n${it.errorMsg}")
-// it.show()
-// }
- }
-
- /**
- * Android 10 及以上断点下载,兼容Android 10以下
- * 如不需要监听下载进度,toDownload 方法不要传进度回调即可
- */
- private suspend fun AwaitFragmentBinding.appendDownloadAndroid10(view: View) {
-// val factory = Android10DownloadFactory(requireContext(), "miaobo.apk")
-// RxHttp.get(Url.DOWNLOAD_URL)
-// .toDownloadAwait(factory, true) {
-// val currentProgress = it.progress //当前进度 0-100
-// val currentSize = it.currentSize //当前已下载的字节大小
-// val totalSize = it.totalSize //要下载的总字节大小
-// tvResult.append(it.toString())
-// }.awaitResult {
-// tvResult.append("\n下载完成, $it")
-// }.onFailure {
-// //异常回调
-// tvResult.append("\n${it.errorMsg}")
-// it.show()
-// }
- }
-
-
- private fun AwaitFragmentBinding.clearLog(view: View) {
- tvResult.text = ""
- tvResult.setBackgroundColor(Color.TRANSPARENT)
- }
-
- override fun onClick(v: View) {
- mBinding.run {
- lifecycleScope.launch {
- when (v.id) {
- R.id.sendGet -> sendGet(v)
- R.id.sendPostForm -> sendPostForm(v)
- R.id.sendPostJson -> sendPostJson(v)
- R.id.sendPostJsonArray -> sendPostJsonArray(v)
- R.id.xmlConverter -> xmlConverter(v)
- R.id.upload -> upload(v)
- R.id.upload10 -> uploadAndroid10(v)
- R.id.download -> download(v)
- R.id.download_append -> appendDownload(v)
- R.id.download10 -> downloadAndroid10(v)
- R.id.download10_append -> appendDownloadAndroid10(v)
- R.id.bt_clear -> clearLog(v)
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/fragment/BaseFragment.kt b/app/src/main/java/com/example/httpsender/fragment/BaseFragment.kt
deleted file mode 100644
index b5ef559c..00000000
--- a/app/src/main/java/com/example/httpsender/fragment/BaseFragment.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.example.httpsender.fragment
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.annotation.LayoutRes
-import androidx.databinding.DataBindingUtil
-import androidx.databinding.ViewDataBinding
-import androidx.fragment.app.Fragment
-
-/**
- * User: ljx
- * Date: 2020/6/2
- * Time: 11:45
- */
-abstract class BaseFragment : Fragment() {
-
- @LayoutRes
- private var layoutId = 0
- protected lateinit var mBinding: T
-
- fun setContentView(@LayoutRes layoutId: Int) {
- this.layoutId = layoutId
- }
-
- override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
- mBinding = DataBindingUtil.inflate(inflater, layoutId, container, false)
- return mBinding.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- mBinding.onViewCreated(savedInstanceState)
- }
-
- open fun T.onViewCreated(savedInstanceState: Bundle?) {
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/fragment/FlowFragment.kt b/app/src/main/java/com/example/httpsender/fragment/FlowFragment.kt
deleted file mode 100644
index 020aabdf..00000000
--- a/app/src/main/java/com/example/httpsender/fragment/FlowFragment.kt
+++ /dev/null
@@ -1,316 +0,0 @@
-package com.example.httpsender.fragment
-
-import android.graphics.Color
-import android.net.Uri
-import android.os.Bundle
-import android.view.View
-import androidx.lifecycle.lifecycleScope
-import com.example.httpsender.R
-import com.example.httpsender.databinding.FlowFragmentBinding
-import com.example.httpsender.entity.Article
-import com.example.httpsender.entity.Location
-import com.example.httpsender.entity.Name
-import com.example.httpsender.entity.NewsDataXml
-import com.example.httpsender.entity.PageList
-import com.example.httpsender.entity.Url
-import com.example.httpsender.kt.errorMsg
-import com.example.httpsender.kt.show
-import com.example.httpsender.parser.Android10DownloadFactory
-import com.google.gson.Gson
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.launch
-import rxhttp.toDownloadFlow
-import rxhttp.toFlow
-import rxhttp.wrapper.param.RxHttp
-import rxhttp.wrapper.param.toFlowResponse
-import java.io.File
-
-/**
- * 使用 协程(RxHttp + Flow) 发请求
- *
- * ```
- * RxHttp.postXxx("/service/...")
- * .add("key", "value")
- * .toFlow()
- * .catch {
- * val throwable = it
- * }.collect {
- * val user = it
- * }
- *```
- * User: ljx
- * Date: 2021/9/18
- * Time: 20:16
- */
-class FlowFragment : BaseFragment(), View.OnClickListener {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.flow_fragment)
- }
-
- override fun FlowFragmentBinding.onViewCreated(savedInstanceState: Bundle?) {
- click = this@FlowFragment
- }
-
- //发送Get请求,获取文章列表
- private suspend fun FlowFragmentBinding.sendGet(view: View) {
- RxHttp.get("/article/list/0/json")
- .toFlowResponse>()
- .catch {
- tvResult.text = it.errorMsg
- it.show()
- }.collect {
- tvResult.text = Gson().toJson(it)
- }
- }
-
- //发送Post表单请求,根据关键字查询文章
- private suspend fun FlowFragmentBinding.sendPostForm(view: View) {
- RxHttp.postForm("/article/query/0/json")
- .add("k", "性能优化")
- .toFlowResponse>()
- .catch {
- tvResult.text = it.errorMsg
- it.show()
- }.collect {
- tvResult.text = Gson().toJson(it)
- }
- }
-
- //发送Post Json请求,此接口不通,通过日志可以看到,发送出去的json对象
- private suspend fun FlowFragmentBinding.sendPostJson(view: View) {
- /*
- 发送以下User对象
- {"name":"张三","sex":1,"height":180,"weight":70,
- "interest":["羽毛球","游泳"],
- "location":{"latitude":30.7866,"longitude":120.6788},
- "address":{"street":"科技园路.","city":"江苏苏州","country":"中国"}}
- */
- val interestList: MutableList = ArrayList() //爱好
- interestList.add("羽毛球")
- interestList.add("游泳")
- val address = """
- {"street":"科技园路.","city":"江苏苏州","country":"中国"}
- """.trimIndent()
- RxHttp.postJson("/article/list/0/json")
- .add("name", "张三")
- .add("sex", 1)
- .addAll("""{"height":180,"weight":70}""") //通过addAll系列方法添加多个参数
- .add("interest", interestList) //添加数组对象
- .add("location", Location(120.6788, 30.7866)) //添加位置对象
- .addJsonElement("address", address) //通过字符串添加一个对象
- .toFlow()
- .catch {
- tvResult.text = it.errorMsg
- it.show()
- }.collect {
- tvResult.text = it
- }
- }
-
- //发送Post JsonArray请求,通过日志可以看到,发送出去的json数组
- private suspend fun FlowFragmentBinding.sendPostJsonArray(view: View) {
- /*
- 发送以下Json数组
- [{"name":"张三"},{"name":"李四"},{"name":"王五"},{"name":"赵六"},{"name":"杨七"}]
- */
- val names: MutableList = ArrayList()
- names.add(Name("赵六"))
- names.add(Name("杨七"))
- RxHttp.postJsonArray("/article/list/0/json")
- .add("name", "张三")
- .add(Name("李四"))
- .addJsonElement("""{"name":"王五"}""")
- .addAll(names)
- .toFlow()
- .catch {
- tvResult.text = it.errorMsg
- it.show()
- }.collect {
- tvResult.text = it
- }
-
- }
-
- //此接口不同,但通过日志可以看到,发送出去的是xml数据,如果收到也是xml数据,则会自动解析为我们指定的对象
- private suspend fun FlowFragmentBinding.xmlConverter(view: View) {
- RxHttp.postBody("http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni")
- .setBody(Name("张三"))
- .setXmlConverter()
- .toFlow()
- .catch {
- tvResult.text = it.errorMsg
- it.show()
- }.collect {
- tvResult.text = Gson().toJson(it)
- }
- }
-
- /**
- * android 10之前 或 沙盒目录(Android/data/packageName/)下的文件上传
- *
- * 如不需要监听进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun FlowFragmentBinding.upload(v: View) {
- RxHttp.postForm(Url.UPLOAD_URL)
- .addFile("file", File("xxxx/1.png"))
- .toFlow()
- .onProgress {
- //上传进度回调,0-100,仅在进度有更新时才会回调
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已上传的字节大小
- val totalSize = it.totalSize //要上传的总字节大小
- tvResult.append("\n$it")
- }.catch {
- tvResult.append("\n${it.errorMsg}")
- //失败回调
- it.show()
- }.collect {
- tvResult.append("\n上传成功 : $it")
- }
- }
-
- /**
- * android 10 及以上文件上传 ,兼容Android 10以下
- *
- * 如不需要监听进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun FlowFragmentBinding.uploadAndroid10(v: View) {
- //真实环境,需要调用文件选择器,拿到Uri对象
- val uri = Uri.parse("content://media/external/downloads/13417")
- RxHttp.postForm(Url.UPLOAD_URL)
- .addPart(requireContext(), "file", uri)
- .toFlow()
- .onProgress {
- //上传进度回调,0-100,仅在进度有更新时才会回调
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已上传的字节大小
- val totalSize = it.totalSize //要上传的总字节大小
- tvResult.append("\n$it")
- }.catch {
- tvResult.append("\n${it.errorMsg}")
- //失败回调
- it.show()
- }.collect {
- tvResult.append("\n上传成功 : $it")
- }
- }
-
- /**
- * Android 10以下 或 下载文件到沙盒目录下,下载可以直接传入file的绝对路径
- *
- * 如不需要监听下载进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun FlowFragmentBinding.download(view: View) {
- val destPath = "${requireContext().externalCacheDir}/${System.currentTimeMillis()}.apk"
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadFlow(destPath)
- .onProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }.catch {
- tvResult.append("\n${it.errorMsg}") //异常回调
- it.show()
- }.collect {
- tvResult.append("\n下载完成, $it")
- }
- }
-
- /**
- * 断点下载
- * Android 10以下 或 下载文件到沙盒目录下,下载可以直接传入file的绝对路径
- *
- * 如不需要监听下载进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun FlowFragmentBinding.appendDownload(view: View) {
- val destPath = "${requireContext().externalCacheDir}/Miaobo.apk"
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadFlow(destPath, true)
- .onProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }.catch {
- tvResult.append("\n${it.errorMsg}")
- it.show()
- }.collect {
- tvResult.append("\n下载完成, $it")
- }
- }
-
- /**
- * Android 10 及以上下载,兼容Android 10以下
- *
- * 如不需要监听下载进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun FlowFragmentBinding.downloadAndroid10(view: View) {
- val factory = Android10DownloadFactory(requireContext(), "miaobo.apk")
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadFlow(factory)
- .onProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }.catch {
- tvResult.append("\n${it.errorMsg}")
- it.show()
- }.collect {
- tvResult.append("\n下载完成, $it")
- }
- }
-
- /**
- * Android 10 及以上断点下载,兼容Android 10以下
- *
- * 如不需要监听下载进度,toFlow 方法不要传进度回调即可
- */
- private suspend fun FlowFragmentBinding.appendDownloadAndroid10(view: View) {
- val factory = Android10DownloadFactory(requireContext(), "miaobo.apk")
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadFlow(factory, true)
- .onProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }.catch {
- //异常回调
- tvResult.append("\n${it.errorMsg}")
- it.show()
- }.collect {
- tvResult.append("\n下载完成, $it")
- }
- }
-
-
- private fun FlowFragmentBinding.clearLog(view: View) {
- tvResult.text = ""
- tvResult.setBackgroundColor(Color.TRANSPARENT)
- }
-
- override fun onClick(v: View) {
- mBinding.run {
- lifecycleScope.launch {
- when (v.id) {
- R.id.sendGet -> sendGet(v)
- R.id.sendPostForm -> sendPostForm(v)
- R.id.sendPostJson -> sendPostJson(v)
- R.id.sendPostJsonArray -> sendPostJsonArray(v)
- R.id.xmlConverter -> xmlConverter(v)
- R.id.upload -> upload(v)
- R.id.upload10 -> uploadAndroid10(v)
- R.id.download -> download(v)
- R.id.download_append -> appendDownload(v)
- R.id.download10 -> downloadAndroid10(v)
- R.id.download10_append -> appendDownloadAndroid10(v)
- R.id.bt_clear -> clearLog(v)
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/fragment/MultiDownloadFragment.java b/app/src/main/java/com/example/httpsender/fragment/MultiDownloadFragment.java
deleted file mode 100644
index 18ce36ed..00000000
--- a/app/src/main/java/com/example/httpsender/fragment/MultiDownloadFragment.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.example.httpsender.fragment;
-
-import android.os.Bundle;
-import android.view.View;
-import android.view.View.OnClickListener;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.SimpleItemAnimator;
-
-import com.example.httpsender.DownloadMultiAdapter;
-import com.example.httpsender.DownloadMultiAdapter.OnItemClickListener;
-import com.example.httpsender.R;
-import com.example.httpsender.Tip;
-import com.example.httpsender.databinding.MultiDownloadFragmentBinding;
-import com.example.httpsender.entity.DownloadTask;
-import com.example.httpsender.vm.MultiTaskDownloader;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-
-/**
- * User: ljx
- * Date: 2021/9/25
- * Time: 18:08
- */
-public class MultiDownloadFragment extends BaseFragment implements OnItemClickListener, OnClickListener {
-
- private final String[] downloadUrl = {
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/uS12nZLR.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/BYGanTMW.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/Iu9hZLL8.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/DdKLk5VX.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/Byww5X8k.ts",
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?111",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?222",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?333",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?444",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?555",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?666",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?777",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?888",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?999",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?101",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?102",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?103",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?104",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?105",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?106",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?107",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk?108",//探探
- "https://apk-ssl.tancdn.com/3.5.3_276/%E6%8E%A2%E6%8E%A2.apk",//探探
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/OUkREagY.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/ZJUsgPSd.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/I5ivzoXR.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/PFPXapY7.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/tJj2JTVy.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/mj2fFYjH.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/MOXijkzw.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/uiwVyFej.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/HijAOXaK.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/h2mFS6ef.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/vf8fjmJd.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/0jsVXFSa.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/aZfnIVnP.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/l7cddTCQ.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/QaMi23d0.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/ljLywei6.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/FQpwzm4U.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/4oW2C2iZ.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/57OL3KeG.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/vYlV9nTw.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/XUmd5HWF.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/btVvEY5r.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/eJRKGoaP.ts",
-// "https://hnzy4.jinhaiwzhs.com:65/20210625/mndoRF1O/2000kb/hls/iz5kx1X1.ts",
- };
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.multi_download_fragment);
- }
-
- @Override
- public void onViewCreated(@NotNull MultiDownloadFragmentBinding binding, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(binding, savedInstanceState);
- binding.setClick(this);
- ArrayList allTask = new ArrayList<>(); //所有下载任务
- for (int i = 0; i < downloadUrl.length; i++) {
- String url = downloadUrl[i];
- DownloadTask task = new DownloadTask(url);
- String suffix = url.substring(url.lastIndexOf("."));
- task.setLocalPath(getContext().getExternalCacheDir() + "/" + i + suffix);
- allTask.add(task);
- }
- RecyclerView recyclerView = binding.recyclerView;
-
- MultiTaskDownloader.addTasks(allTask);
- DownloadMultiAdapter multiAdapter = new DownloadMultiAdapter(MultiTaskDownloader.getAllTask());
- multiAdapter.setOnItemClickListener(this);
- recyclerView.setAdapter(multiAdapter);
- ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
-
- MultiTaskDownloader.getLiveTask().observe(getViewLifecycleOwner(), task -> {
- int index = MultiTaskDownloader.getAllTask().indexOf(task);
- if (index != -1) {
- //任务有更新,刷新单个item
- multiAdapter.notifyItemChanged(index);
- }
- });
- }
-
- @Override
- public void onClick(View v) {
- int id = v.getId();
- if (id == R.id.start_all) {
- MultiTaskDownloader.startAllDownloadTask();
- } else if (id == R.id.cancel_all) {
- MultiTaskDownloader.cancelAllTask();
- }
- }
-
- @Override
- public void onItemClick(View view, DownloadTask task, int position) {
- if (view.getId() == R.id.bt_pause) {
- int curState = task.getState(); //任务当前状态
- if (curState == MultiTaskDownloader.IDLE //未开始->开始下载
- || curState == MultiTaskDownloader.PAUSED //暂停下载->继续下载
- || curState == MultiTaskDownloader.CANCEL //已取消->重新开始下载
- || curState == MultiTaskDownloader.FAIL //下载失败->重新下载
- ) {
- MultiTaskDownloader.download(task);
- } else if (curState == MultiTaskDownloader.WAITING) { //等待中->取消下载
- MultiTaskDownloader.removeWaitTask(task);
- } else if (curState == MultiTaskDownloader.DOWNLOADING) { //下载中->暂停下载
- MultiTaskDownloader.pauseTask(task);
- } else if (curState == MultiTaskDownloader.COMPLETED) { //任务已完成
- Tip.show("该任务已完成");
- }
- }
- }
-}
diff --git a/app/src/main/java/com/example/httpsender/fragment/RxJavaFragment.kt b/app/src/main/java/com/example/httpsender/fragment/RxJavaFragment.kt
deleted file mode 100644
index 7a7e79ee..00000000
--- a/app/src/main/java/com/example/httpsender/fragment/RxJavaFragment.kt
+++ /dev/null
@@ -1,355 +0,0 @@
-package com.example.httpsender.fragment
-
-import android.graphics.Color
-import android.net.Uri
-import android.os.Bundle
-import android.view.View
-import com.example.httpsender.R
-import com.example.httpsender.databinding.RxjavaFragmentBinding
-import com.example.httpsender.entity.Article
-import com.example.httpsender.entity.Location
-import com.example.httpsender.entity.Name
-import com.example.httpsender.entity.NewsDataXml
-import com.example.httpsender.entity.PageList
-import com.example.httpsender.entity.Url
-import com.example.httpsender.kt.errorMsg
-import com.example.httpsender.kt.show
-import com.example.httpsender.parser.Android10DownloadFactory
-import com.google.gson.Gson
-import com.rxjava.rxlife.life
-import com.rxjava.rxlife.lifeOnMain
-import rxhttp.wrapper.param.RxHttp
-import rxhttp.wrapper.param.toObservable
-import rxhttp.wrapper.param.toObservableResponse
-import java.io.File
-
-/**
- * 使用 RxHttp + RxJava 发请求
- *
- * ```
- * RxHttp.postXxx("/service/...")
- * .add("key", "value")
- * .toObservable()
- * .subscribe(user -> {
- *
- * }, throwable -> {
- *
- * })
- * ```
- * User: ljx
- * Date: 2020/4/24
- * Time: 18:16
- */
-class RxJavaFragment : BaseFragment(), View.OnClickListener {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.rxjava_fragment)
- }
-
- override fun RxjavaFragmentBinding.onViewCreated(savedInstanceState: Bundle?) {
- click = this@RxJavaFragment
- }
-
- //发送Get请求,获取文章列表
- fun RxjavaFragmentBinding.sendGet(view: View?) {
- RxHttp.get("/article/list/0/json")
- .addQuery("aa")
- .addQuery("bb","")
- .toObservableResponse>()
- .lifeOnMain(this@RxJavaFragment)
- .subscribe({
- tvResult.text = Gson().toJson(it)
- }, {
- tvResult.text = it.errorMsg
- it.show()
- })
- }
-
- //发送Post表单请求,根据关键字查询文章
- fun RxjavaFragmentBinding.sendPostForm(view: View?) {
- RxHttp.postForm("/article/query/0/json")
- .add("k", "性能优化")
- .toObservableResponse>()
- .lifeOnMain(this@RxJavaFragment) //感知生命周期,并在主线程回调
- .subscribe({
- tvResult.text = Gson().toJson(it)
- }, {
- tvResult.text = it.errorMsg
- it.show()
- })
- }
-
- //发送Post Json请求,此接口不通,通过日志可以看到,发送出去的json对象
- fun RxjavaFragmentBinding.sendPostJson(view: View?) {
- //发送以下User对象
- /*
- {
- "name": "张三",
- "sex": 1,
- "height": 180,
- "weight": 70,
- "interest": [
- "羽毛球",
- "游泳"
- ],
- "location": {
- "latitude": 30.7866,
- "longitude": 120.6788
- },
- "address": {
- "street": "科技园路.",
- "city": "江苏苏州",
- "country": "中国"
- }
- }
- */
- val interestList: MutableList = ArrayList() //爱好
- interestList.add("羽毛球")
- interestList.add("游泳")
- val address = "{\"street\":\"科技园路.\",\"city\":\"江苏苏州\",\"country\":\"中国\"}"
- RxHttp.postJson("/article/list/0/json")
- .add("name", "张三")
- .add("sex", 1)
- .addAll("{\"height\":180,\"weight\":70}") //通过addAll系列方法添加多个参数
- .add("interest", interestList) //添加数组对象
- .add("location", Location(120.6788, 30.7866)) //添加位置对象
- .addJsonElement("address", address) //通过字符串添加一个对象
- .toObservableString()
- .lifeOnMain(this@RxJavaFragment)//感知生命周期,并在主线程回调
- .subscribe({
- tvResult.text = it
- }, {
- tvResult.text = it.errorMsg
- it.show()
- })
- }
-
- //发送Post JsonArray请求,通过日志可以看到,发送出去的json数组
- fun RxjavaFragmentBinding.sendPostJsonArray(view: View?) {
- //发送以下Json数组
- /*
- [
- {
- "name": "张三"
- },
- {
- "name": "李四"
- },
- {
- "name": "王五"
- },
- {
- "name": "赵六"
- },
- {
- "name": "杨七"
- }
- ]
- */
- val names: MutableList = ArrayList()
- names.add(Name("赵六"))
- names.add(Name("杨七"))
- RxHttp.postJsonArray("/article/list/0/json")
- .add("name", "张三")
- .add(Name("李四"))
- .addJsonElement("{\"name\":\"王五\"}")
- .addAll(names)
- .toObservableString()
- .lifeOnMain(this@RxJavaFragment)
- .subscribe({
- tvResult.text = it
- }, {
- tvResult.text = it.errorMsg
- //失败回调
- it.show()
- })
- }
-
- //此接口不同,但通过日志可以看到,发送出去的是xml数据,如果收到也是xml数据,则会自动解析为我们指定的对象
- fun RxjavaFragmentBinding.xmlConverter(view: View?) {
- RxHttp.postBody("http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni")
- .setBody(Name("张三"))
- .setXmlConverter()
- .toObservable()
- .lifeOnMain(this@RxJavaFragment) //感知生命周期,并在主线程回调
- .subscribe({
- tvResult.text = Gson().toJson(it)
- }, {
- tvResult.text = it.errorMsg
- //失败回调
- it.show()
- })
- }
-
- /**
- * android 10之前 或 沙盒目录(Android/data/packageName/)下的文件上传,如不需要监听进度,注释掉 upload 方法即可
- */
- private fun RxjavaFragmentBinding.upload(v: View) {
- RxHttp.postForm(Url.UPLOAD_URL)
- .addFile("file", File("xxxx/1.png"))
- .toObservableString()
- .onMainProgress {
- //上传进度回调,0-100,仅在进度有更新时才会回调
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已上传的字节大小
- val totalSize = it.totalSize //要上传的总字节大小
- tvResult.append("\n$it")
- }
- .life(this@RxJavaFragment) //页面销毁,自动关闭请求
- .subscribe({
- tvResult.append("\n上传成功 : $it")
- }, {
- tvResult.append("\n${it.errorMsg}")
- it.show()
- })
- }
-
- /**
- * android 10 及以上文件上传 ,兼容Android 10以下,如不需要监听进度,注释掉 upload 方法即可
- */
- private fun RxjavaFragmentBinding.uploadAndroid10(v: View) {
- //真实环境,需要调用文件选择器,拿到Uri对象
- val uri = Uri.parse("content://media/external/downloads/13417")
- RxHttp.postForm(Url.UPLOAD_URL)
- .addPart(requireContext(), "file", uri)
- .toObservableString()
- .onMainProgress {
- //上传进度回调,0-100,仅在进度有更新时才会回调
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已上传的字节大小
- val totalSize = it.totalSize //要上传的总字节大小
- tvResult.append("\n$it")
- }
- .life(this@RxJavaFragment) //页面销毁,自动关闭请求
- .subscribe({
- tvResult.append("\n上传成功 : $it")
- }, {
- tvResult.append("\n${it.errorMsg}") //失败回调
- it.show()
- })
- }
-
-
- /**
- * Android 10以下 或 下载文件到沙盒目录下,下载可以直接传入file的绝对路径
- *
- * 如不需要监听下载进度,asDownload 方法不要传进度回调即可
- */
- private fun RxjavaFragmentBinding.download(view: View) {
- val destPath = "${requireContext().externalCacheDir}/${System.currentTimeMillis()}.apk"
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadObservable(destPath)
- .onMainProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }
- .life(this@RxJavaFragment) //感知生命周期,并在主线程回调
- .subscribe({
- tvResult.append("\n下载完成, $it")
- }, {
- //下载失败
- tvResult.append("\n${it.errorMsg}")
- it.show()
- })
- }
-
- /**
- * 断点下载
- * Android 10以下 或 下载文件到沙盒目录下,下载可以直接传入file的绝对路径
- * 如不需要监听下载进度,asAppendDownload 方法不要传进度回调即可
- */
- private fun RxjavaFragmentBinding.appendDownload(view: View) {
- val destPath = "${requireContext().externalCacheDir}/Miaobo.apk"
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadObservable(destPath, true)
- .onMainProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }
- .life(this@RxJavaFragment) //感知生命周期,并在主线程回调
- .subscribe({
- tvResult.append("\n下载完成, $it")
- }, {
- //下载失败
- tvResult.append("\n${it.errorMsg}")
- it.show()
- })
- }
-
-
- /**
- * Android 10 及以上下载,兼容Android 10以下
- * 如不需要监听下载进度,asDownload 方法不要传进度回调即可
- */
- private fun RxjavaFragmentBinding.downloadAndroid10(view: View) {
- val factory = Android10DownloadFactory(requireContext(), "miaobo.apk")
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadObservable(factory)
- .onMainProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }
- .life(this@RxJavaFragment) //感知生命周期,并在主线程回调
- .subscribe({
- tvResult.append("\n下载完成, $it")
- }, {
- //下载失败
- tvResult.append("\n${it.errorMsg}")
- it.show()
- })
- }
-
- /**
- * Android 10 及以上断点下载,兼容Android 10以下
- * 如不需要监听下载进度,asAppendDownload 方法不要传进度回调即可
- */
- private fun RxjavaFragmentBinding.appendDownloadAndroid10(view: View) {
- val factory = Android10DownloadFactory(requireContext(), "miaobo.apk")
- RxHttp.get(Url.DOWNLOAD_URL)
- .toDownloadObservable(factory, true)
- .onMainProgress {
- val currentProgress = it.progress //当前进度 0-100
- val currentSize = it.currentSize //当前已下载的字节大小
- val totalSize = it.totalSize //要下载的总字节大小
- tvResult.append("\n$it")
- }
- .life(this@RxJavaFragment) //感知生命周期,并在主线程回调
- .subscribe({
- tvResult.append("\n下载完成, $it")
- }, {
- //下载失败
- tvResult.append("\n${it.errorMsg}")
- it.show()
- })
- }
-
- private fun RxjavaFragmentBinding.clearLog(view: View?) {
- tvResult.text = ""
- tvResult.setBackgroundColor(Color.TRANSPARENT)
- }
-
- override fun onClick(v: View) {
- mBinding.apply {
- when (v.id) {
- R.id.sendGet -> sendGet(v)
- R.id.sendPostForm -> sendPostForm(v)
- R.id.sendPostJson -> sendPostJson(v)
- R.id.sendPostJsonArray -> sendPostJsonArray(v)
- R.id.xmlConverter -> xmlConverter(v)
- R.id.upload -> upload(v)
- R.id.upload10 -> uploadAndroid10(v)
- R.id.download -> download(v)
- R.id.download_append -> appendDownload(v)
- R.id.download10 -> downloadAndroid10(v)
- R.id.download10_append -> appendDownloadAndroid10(v)
- R.id.bt_clear -> clearLog(v)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/interceptor/TokenInterceptor.java b/app/src/main/java/com/example/httpsender/interceptor/TokenInterceptor.java
index db22d291..f8de52f7 100644
--- a/app/src/main/java/com/example/httpsender/interceptor/TokenInterceptor.java
+++ b/app/src/main/java/com/example/httpsender/interceptor/TokenInterceptor.java
@@ -3,15 +3,16 @@
import com.example.httpsender.entity.User;
-import org.jetbrains.annotations.NotNull;
-
import java.io.IOException;
-import java.util.concurrent.atomic.AtomicReference;
+import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.Request;
+import okhttp3.RequestBody;
import okhttp3.Response;
import rxhttp.wrapper.param.RxHttp;
+import rxhttp.wrapper.param.RxHttp$FormParam;
+import rxhttp.wrapper.parse.SimpleParser;
/**
* token 失效,自动刷新token,然后再次发送请求,用户无感知
@@ -21,49 +22,62 @@
*/
public class TokenInterceptor implements Interceptor {
- //保存刷新后的token
- private final AtomicReference atomicToken = new AtomicReference<>();
-
//token刷新时间
- @NotNull
+ private static volatile long SESSION_KEY_REFRESH_TIME = 0;
+
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response originalResponse = chain.proceed(request);
- String code = originalResponse.header("xxx"); //其中xxx,自己跟服务端协定
- if ("-1".equals(code)) { //token 失效 这里根据自己的业务需求写判断条件
- atomicToken.set(null);
+ String code = originalResponse.header("token_code");
+ if ("-1".equals(code)) { //token 失效 1、这里根据自己的业务需求写判断条件
return handleTokenInvalid(chain, request);
}
return originalResponse;
}
- //处理token失效问题, 同步刷新
+
+ //处理token失效问题
private Response handleTokenInvalid(Chain chain, Request request) throws IOException {
- boolean success = refreshToken();
+ RxHttp$FormParam rxHttp = RxHttp.postForm(request.url().toString()); //2、根据自己的业务修改
+ RequestBody body = request.body();
+ if (body instanceof FormBody) {
+ FormBody formBody = (FormBody) body;
+ for (int i = 0; i < formBody.size(); i++) {
+ rxHttp.add(formBody.name(i), formBody.value(i));
+ }
+ }
+ //同步刷新token
+ Object requestTime = rxHttp.queryValue("request_time"); //3、发请求前需要add("request_time",System.currentTimeMillis())
+ boolean success = refreshToken(requestTime);
Request newRequest;
- if (success) { //刷新成功,重新添加token
- newRequest = request.newBuilder()
- .header("xxx", atomicToken.get()) //其中xxx,自己跟服务端协定
- .build();
+ if (success) { //刷新成功,重新签名
+ rxHttp.add("token", User.get().getToken()); //拿到最新的token,重新发起请求 4、根据自己的业务修改
+ newRequest = rxHttp.buildRequest();
} else {
newRequest = request;
}
return chain.proceed(newRequest);
}
- //刷新token, 考虑到有并发情况,故这里需要加锁
- private boolean refreshToken() {
- //token不等于null,说明已经刷新
- if (atomicToken.get() != null) return true;
+ //刷新token
+ private boolean refreshToken(Object value) {
+ long requestTime = 0;
+ try {
+ requestTime = Integer.valueOf(value.toString());
+ } catch (Exception ignore) {
+ }
+ //请求时间小于token刷新时间,说明token已经刷新,则无需再次刷新
+ if (requestTime <= SESSION_KEY_REFRESH_TIME) return true;
synchronized (this) {
//再次判断是否已经刷新
- if (atomicToken.get() != null) return true;
+ if (requestTime <= SESSION_KEY_REFRESH_TIME) return true;
try {
- //根据自己业务,同步刷新token, 注意这里千万不能异步
+ //获取到最新的token,这里需要同步请求token,千万不能异步 5、根据自己的业务修改
String token = RxHttp.postForm("/refreshToken/...")
- .executeString();
- atomicToken.set(token);
+ .execute(SimpleParser.get(String.class));
+
+ SESSION_KEY_REFRESH_TIME = System.currentTimeMillis() / 1000;
User.get().setToken(token); //保存最新的token
return true;
} catch (IOException e) {
diff --git a/app/src/main/java/com/example/httpsender/kt/Activity.kt b/app/src/main/java/com/example/httpsender/kt/Activity.kt
deleted file mode 100644
index 91ee01c8..00000000
--- a/app/src/main/java/com/example/httpsender/kt/Activity.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.example.httpsender.kt
-
-import android.app.Activity
-import android.content.Intent
-import androidx.fragment.app.Fragment
-import kotlin.reflect.KClass
-
-/**
- * User: ljx
- * Date: 2020/5/15
- * Time: 16:33
- */
-
-fun Activity.startActivity(clazz: KClass, block: (Intent.() -> Unit)? = null) {
- val intent = Intent(this, clazz.java).apply {
- block?.invoke(this)
- }
- startActivity(intent)
-}
-
-fun Fragment.startActivity(clazz: KClass, block: (Intent.() -> Unit)? = null) {
- val intent = Intent(activity, clazz.java).apply {
- block?.invoke(this)
- }
- startActivity(intent)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/kt/KotlinExtensions.kt b/app/src/main/java/com/example/httpsender/kt/KotlinExtensions.kt
deleted file mode 100644
index 1dcb704b..00000000
--- a/app/src/main/java/com/example/httpsender/kt/KotlinExtensions.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.example.httpsender.kt
-
-import android.content.Context
-import android.net.ConnectivityManager
-import com.example.httpsender.AppHolder
-import com.example.httpsender.Tip
-import com.google.gson.JsonSyntaxException
-import kotlinx.coroutines.TimeoutCancellationException
-import rxhttp.wrapper.exception.HttpStatusCodeException
-import rxhttp.wrapper.exception.ParseException
-import java.net.ConnectException
-import java.net.SocketTimeoutException
-import java.net.UnknownHostException
-import java.util.concurrent.TimeoutException
-
-/**
- * User: ljx
- * Date: 2020-02-07
- * Time: 21:04
- */
-fun Throwable.show() {
- errorMsg.show()
-}
-
-fun String.show() {
- Tip.show(this)
-}
-
-val Throwable.errorCode: Int
- get() =
- when (this) {
- is HttpStatusCodeException -> this.statusCode //Http状态码异常
- is ParseException -> this.errorCode.toIntOrNull() ?: -1 //业务code异常
- else -> -1
- }
-
-val Throwable.errorMsg: String
- get() {
- return if (this is UnknownHostException) { //网络异常
- if (!isNetworkConnected(AppHolder.getInstance()))
- "当前无网络,请检查你的网络设置"
- else
- "网络连接不可用,请稍后重试!"
- } else if (
- this is SocketTimeoutException //okhttp全局设置超时
- || this is TimeoutException //rxjava中的timeout方法超时
- || this is TimeoutCancellationException //协程超时
- ) {
- "连接超时,请稍后再试"
- } else if (this is ConnectException) {
- "网络不给力,请稍候重试!"
- } else if (this is HttpStatusCodeException) { //请求失败异常
- "Http状态码异常 $message"
- } else if (this is JsonSyntaxException) { //请求成功,但Json语法异常,导致解析失败
- "数据解析失败,请检查数据是否正确"
- } else if (this is ParseException) { // ParseException异常表明请求成功,但是数据不正确
- this.message ?: errorCode //msg为空,显示code
- } else {
- message ?: this.toString()
- }
- }
-
-private fun isNetworkConnected(context: Context): Boolean {
- val mConnectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
- val mNetworkInfo = mConnectivityManager.activeNetworkInfo
- if (mNetworkInfo != null) {
- return mNetworkInfo.isAvailable
- }
- return false
-}
diff --git a/app/src/main/java/com/example/httpsender/kt/Uri.kt b/app/src/main/java/com/example/httpsender/kt/Uri.kt
deleted file mode 100644
index cfbb2721..00000000
--- a/app/src/main/java/com/example/httpsender/kt/Uri.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.example.httpsender.kt
-
-import android.content.Context
-import android.net.Uri
-import android.provider.MediaStore
-import android.util.Log
-
-/**
- * User: ljx
- * Date: 2020/9/24
- * Time: 15:33
- */
-
-fun Uri.dimQuery(context: Context, displayName: String) {
- context.contentResolver.query(this, null,
- "_display_name LIKE '%$displayName%'",null, null)?.use {
- while (it.moveToNext()) {
- val id = it.getString(it.getColumnIndex(MediaStore.MediaColumns._ID))
- val name = it.getString(it.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME))
- val data = it.getString(it.getColumnIndex(MediaStore.MediaColumns.DATA))
- //注意: 通过这种方式获取的文件size,在文件被手动删除后,读取到的是不准确的
- val size = it.getString(it.getColumnIndex(MediaStore.MediaColumns.SIZE))
- val dateAdded = it.getString(it.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED))
- val dateModified = it.getString(it.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED))
- Log.e("LJX", "id=$id size=$size name=$name data=$data dateAdded=$dateAdded dateModified=$dateModified")
- }
- }
-}
-
-fun Uri.dimDelete(context: Context, displayName: String) {
- val delete = context.contentResolver.delete(this, "_display_name LIKE '%$displayName%'", null)
- Log.e("LJX", "delete=$delete")
-}
-
-fun Uri.delete(context: Context, displayName: String) {
- val delete = context.contentResolver.delete(this, "_display_name=?", arrayOf(displayName))
- Log.e("LJX", "delete=$delete")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/param/GetEncryptParam.java b/app/src/main/java/com/example/httpsender/param/GetEncryptParam.java
index dd493ad9..6f93b9cb 100644
--- a/app/src/main/java/com/example/httpsender/param/GetEncryptParam.java
+++ b/app/src/main/java/com/example/httpsender/param/GetEncryptParam.java
@@ -1,19 +1,10 @@
package com.example.httpsender.param;
-import android.graphics.Point;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import okhttp3.HttpUrl;
import rxhttp.wrapper.annotation.Param;
-import rxhttp.wrapper.entity.KeyValuePair;
import rxhttp.wrapper.param.Method;
import rxhttp.wrapper.param.NoBodyParam;
/**
- * 加密get请求
* User: ljx
* Date: 2019-09-12
* Time: 17:25
@@ -25,25 +16,7 @@ public GetEncryptParam(String url) {
super(url, Method.GET);
}
- @SafeVarargs
- public final GetEncryptParam test(List a, Map map, T[]... b) throws IOException, IllegalArgumentException {
- return this;
- }
+ public void test(){
- @Override
- public HttpUrl getHttpUrl() {
- StringBuilder paramsBuilder = new StringBuilder(); //存储加密后的参数
- List queryParam = getQueryParam();
- if (queryParam != null) {
- for (KeyValuePair pair : getQueryParam()) {
- //这里遍历所有添加的参数,可对参数进行加密操作
- String key = pair.getKey();
- Object value = pair.getValue();
- //加密逻辑自己写
- }
- }
- String simpleUrl = getSimpleUrl(); //拿到请求Url
- if (paramsBuilder.length() == 0) return HttpUrl.get(simpleUrl);
- return HttpUrl.get(simpleUrl + "?" + paramsBuilder); //将加密后的参数和url组拼成HttpUrl对象并返回
}
}
diff --git a/app/src/main/java/com/example/httpsender/param/PostEncryptFormParam.java b/app/src/main/java/com/example/httpsender/param/PostEncryptFormParam.java
index eb6cf71b..e7addab1 100644
--- a/app/src/main/java/com/example/httpsender/param/PostEncryptFormParam.java
+++ b/app/src/main/java/com/example/httpsender/param/PostEncryptFormParam.java
@@ -18,8 +18,8 @@ public PostEncryptFormParam(String url) {
super(url, Method.POST);
}
- public PostEncryptFormParam(String url, Method method) {
- super(url, method);
+ public PostEncryptFormParam test() {
+ return this;
}
public PostEncryptFormParam test1(String s) {
diff --git a/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam.kt b/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam.kt
index 0e47913d..8e172589 100644
--- a/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam.kt
+++ b/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam.kt
@@ -1,10 +1,7 @@
package com.example.httpsender.param
-import okhttp3.MediaType
-import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
-import okhttp3.RequestBody.Companion.toRequestBody
import rxhttp.wrapper.annotation.Param
import rxhttp.wrapper.param.JsonParam
import rxhttp.wrapper.param.Method
@@ -18,18 +15,17 @@ import rxhttp.wrapper.utils.GsonUtil
@Param(methodName = "postEncryptJson")
class PostEncryptJsonParam(url: String) : JsonParam(url, Method.POST) {
- private var MEDIA_TYPE_JSON: MediaType = "application/json; charset=utf-8".toMediaType()
/**
* @return 根据自己的业务需求返回对应的RequestBody
*/
override fun getRequestBody(): RequestBody {
//我们要发送Post请求,参数以加密后的json形式发出
//第一步,将参数转换为Json字符串
- val json = if (bodyParam == null) "" else GsonUtil.toJson(bodyParam)
+ val json = if (params == null) "" else GsonUtil.toJson(params)
//第二步,加密
val encryptByte = encrypt(json, "RxHttp")
//第三部,创建RequestBody并返回
- return encryptByte!!.toRequestBody(MEDIA_TYPE_JSON)
+ return RequestBody.create(MEDIA_TYPE_JSON, encryptByte!!)
}
/**
diff --git a/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam1.java b/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam1.java
index cc9c0066..7777239f 100644
--- a/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam1.java
+++ b/app/src/main/java/com/example/httpsender/param/PostEncryptJsonParam1.java
@@ -1,8 +1,9 @@
package com.example.httpsender.param;
+import okhttp3.Request;
import okhttp3.RequestBody;
import rxhttp.wrapper.annotation.Param;
-import rxhttp.wrapper.param.AbstractBodyParam;
+import rxhttp.wrapper.param.AbstractParam;
import rxhttp.wrapper.param.Method;
/**
@@ -11,18 +12,23 @@
* Time: 11:52
*/
@Param(methodName = "postEncryptJson1")
-public class PostEncryptJsonParam1 extends AbstractBodyParam {
+public class PostEncryptJsonParam1 extends AbstractParam {
public PostEncryptJsonParam1(String url) {
super(url, Method.POST);
}
+ @Override
+ public Request buildRequest() {
+ return null;
+ }
+
@Override
public RequestBody getRequestBody() {
return null;
}
- public void test() {
+ public void test(){
}
diff --git a/app/src/main/java/com/example/httpsender/parser/Android10DownloadFactory.kt b/app/src/main/java/com/example/httpsender/parser/Android10DownloadFactory.kt
deleted file mode 100644
index 45143ad6..00000000
--- a/app/src/main/java/com/example/httpsender/parser/Android10DownloadFactory.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.example.httpsender.parser
-
-import android.content.ContentValues
-import android.content.Context
-import android.net.Uri
-import android.os.Build
-import android.os.Environment
-import android.provider.MediaStore
-import androidx.annotation.RequiresApi
-import okhttp3.Response
-import rxhttp.wrapper.callback.UriFactory
-import rxhttp.wrapper.utils.query
-import java.io.File
-
-/**
- * User: ljx
- * Date: 2020/9/11
- * Time: 17:43
- *
- * @param context Context
- * @param filename 文件名
- * @param relativePath 文件相对路径,可取值:
- * [Environment.DIRECTORY_DOWNLOADS]
- * [Environment.DIRECTORY_DCIM]
- * [Environment.DIRECTORY_PICTURES]
- * [Environment.DIRECTORY_MUSIC]
- * [Environment.DIRECTORY_MOVIES]
- * [Environment.DIRECTORY_DOCUMENTS]
- * ...
- */
-class Android10DownloadFactory @JvmOverloads constructor(
- context: Context,
- private val filename: String,
- private val relativePath: String = Environment.DIRECTORY_DOWNLOADS
-) : UriFactory(context) {
-
- /**
- * [MediaStore.Files.getContentUri]
- * [MediaStore.Downloads.EXTERNAL_CONTENT_URI]
- * [MediaStore.Audio.Media.EXTERNAL_CONTENT_URI]
- * [MediaStore.Video.Media.EXTERNAL_CONTENT_URI]
- * [MediaStore.Images.Media.EXTERNAL_CONTENT_URI]
- */
- @RequiresApi(Build.VERSION_CODES.Q)
- fun getInsertUri() = MediaStore.Downloads.EXTERNAL_CONTENT_URI
-
- override fun query(): Uri? {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- getInsertUri().query(context, filename, relativePath)
- } else {
- val file = File("${Environment.getExternalStorageDirectory()}/$relativePath/$filename")
- Uri.fromFile(file)
- }
- }
-
- override fun insert(response: Response): Uri {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- val uri = getInsertUri().query(context, filename, relativePath)
- /*
- * 通过查找,要插入的Uri已经存在,就无需再次插入
- * 否则会出现新插入的文件,文件名被系统更改的现象,因为insert不会执行覆盖操作
- */
- if (uri != null) return uri
- ContentValues().run {
- put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath) //下载到指定目录
- put(MediaStore.MediaColumns.DISPLAY_NAME, filename) //文件名
- //取contentType响应头作为文件类型
- put(MediaStore.MediaColumns.MIME_TYPE, response.body?.contentType().toString())
- context.contentResolver.insert(getInsertUri(), this)
- //当相同路径下的文件,在文件管理器中被手动删除时,就会插入失败
- } ?: throw NullPointerException("Uri insert failed. Try changing filename")
- } else {
- val file = File("${Environment.getExternalStorageDirectory()}/$relativePath/$filename")
- Uri.fromFile(file)
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/parser/ResponseListParser.java b/app/src/main/java/com/example/httpsender/parser/ResponseListParser.java
new file mode 100644
index 00000000..e92e78bc
--- /dev/null
+++ b/app/src/main/java/com/example/httpsender/parser/ResponseListParser.java
@@ -0,0 +1,42 @@
+package com.example.httpsender.parser;
+
+
+import com.example.httpsender.entity.Response;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import rxhttp.wrapper.annotation.Parser;
+import rxhttp.wrapper.entity.ParameterizedTypeImpl;
+import rxhttp.wrapper.exception.ParseException;
+import rxhttp.wrapper.parse.AbstractParser;
+
+/**
+ * Response> 数据解析器,解析完成对Response对象做判断,如果ok,返回数据 List
+ * User: ljx
+ * Date: 2018/10/23
+ * Time: 13:49
+ */
+@Parser(name = "ResponseList")
+public class ResponseListParser extends AbstractParser> {
+
+ protected ResponseListParser() {
+ super();
+ }
+
+ public ResponseListParser(Class type) {
+ super(type);
+ }
+
+ @Override
+ public List onParse(okhttp3.Response response) throws IOException {
+ final Type type = ParameterizedTypeImpl.get(Response.class, List.class, mType); //获取泛型类型
+ Response> data = convert(response, type);
+ List list = data.getData(); //获取data字段
+ if (data.getCode() != 0 || list == null) { //code不等于0,说明数据不正确,抛出异常
+ throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);
+ }
+ return list;
+ }
+}
diff --git a/app/src/main/java/com/example/httpsender/parser/ResponsePageListParser.java b/app/src/main/java/com/example/httpsender/parser/ResponsePageListParser.java
new file mode 100644
index 00000000..5b52016a
--- /dev/null
+++ b/app/src/main/java/com/example/httpsender/parser/ResponsePageListParser.java
@@ -0,0 +1,42 @@
+package com.example.httpsender.parser;
+
+
+import com.example.httpsender.entity.PageList;
+import com.example.httpsender.entity.Response;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+import rxhttp.wrapper.annotation.Parser;
+import rxhttp.wrapper.entity.ParameterizedTypeImpl;
+import rxhttp.wrapper.exception.ParseException;
+import rxhttp.wrapper.parse.AbstractParser;
+
+/**
+ * Response> 数据解析器,解析完成对Response对象做判断,如果ok,返回数据 PageList
+ * User: ljx
+ * Date: 2018/10/23
+ * Time: 13:49
+ */
+@Parser(name = "ResponsePageList")
+public class ResponsePageListParser extends AbstractParser> {
+
+ protected ResponsePageListParser() {
+ super();
+ }
+
+ public ResponsePageListParser(Class type) {
+ super(type);
+ }
+
+ @Override
+ public PageList onParse(okhttp3.Response response) throws IOException {
+ final Type type = ParameterizedTypeImpl.get(Response.class, PageList.class, mType); //获取泛型类型
+ Response> data = convert(response, type);
+ PageList pageList = data.getData(); //获取data字段
+ if (data.getCode() != 0 || pageList == null) { //code不等于0,说明数据不正确,抛出异常
+ throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);
+ }
+ return pageList;
+ }
+}
diff --git a/app/src/main/java/com/example/httpsender/parser/ResponseParser.java b/app/src/main/java/com/example/httpsender/parser/ResponseParser.java
new file mode 100644
index 00000000..e3ed913f
--- /dev/null
+++ b/app/src/main/java/com/example/httpsender/parser/ResponseParser.java
@@ -0,0 +1,50 @@
+package com.example.httpsender.parser;
+
+
+import com.example.httpsender.entity.Response;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+import rxhttp.wrapper.annotation.Parser;
+import rxhttp.wrapper.entity.ParameterizedTypeImpl;
+import rxhttp.wrapper.exception.ParseException;
+import rxhttp.wrapper.parse.AbstractParser;
+
+/**
+ * Response 数据解析器,解析完成对Response对象做判断,如果ok,返回数据 T
+ * User: ljx
+ * Date: 2018/10/23
+ * Time: 13:49
+ */
+@Parser(name = "Response")
+public class ResponseParser extends AbstractParser {
+
+ protected ResponseParser() {
+ super();
+ }
+
+ public ResponseParser(Class type) {
+ super(type);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T onParse(okhttp3.Response response) throws IOException {
+ final Type type = ParameterizedTypeImpl.get(Response.class, mType); //获取泛型类型
+ Response data = convert(response, type);
+ T t = data.getData(); //获取data字段
+ if (t == null && mType == String.class) {
+ /*
+ * 考虑到有些时候服务端会返回:{"errorCode":0,"errorMsg":"关注成功"} 类似没有data的数据
+ * 此时code正确,但是data字段为空,直接返回data的话,会报空指针错误,
+ * 所以,判断泛型为String类型时,重新赋值,并确保赋值不为null
+ */
+ t = (T) data.getMsg();
+ }
+ if (data.getCode() != 0 || t == null) {//code不等于0,说明数据不正确,抛出异常
+ throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);
+ }
+ return t;
+ }
+}
diff --git a/app/src/main/java/com/example/httpsender/parser/ResponseParser.kt b/app/src/main/java/com/example/httpsender/parser/ResponseParser.kt
deleted file mode 100644
index fc8664b4..00000000
--- a/app/src/main/java/com/example/httpsender/parser/ResponseParser.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.example.httpsender.parser
-
-import com.example.httpsender.entity.PageList
-import com.example.httpsender.entity.Response
-import rxhttp.wrapper.annotation.Parser
-import rxhttp.wrapper.exception.ParseException
-import rxhttp.wrapper.parse.TypeParser
-import rxhttp.wrapper.utils.convertTo
-import java.io.IOException
-import java.lang.reflect.Type
-
-/**
- * 输入T,输出T,并对code统一判断
- * User: ljx
- * Date: 2018/10/23
- * Time: 13:49
- *
- * 如果使用协程发送请求,wrappers属性可不设置,设置了也无效
- */
-@Parser(name = "Response", wrappers = [PageList::class])
-open class ResponseParser : TypeParser {
- /**
- * 此构造方法可适用任意Class对象,但更多用于带泛型的Class对象,如:List>>
- *
- * 如Java环境中调用
- * toObservable(new ResponseParser>>(){})
- * 等价于kotlin环境下的
- * toObservableResponse>>()
- *
- * 注:此构造方法一定要用protected关键字修饰,否则调用此构造方法将拿不到泛型类型
- */
- protected constructor() : super()
-
- /**
- * 该解析器会生成以下系列方法,前3个kotlin环境调用,后4个Java环境调用,所有方法内部均会调用本构造方法
- * toFlowResponse()
- * toAwaitResponse()
- * toObservableResponse()
- * toObservableResponse(Type)
- * toObservableResponse(Class)
- * toObservableResponseList(Class)
- * toObservableResponsePageList(Class)
- *
- * Flow/Await下 toXxxResponse> 等同于 toObservableResponsePageList(Class)
- */
- constructor(type: Type) : super(type)
-
- @Throws(IOException::class)
- override fun onParse(response: okhttp3.Response): T {
- val data: Response = response.convertTo(Response::class, *types)
- var t = data.data //获取data字段
- if (t == null && types[0] === String::class.java) {
- /*
- * 考虑到有些时候服务端会返回:{"errorCode":0,"errorMsg":"关注成功"} 类似没有data的数据
- * 此时code正确,但是data字段为空,直接返回data的话,会报空指针错误,
- * 所以,判断泛型为String类型时,重新赋值,并确保赋值不为null
- */
- @Suppress("UNCHECKED_CAST")
- t = data.msg as T
- }
- if (data.code != 0 || t == null) { //code不等于0,说明数据不正确,抛出异常
- throw ParseException(data.code.toString(), data.msg, response)
- }
- return t
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/httpsender/parser/java/DoubleTypeParser.java b/app/src/main/java/com/example/httpsender/parser/java/DoubleTypeParser.java
deleted file mode 100644
index 90b69c72..00000000
--- a/app/src/main/java/com/example/httpsender/parser/java/DoubleTypeParser.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.example.httpsender.parser.java;
-
-import android.util.Pair;
-
-import com.example.httpsender.entity.Response;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-import java.lang.reflect.Type;
-
-import rxhttp.wrapper.entity.ParameterizedTypeImpl;
-import rxhttp.wrapper.exception.ParseException;
-import rxhttp.wrapper.parse.TypeParser;
-import rxhttp.wrapper.utils.Converter;
-
-/**
- * 大于等于2个泛型的解析器,可以参考此类
- * User: ljx
- * Date: 2018/10/23
- * Time: 13:49
- */
-//@Parser(name = "DoubleType")
-public class DoubleTypeParser extends TypeParser> {
-
- protected DoubleTypeParser() {
- super();
- }
-
- public DoubleTypeParser(Type fType, Type sType) {
- super(fType, sType);
- }
-
- @Override
- public Pair onParse(@NotNull okhttp3.Response response) throws IOException {
- Type pairType = ParameterizedTypeImpl.getParameterized(Pair.class, types);
- Response> data = Converter.convertTo(response, Response.class, pairType);
- Pair t = data.getData(); //获取data字段
- if (data.getCode() != 0 || t == null) {//code不等于0,说明数据不正确,抛出异常
- throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);
- }
- return t;
- }
-}
diff --git a/app/src/main/java/com/example/httpsender/parser/java/ResponseParser.java b/app/src/main/java/com/example/httpsender/parser/java/ResponseParser.java
deleted file mode 100644
index 9b467f76..00000000
--- a/app/src/main/java/com/example/httpsender/parser/java/ResponseParser.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.example.httpsender.parser.java;
-
-import com.example.httpsender.entity.Response;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-import java.lang.reflect.Type;
-
-import rxhttp.wrapper.exception.ParseException;
-import rxhttp.wrapper.parse.TypeParser;
-import rxhttp.wrapper.utils.Converter;
-
-/**
- * 输入T,输出T,并对code统一判断
- * User: ljx
- * Date: 2018/10/23
- * Time: 13:49
- */
-//@Parser(name = "Response", wrappers = {PageList.class})
-public class ResponseParser extends TypeParser {
-
- /**
- * 此构造方法可适用任意Class对象,但更多用于带泛型的Class对象,如:List>>
- *