package com.grkj.iscs.util import android.content.Context import android.util.Log import cn.zhxu.okhttps.HTTP import cn.zhxu.data.Mapper import cn.zhxu.okhttps.HttpResult import cn.zhxu.okhttps.HttpTask import cn.zhxu.okhttps.OkHttps import cn.zhxu.okhttps.gson.GsonMsgConvertor import cn.zhxu.okhttps.okhttp.OkHttpClientWrapper import com.grkj.iscs.MyApplication import com.grkj.iscs.R import com.grkj.iscs.model.Constants import com.grkj.iscs.model.Token import com.grkj.iscs.model.UrlConsts import com.grkj.iscs.model.UrlConsts.SIGN_IN import com.grkj.iscs.util.log.LogUtil import okhttp3.logging.HttpLoggingInterceptor import java.io.IOException import java.net.SocketTimeoutException class NetHttpManager { lateinit var myHttp: HTTP var context: Context? = null var exceptionCount: Int = 0 companion object { fun getInstance() = InstanceHelper.sSingle val tagAuth = "Auth" } object InstanceHelper { val sSingle = NetHttpManager() } fun initCtx(ctx: Context) { context = ctx myHttp = HTTP.builder() .addMsgConvertor(GsonMsgConvertor()) .bodyType("application/json") .baseUrl(UrlConsts.BASE_URL) .responseListener { task: HttpTask<*>?, result: HttpResult? -> if (result?.status != 200) { LogUtil.d( "Api fail : Url : ${task?.url}, " + "Status : ${result?.status}, " + "Params : ${task?.urlParas ?: task?.bodyParas}" ) } true } .config { it.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) } .addSerialPreprocessor { itPreChain -> if (!itPreChain.task.isTagged(tagAuth)) { itPreChain.proceed() return@addSerialPreprocessor } requestTokenAndRefreshIfExpired { itPreChain.task.addHeader("Authorization", it) itPreChain.proceed() } } .build() } /** * 获取TOKEN,若过期则刷新(代码中的字符串可以替换为常量) */ fun requestTokenAndRefreshIfExpired(callback: (String?) -> Unit) { val token = Token.fromSp(context!!) if (token == null) { doLogin(callback) return } if (token.isValid()) { callback(token.token) return } doLogin(callback) } private fun doLogin(callback: (String?) -> Unit) { val ctx = MyApplication.instance?.applicationContext // TODO 临时注掉,方便调试 // if (ctx == null || SPUtils.getLoginUser(ctx) == null) { // return // } myHttp.async(SIGN_IN) .skipPreproc() .addBodyPara("username", "admin") .addBodyPara("password", "grkj8888") .nextOnIO() .setOnResponse { exceptionCount = 0 if (!it.isSuccessful) { callback(null) return@setOnResponse } try { val newToken = it.body.toBean(Token::class.java) newToken.saveToSp(context!!) callback(newToken.token) } catch (e: Exception) { callback(null) return@setOnResponse } } .setOnException { evictHttpConnectPool(it) callback(null) } .post() } fun doRequestNet( urlStr: String, isSkipPreproc: Boolean, bodyParas: Map, callback: (HttpResult.Body?, String?, Int) -> Unit, isGet: Boolean, isAuth: Boolean, mapperCallBack: ((Mapper) -> Unit)? = null ) { var httpTask = myHttp.async(urlStr).setOnException { evictHttpConnectPool(it) callback(null, context?.getString(R.string.common_net_dis), 0) } if (isAuth) httpTask.tag(tagAuth) if (isSkipPreproc) { httpTask.skipPreproc() } httpTask.nextOnIO() .setOnResponse { exceptionCount = 0 if (it.isSuccessful) { MyApplication.instance?.applicationContext?.let { itCtx -> Token.refresh(itCtx) } callback(it.body, null, it.status) } else { var bobyStr = it.body.toString() callback( null, if (bobyStr.isNullOrEmpty()) { it.toString() } else { bobyStr }, it.status ) } } .setOnException { evictHttpConnectPool(it) callback(null, context?.getString(R.string.common_net_dis), 0) } mapperCallBack?.let { httpTask.setOnResMapper { mapperCallBack.invoke(it) } } // .setOnResMapper { // mapperCallBack?.invoke(it) // } if (isGet) { httpTask.addUrlPara(bodyParas) httpTask.get() } else { httpTask.addBodyPara(bodyParas) httpTask.post() } } fun downloadFileWithProcess( url: String, downloadCallBack: DownloadCallBack, filePath: String? = null, folderPath: String? = null ) { try { if (filePath.isNullOrBlank() && folderPath.isNullOrBlank()) { downloadCallBack.onResult( false, errorMsg = context?.getString(R.string.common_download_erro_notag) ) return } OkHttps.async(url).setOnResponse { exceptionCount = 0 if (it.isSuccessful) { if (filePath != null && filePath.isNotEmpty()) { it.body .stepRate(0.01) .setOnProcess { downloadCallBack.onProcess(it) } .toFile(filePath) .setOnSuccess { downloadCallBack.onResult(true, file = it) } .setOnFailure { downloadCallBack.onResult(false, errorMsg = it.exception.toString()) }.start() } else if (folderPath != null && folderPath.isNotEmpty()) { it.body .stepRate(0.01) .setOnProcess { downloadCallBack.onProcess(it) } .toFolder(folderPath) .setOnSuccess { downloadCallBack.onResult(true, file = it) } .setOnFailure { downloadCallBack.onResult(false, errorMsg = it.exception.toString()) }.start() } } else { downloadCallBack.onResult( false, it.status, errorMsg = context?.getString(R.string.common_net_download) ) } }.setOnException { evictHttpConnectPool(it) downloadCallBack.onResult( false, errorMsg = context?.getString(R.string.common_net_download) ) }.get() } catch (e: Exception) { downloadCallBack.onResult(false, errorMsg = e.message) } } private fun evictHttpConnectPool(e: Exception) { try { if (e is SocketTimeoutException) { exceptionCount += 1 if (exceptionCount >= 5) { exceptionCount = 0 (myHttp as OkHttpClientWrapper).okClient().connectionPool().evictAll() } } else { exceptionCount = 0 } } catch (e: Exception) { } } }