package com.example.whatever.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.example.whatever.Token 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()) // .baseUrl("${UrlConsts.BASE_URL_PROD}$DEFAULT_DOMAIN") // .baseUrl(Environment.baseUrl(ctx)) .baseUrl("http://192.168.1.2:48080") .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("Access-Token", 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.accessToken) return } // 访问令牌已过期,刷新令牌未过期,则调接口刷新当前令牌 // myHttp.async(TOKEN_REFRESH) myHttp.async("/app-api/member/auth/refresh-token") .skipPreproc() // 跳过所有预处理器 .addBodyPara("refreshToken", token.refreshToken) .nextOnIO() .setOnResponse { res: HttpResult -> exceptionCount = 0 if (!res.isSuccessful) { // doLogin(callback) return@setOnResponse } try { val newToken = res.body.toBean(Token::class.java) newToken.saveToSp(context!!) callback(newToken.accessToken) } catch (e: Exception) { // doLogin(callback) return@setOnResponse } } .setOnException { e: IOException -> evictHttpConnectPool(e) // doLogin(callback) } .post() } // private fun doLogin(callback: (String?) -> Unit) { // myHttp.async(SIGN_IN) // .skipPreproc() // .addBodyPara("username", "IPC") // .addBodyPara("password", "123456") // .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.accessToken) // } 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) callback(null, "haha", 0) } if (isAuth) httpTask.tag(tagAuth) if (isSkipPreproc) { httpTask.skipPreproc() } httpTask.nextOnIO() .setOnResponse { exceptionCount = 0 if (it.isSuccessful) { // Log.i("wtf1", it.body.toString()) 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) callback(null, "xixi", 0) Log.i("wtf2", it.toString()) } 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) errorMsg = "lala" ) 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) errorMsg = "dd" ) } }.setOnException { evictHttpConnectPool(it) downloadCallBack.onResult( false, // errorMsg = context?.getString(R.string.common_net_download) errorMsg = "qq" ) }.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) { } } }