parent
9bdb30e28f
commit
d751ec6c6d
|
|
@ -245,7 +245,6 @@ class MainActivity : ComponentActivity(), LoadingCallback {
|
||||||
//资源下载进度
|
//资源下载进度
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
progressWGTToPageState.floatValue = progress
|
progressWGTToPageState.floatValue = progress
|
||||||
Log.i("HomeScreen", "DOWNLOAD_PROGRESS:$progress")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,6 @@ fun TipsUniMpDialog(
|
||||||
//资源下载进度
|
//资源下载进度
|
||||||
if(progress != null){
|
if(progress != null){
|
||||||
downProgress.value = progress
|
downProgress.value = progress
|
||||||
Log.i("HomeScreen","DOWNLOAD_PROGRESS:$progress")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,84 +4,47 @@ import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import okhttp3.Headers.Companion.toHeaders
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.concurrent.CancellationException
|
import java.util.concurrent.CancellationException
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
class DownUtils private constructor() {
|
class DownUtils private constructor() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "DownLoadUtils"
|
private const val TAG = "DownUtils"
|
||||||
private val downLoadHttpUtils: DownUtils by lazy {
|
private val _instance: DownUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||||
DownUtils()
|
DownUtils()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Synchronized
|
fun getInstance(): DownUtils = _instance
|
||||||
fun getInstance(): DownUtils {
|
|
||||||
return downLoadHttpUtils
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var downloadSizeInfo = mutableMapOf<String, Long>()
|
// 1. 线程安全集合:防止并发修改异常
|
||||||
private var cancelledList = mutableListOf<String>()
|
private val downloadSizeInfo = ConcurrentHashMap<String, Long>()
|
||||||
|
private val cancelledList = CopyOnWriteArrayList<String>()
|
||||||
|
|
||||||
private var buffSize = 4096//建议设置为2048
|
// 2. 常驻 Handler:解决 runOnUiThread 随机崩溃
|
||||||
fun setBuffSize(size: Int): DownUtils {
|
private val mainHandler = Handler(Looper.getMainLooper())
|
||||||
this.buffSize = size
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private var interceptor: Interceptor? = null
|
|
||||||
fun setInterceptor(interceptor: Interceptor?): DownUtils {
|
|
||||||
this.interceptor = interceptor
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private var buffSize = 8192
|
||||||
private var readTimeOut = 30L
|
private var readTimeOut = 30L
|
||||||
fun setReadTImeOut(read: Long): DownUtils {
|
|
||||||
this.readTimeOut = read
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private var writeTimeout = 30L
|
private var writeTimeout = 30L
|
||||||
fun setWriteTimeOut(write: Long): DownUtils {
|
|
||||||
this.writeTimeout = write
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private var connectTimeout = 30L
|
private var connectTimeout = 30L
|
||||||
fun setConnectTimeOut(connect: Long): DownUtils {
|
private var interceptor: Interceptor? = null
|
||||||
this.connectTimeout = connect
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
var filePath = ""
|
|
||||||
fun setFilePath(path: String): DownUtils {
|
|
||||||
this.filePath = path
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 任务参数
|
||||||
|
private var filePath = ""
|
||||||
private var fileName = ""
|
private var fileName = ""
|
||||||
fun setFileName(name: String): DownUtils {
|
private var deleteWhenException = false
|
||||||
this.fileName = name
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private var deleteWhenException = true
|
|
||||||
fun setDeleteWhenException(dele: Boolean): DownUtils {
|
|
||||||
this.deleteWhenException = dele
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private val requestBuilder: Request.Builder = Request.Builder()
|
|
||||||
private var urlBuilder: HttpUrl.Builder? = null
|
private var urlBuilder: HttpUrl.Builder? = null
|
||||||
|
private val headers = mutableMapOf<String, String>()
|
||||||
|
|
||||||
private val okHttpClient = lazy {
|
private val okHttpClient: OkHttpClient by lazy {
|
||||||
OkHttpClient.Builder()
|
OkHttpClient.Builder()
|
||||||
.readTimeout(readTimeOut, TimeUnit.SECONDS)
|
.readTimeout(readTimeOut, TimeUnit.SECONDS)
|
||||||
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
|
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
|
||||||
|
|
@ -89,289 +52,199 @@ class DownUtils private constructor() {
|
||||||
.addInterceptor(interceptor ?: LoggingInterceptor())
|
.addInterceptor(interceptor ?: LoggingInterceptor())
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
private var actionGetTotal: (total: Long) -> Unit? = { _ -> }
|
|
||||||
private var actionProgress: (position: Long) -> Unit? = { _ -> }
|
private var actionGetTotal: (total: Long) -> Unit = {}
|
||||||
private var actionSuccess: (file: File) -> Unit? = { _ -> }
|
private var actionProgress: (position: Long) -> Unit = {}
|
||||||
private var actionCancel: () -> Unit? = { }
|
private var actionSuccess: (file: File) -> Unit = {}
|
||||||
private var actionFail: (msg: String) -> Unit? = { _ -> }
|
private var actionCancel: () -> Unit = {}
|
||||||
|
private var actionFail: (msg: String) -> Unit = {}
|
||||||
|
private var downCallBack: DownCallBack? = null
|
||||||
|
|
||||||
|
// --- 配置方法 ---
|
||||||
|
|
||||||
|
fun setBuffSize(size: Int): DownUtils { this.buffSize = size; return this }
|
||||||
|
fun setFilePath(path: String): DownUtils { this.filePath = path; return this }
|
||||||
|
fun setFileName(name: String): DownUtils { this.fileName = name; return this }
|
||||||
|
fun initUrl(url: String, params: Map<String, String>? = null): DownUtils {
|
||||||
|
urlBuilder = url.toHttpUrlOrNull()?.newBuilder()
|
||||||
|
params?.forEach { (k, v) -> urlBuilder?.setQueryParameter(k, v) }
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
fun addHeader(map: Map<String, String>): DownUtils { this.headers.putAll(map); return this }
|
||||||
|
|
||||||
fun setActionCallBack(
|
fun setActionCallBack(
|
||||||
actionGetTotal: (total: Long) -> Unit,
|
getTotal: (Long) -> Unit,
|
||||||
actionProgress: (position: Long) -> Unit,
|
progress: (Long) -> Unit,
|
||||||
actionSuccess: (file: File) -> Unit,
|
success: (File) -> Unit,
|
||||||
actionFail: (msg: String) -> Unit,
|
fail: (String) -> Unit
|
||||||
): DownUtils {
|
): DownUtils {
|
||||||
this.actionGetTotal = actionGetTotal
|
this.actionGetTotal = getTotal
|
||||||
this.actionProgress = actionProgress
|
this.actionProgress = progress
|
||||||
this.actionSuccess = actionSuccess
|
this.actionSuccess = success
|
||||||
this.actionFail = actionFail
|
this.actionFail = fail
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private var downCallBack: DownCallBack? = null
|
|
||||||
fun setDownCallBack(callBack: DownCallBack): DownUtils {
|
fun setDownCallBack(callBack: DownCallBack): DownUtils {
|
||||||
this.downCallBack = callBack
|
this.downCallBack = callBack
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initUrl(url: String, params: Map<String, String>?): DownUtils {
|
|
||||||
urlBuilder = url.toHttpUrlOrNull()?.newBuilder()
|
|
||||||
if (params.isNullOrEmpty()) {
|
|
||||||
return this
|
|
||||||
} else {
|
|
||||||
for ((k, v) in params) {
|
|
||||||
checkName(k)
|
|
||||||
urlBuilder?.setQueryParameter(k, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addHeader(map: Map<String, String>): DownUtils {
|
|
||||||
requestBuilder.headers(map.toHeaders())
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkName(name: String) {
|
|
||||||
require(name.isNotEmpty()) { "name is empty" }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun down() {
|
fun down() {
|
||||||
if (urlBuilder == null) {
|
val url = urlBuilder?.build() ?: throw IllegalStateException("URL not initialized")
|
||||||
throw IllegalStateException("url not init")
|
doDown(url)
|
||||||
} else {
|
|
||||||
doDown()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doDown() {
|
private fun doDown(url: HttpUrl) {
|
||||||
val startTime = System.currentTimeMillis()
|
val tag = filePath + fileName
|
||||||
Log.i(TAG, "startTime=$startTime")
|
if (isDowning(tag)) return
|
||||||
val url = urlBuilder?.build()
|
|
||||||
if (url == null) {
|
|
||||||
doException("url is null")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (isDowning(filePath + fileName)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cancelledList.remove(fileName)
|
cancelledList.remove(fileName)
|
||||||
|
|
||||||
val currentLen = downloadSizeInfo[fileName] ?: 0L
|
// 3. 状态恢复:读取上次进度
|
||||||
if (isCanContinueDownload(url.toUrl(), currentLen)) {
|
var currentLen = downloadSizeInfo[fileName] ?: 0L
|
||||||
requestBuilder.removeHeader("RANGE")
|
|
||||||
requestBuilder.addHeader("RANGE", "bytes=${currentLen}-")
|
|
||||||
}
|
|
||||||
val request = requestBuilder.url(url).tag(filePath + fileName).build()
|
|
||||||
|
|
||||||
var `is`: InputStream? = null
|
// 校验:如果上次进度不为0,验证服务器是否支持断点续传
|
||||||
|
if (currentLen > 0) {
|
||||||
|
if (!isCanContinueDownload(url.toUrl(), currentLen)) {
|
||||||
|
currentLen = 0L // 不支持续传则重置
|
||||||
|
downloadSizeInfo[fileName] = 0L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.apply {
|
||||||
|
headers.forEach { (k, v) -> addHeader(k, v) }
|
||||||
|
if (currentLen > 0) addHeader("RANGE", "bytes=$currentLen-")
|
||||||
|
}
|
||||||
|
.tag(tag)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
var inputStream: InputStream? = null
|
||||||
var raf: RandomAccessFile? = null
|
var raf: RandomAccessFile? = null
|
||||||
var file: File? = null
|
var file: File? = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val response = okHttpClient.value.newCall(request).execute()
|
val response = okHttpClient.newCall(request).execute()
|
||||||
val total = response.body.contentLength()
|
if (!response.isSuccessful) throw IOException("Unexpected code $response")
|
||||||
|
|
||||||
|
val body = response.body
|
||||||
|
val total = body.contentLength()
|
||||||
doGetTotal(currentLen + total)
|
doGetTotal(currentLen + total)
|
||||||
|
|
||||||
|
val fileDir = File(filePath)
|
||||||
|
if (!fileDir.exists()) fileDir.mkdirs()
|
||||||
|
file = File(fileDir, fileName)
|
||||||
|
|
||||||
|
inputStream = body.byteStream()
|
||||||
|
raf = RandomAccessFile(file, "rw")
|
||||||
|
|
||||||
|
// 4. 只有响应码为 206 时才 seek,否则强制重置到文件开头
|
||||||
|
if (response.code == 206) {
|
||||||
|
raf.seek(currentLen)
|
||||||
|
} else {
|
||||||
|
raf.seek(0)
|
||||||
|
currentLen = 0
|
||||||
|
}
|
||||||
|
|
||||||
val buf = ByteArray(buffSize)
|
val buf = ByteArray(buffSize)
|
||||||
var len: Int
|
var len: Int
|
||||||
|
var sum = currentLen
|
||||||
|
var lastUpdateTime = 0L
|
||||||
|
|
||||||
file = if (fileName.isEmpty()) {
|
while (inputStream.read(buf).also { len = it } != -1) {
|
||||||
File(filePath)
|
|
||||||
} else {
|
|
||||||
val fileDir = File(filePath)
|
|
||||||
if (!fileDir.exists() || !fileDir.isDirectory) {
|
|
||||||
fileDir.mkdirs()
|
|
||||||
}
|
|
||||||
File(filePath, fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
`is` = response.body.byteStream()
|
|
||||||
raf = RandomAccessFile(file, "rw")
|
|
||||||
raf.seek(currentLen)
|
|
||||||
|
|
||||||
var sum: Long = currentLen
|
|
||||||
while (`is`.read(buf).also { len = it } != -1) {
|
|
||||||
if (isCancelled()) throw CancellationException()
|
if (isCancelled()) throw CancellationException()
|
||||||
raf.write(buf, 0, len)
|
raf.write(buf, 0, len)
|
||||||
sum += len.toLong()
|
sum += len
|
||||||
downloadSizeInfo[fileName] = sum
|
downloadSizeInfo[fileName] = sum
|
||||||
|
|
||||||
|
// 5. 性能节流:限制 UI 刷新频率(每100ms一次)
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
if (now - lastUpdateTime > 100L || sum == currentLen + total) {
|
||||||
doProgress(sum)
|
doProgress(sum)
|
||||||
|
lastUpdateTime = now
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Log.e(TAG, "download success")
|
|
||||||
|
|
||||||
if (!file.exists()) {
|
if (file.exists()) {
|
||||||
throw FileNotFoundException("file create err,not exists")
|
|
||||||
} else {
|
|
||||||
doSuccess(file)
|
doSuccess(file)
|
||||||
|
// 6. 状态清理:成功后移除进度,防止下次下载“续传”到已完成文件的末尾
|
||||||
|
downloadSizeInfo.remove(fileName)
|
||||||
}
|
}
|
||||||
Log.e(TAG, "totalTime=" + (System.currentTimeMillis() - startTime))
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (deleteWhenException && file?.exists() == true) file.delete()
|
Log.e(TAG, "Download failed: ${e.message}")
|
||||||
Log.e(TAG, "download failed : " + e.message)
|
if (e !is CancellationException) {
|
||||||
doException(e.message.toString())
|
if (deleteWhenException) file?.delete()
|
||||||
|
doException(e.message ?: "Unknown error")
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
inputStream?.close()
|
||||||
`is`?.close()
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
raf?.close()
|
raf?.close()
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCanContinueDownload(url: URL, start: Long): Boolean { //是否支持断点下载
|
private fun isCanContinueDownload(url: URL, start: Long): Boolean {
|
||||||
val requestBuilder = Request.Builder()
|
return try {
|
||||||
requestBuilder.addHeader("RANGE", "bytes=$start-")
|
val request = Request.Builder()
|
||||||
requestBuilder.addHeader("Connection", "close")
|
.url(url)
|
||||||
val request: Request = requestBuilder.url(url).head().build()
|
.header("RANGE", "bytes=$start-")
|
||||||
val response: Response = okHttpClient.value.newCall(request).execute()
|
.head()
|
||||||
return if (response.isSuccessful) {
|
.build()
|
||||||
if (response.code == 206) { //支持
|
okHttpClient.newCall(request).execute().use { it.code == 206 }
|
||||||
response.close()
|
} catch (e: Exception) {
|
||||||
true
|
|
||||||
} else { //不支持
|
|
||||||
response.close()
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
response.close()
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isDowning(tag: String): Boolean {
|
private fun isDowning(tag: String): Boolean {
|
||||||
for (call in okHttpClient.value.dispatcher.runningCalls()) {
|
return okHttpClient.dispatcher.runningCalls().any { it.request().tag() == tag }
|
||||||
if (call.request().tag() == tag) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCancelled(): Boolean {
|
private fun isCancelled() = cancelledList.contains(fileName)
|
||||||
return cancelledList.contains(fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun cancel() {
|
fun cancel() {
|
||||||
cancel(filePath + fileName)
|
val tag = filePath + fileName
|
||||||
}
|
|
||||||
|
|
||||||
fun cancel(tag: String) {
|
|
||||||
cancelledList.add(fileName)
|
cancelledList.add(fileName)
|
||||||
if (okHttpClient.value.dispatcher.runningCalls().isNotEmpty()) {
|
okHttpClient.dispatcher.runningCalls().forEach { if (it.request().tag() == tag) it.cancel() }
|
||||||
for (call in okHttpClient.value.dispatcher.runningCalls()) {
|
|
||||||
if (call.request().tag() == tag) {
|
|
||||||
call.cancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
doCancel()
|
doCancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doException(err: String) {
|
// --- 线程调度优化 ---
|
||||||
runOnUiThread {
|
|
||||||
if (downCallBack == null) {
|
|
||||||
actionFail.invoke(err)
|
|
||||||
} else {
|
|
||||||
downCallBack?.fail(err)
|
|
||||||
}
|
|
||||||
mainThread = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doSuccess(file: File?) {
|
|
||||||
runOnUiThread {
|
|
||||||
if (file == null) {
|
|
||||||
doException("file not exit")
|
|
||||||
} else {
|
|
||||||
if (downCallBack == null) {
|
|
||||||
actionSuccess.invoke(file)
|
|
||||||
} else {
|
|
||||||
downCallBack?.success(file)
|
|
||||||
}
|
|
||||||
downloadSizeInfo.remove(fileName)
|
|
||||||
}
|
|
||||||
mainThread = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doGetTotal(total: Long) {
|
|
||||||
runOnUiThread {
|
|
||||||
if (downCallBack == null) {
|
|
||||||
actionGetTotal.invoke(total)
|
|
||||||
} else {
|
|
||||||
downCallBack?.total(total)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mainThread = null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doProgress(progress: Long) {
|
|
||||||
runOnUiThread {
|
|
||||||
if (downCallBack == null) {
|
|
||||||
actionProgress.invoke(progress)
|
|
||||||
} else {
|
|
||||||
downCallBack?.progress(progress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doCancel() {
|
|
||||||
runOnUiThread {
|
|
||||||
if (downCallBack == null) {
|
|
||||||
actionCancel.invoke()
|
|
||||||
} else {
|
|
||||||
downCallBack?.cancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mainThread = null
|
|
||||||
}
|
|
||||||
|
|
||||||
private var mainThread: Handler? = null
|
|
||||||
private fun runOnUiThread(action: () -> Unit) {
|
private fun runOnUiThread(action: () -> Unit) {
|
||||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
if (Looper.myLooper() == Looper.getMainLooper()) action() else mainHandler.post(action)
|
||||||
if (mainThread == null) {
|
|
||||||
mainThread = Handler(Looper.getMainLooper())
|
|
||||||
}
|
|
||||||
mainThread?.post {
|
|
||||||
action.invoke()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
action.invoke()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun doException(err: String) = runOnUiThread {
|
||||||
|
downCallBack?.fail(err) ?: actionFail.invoke(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doSuccess(file: File) = runOnUiThread {
|
||||||
|
downCallBack?.success(file) ?: actionSuccess.invoke(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doGetTotal(total: Long) = runOnUiThread {
|
||||||
|
downCallBack?.total(total) ?: actionGetTotal.invoke(total)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doProgress(progress: Long) = runOnUiThread {
|
||||||
|
downCallBack?.progress(progress) ?: actionProgress.invoke(progress)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doCancel() = runOnUiThread {
|
||||||
|
downCallBack?.cancel() ?: actionCancel.invoke()
|
||||||
|
}
|
||||||
|
|
||||||
class LoggingInterceptor : Interceptor {
|
class LoggingInterceptor : Interceptor {
|
||||||
@Throws(IOException::class)
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
val request: Request = chain.request()
|
val request = chain.request()
|
||||||
val startTime = System.nanoTime()
|
val t1 = System.nanoTime()
|
||||||
Log.d(
|
Log.d(TAG, "Sending request ${request.url}")
|
||||||
TAG, String.format(
|
val response = chain.proceed(request)
|
||||||
"Sending request %s on %s%n%s",
|
val t2 = System.nanoTime()
|
||||||
request.url, chain.connection(), request.headers
|
Log.d(TAG, "Received response for ${response.request.url} in ${(t2 - t1) / 1e6}ms")
|
||||||
)
|
|
||||||
)
|
|
||||||
val response: Response = chain.proceed(request)
|
|
||||||
val endTime = System.nanoTime()
|
|
||||||
Log.d(
|
|
||||||
TAG, String.format(
|
|
||||||
"Received response for %s in %.1fms%n%s",
|
|
||||||
response.request.url, (endTime - startTime) / 1e6, response.headers
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "LoggingInterceptor"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DownCallBack {
|
interface DownCallBack {
|
||||||
|
|
|
||||||
|
|
@ -25,23 +25,27 @@ object UpdateUtils {
|
||||||
}
|
}
|
||||||
var totalProgress = 0L
|
var totalProgress = 0L
|
||||||
DownUtils.getInstance()
|
DownUtils.getInstance()
|
||||||
.setReadTImeOut(10L)
|
|
||||||
.setDeleteWhenException(false)
|
|
||||||
.initUrl(url, null)
|
.initUrl(url, null)
|
||||||
.setFilePath(filePath)
|
.setFilePath(filePath)
|
||||||
.setFileName(fileName)
|
.setFileName(fileName)
|
||||||
.setActionCallBack(
|
.setActionCallBack(
|
||||||
{ totalProgress = it },
|
getTotal = { totalProgress = it },
|
||||||
{
|
progress = {
|
||||||
val percent = it.toDouble() / totalProgress.toDouble() * 100
|
val percent = it.toDouble() / totalProgress.toDouble() * 100
|
||||||
val curProgress = percent.toInt()
|
val curProgress = percent.toInt()
|
||||||
onProgress(curProgress)
|
onProgress(curProgress)
|
||||||
},
|
},
|
||||||
{
|
success = {
|
||||||
onFinish(true, it.absolutePath)
|
onFinish(true, it.absolutePath)
|
||||||
}, {
|
},
|
||||||
|
fail = {
|
||||||
|
if(destination.exists()){
|
||||||
|
destination.delete()
|
||||||
|
}
|
||||||
onFinish(false, null)
|
onFinish(false, null)
|
||||||
}).down()
|
}
|
||||||
|
)
|
||||||
|
.down()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
applicationContext?.let {
|
applicationContext?.let {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue