NetHttpManager.kt 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. package com.grkj.iscs.util
  2. import android.content.Context
  3. import android.util.Log
  4. import cn.zhxu.okhttps.HTTP
  5. import cn.zhxu.data.Mapper
  6. import cn.zhxu.okhttps.HttpResult
  7. import cn.zhxu.okhttps.HttpTask
  8. import cn.zhxu.okhttps.OkHttps
  9. import cn.zhxu.okhttps.gson.GsonMsgConvertor
  10. import cn.zhxu.okhttps.okhttp.OkHttpClientWrapper
  11. import com.grkj.iscs.MyApplication
  12. import com.grkj.iscs.R
  13. import com.grkj.iscs.model.Constants
  14. import com.grkj.iscs.model.Token
  15. import com.grkj.iscs.model.UrlConsts
  16. import com.grkj.iscs.model.UrlConsts.SIGN_IN
  17. import com.grkj.iscs.model.vo.BaseVO
  18. import com.grkj.iscs.util.log.LogUtil
  19. import okhttp3.logging.HttpLoggingInterceptor
  20. import java.io.IOException
  21. import java.net.SocketTimeoutException
  22. class NetHttpManager {
  23. lateinit var myHttp: HTTP
  24. var context: Context? = null
  25. var exceptionCount: Int = 0
  26. companion object {
  27. fun getInstance() = InstanceHelper.sSingle
  28. val tagAuth = "Auth"
  29. }
  30. object InstanceHelper {
  31. val sSingle = NetHttpManager()
  32. }
  33. fun initCtx(ctx: Context) {
  34. context = ctx
  35. myHttp = HTTP.builder()
  36. .addMsgConvertor(GsonMsgConvertor())
  37. .bodyType("application/json")
  38. .baseUrl(UrlConsts.BASE_URL)
  39. .responseListener { task: HttpTask<*>?, result: HttpResult? ->
  40. if (result?.status != 200) {
  41. LogUtil.d(
  42. "Api fail : Url : ${task?.url}, " +
  43. "Status : ${result?.status}, " +
  44. "Params : ${task?.urlParas ?: task?.bodyParas}"
  45. )
  46. }
  47. true
  48. }
  49. .config {
  50. it.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
  51. }
  52. .addSerialPreprocessor { itPreChain ->
  53. if (!itPreChain.task.isTagged(tagAuth)) {
  54. itPreChain.proceed()
  55. return@addSerialPreprocessor
  56. }
  57. requestTokenAndRefreshIfExpired {
  58. itPreChain.task.addHeader("Authorization", it)
  59. itPreChain.proceed()
  60. }
  61. }
  62. .build()
  63. }
  64. /**
  65. * 获取TOKEN,若过期则刷新(代码中的字符串可以替换为常量)
  66. */
  67. fun requestTokenAndRefreshIfExpired(callback: (String?) -> Unit) {
  68. val token = Token.fromSp(context!!)
  69. if (token == null) {
  70. doLogin(callback)
  71. return
  72. }
  73. if (token.isValid()) {
  74. callback(token.token)
  75. return
  76. }
  77. // TODO 检查当前登录状态;临时注掉,方便调试
  78. // if (SPUtils.getLoginUser(context!!) == null) {
  79. // ToastUtils.tip(context!!.resources.getString(R.string.please_login))
  80. // return
  81. // }
  82. doLogin(callback)
  83. }
  84. private fun doLogin(callback: (String?) -> Unit) {
  85. val ctx = MyApplication.instance?.applicationContext
  86. // TODO 临时注掉,方便调试
  87. // if (ctx == null || SPUtils.getLoginUser(ctx) == null) {
  88. // return
  89. // }
  90. // TODO 后续用SP数据替换
  91. myHttp.async(SIGN_IN)
  92. .skipPreproc()
  93. .addBodyPara("username", "admin")
  94. .addBodyPara("password", "grkj8888")
  95. .nextOnIO()
  96. .setOnResponse {
  97. exceptionCount = 0
  98. if (!it.isSuccessful) {
  99. callback(null)
  100. return@setOnResponse
  101. }
  102. try {
  103. val newToken = it.body.toBean(Token::class.java)
  104. newToken.saveToSp(context!!)
  105. callback(newToken.token)
  106. } catch (e: Exception) {
  107. callback(null)
  108. return@setOnResponse
  109. }
  110. }
  111. .setOnException {
  112. evictHttpConnectPool(it)
  113. callback(null)
  114. }
  115. .post()
  116. }
  117. fun doRequestNet(
  118. urlStr: String, isSkipPreproc: Boolean,
  119. bodyParas: Map<String, *>,
  120. callback: (HttpResult.Body?, String?, Int) -> Unit,
  121. isGet: Boolean, isAuth: Boolean,
  122. mapperCallBack: ((Mapper) -> Unit)? = null
  123. ) {
  124. var httpTask = myHttp.async(urlStr).setOnException {
  125. evictHttpConnectPool(it)
  126. callback(null, context?.getString(R.string.common_net_dis), 0)
  127. }
  128. if (isAuth) httpTask.tag(tagAuth)
  129. if (isSkipPreproc) {
  130. httpTask.skipPreproc()
  131. }
  132. httpTask.nextOnIO()
  133. .setOnResponse {
  134. exceptionCount = 0
  135. if (it.isSuccessful) {
  136. MyApplication.instance?.applicationContext?.let { itCtx ->
  137. Token.refresh(itCtx)
  138. }
  139. // TODO 待观察
  140. try {
  141. it.body.cache()
  142. val baseVO = getBaseVO<Any>(it.body)
  143. if (baseVO?.code in 200 until 300) {
  144. callback(it.body, null, it.status)
  145. } else {
  146. baseVO?.msg?.let { itMsg ->
  147. ToastUtils.tip(itMsg)
  148. }
  149. val bobyStr = it.body.toString()
  150. callback(
  151. null, if (bobyStr.isEmpty()) {
  152. it.toString()
  153. } else {
  154. bobyStr
  155. }, it.status
  156. )
  157. }
  158. } catch (e: Exception) {
  159. println("非标准返回数据,特殊处理:${e.message}")
  160. callback(it.body, null, it.status)
  161. }
  162. } else {
  163. var bobyStr = it.body.toString()
  164. callback(
  165. null, if (bobyStr.isNullOrEmpty()) {
  166. it.toString()
  167. } else {
  168. bobyStr
  169. }, it.status
  170. )
  171. }
  172. }
  173. .setOnException {
  174. evictHttpConnectPool(it)
  175. callback(null, context?.getString(R.string.common_net_dis), 0)
  176. }
  177. mapperCallBack?.let {
  178. httpTask.setOnResMapper {
  179. mapperCallBack.invoke(it)
  180. }
  181. }
  182. // .setOnResMapper {
  183. // mapperCallBack?.invoke(it)
  184. // }
  185. if (isGet) {
  186. httpTask.addUrlPara(bodyParas)
  187. httpTask.get()
  188. } else {
  189. httpTask.addBodyPara(bodyParas)
  190. httpTask.post()
  191. }
  192. }
  193. fun downloadFileWithProcess(
  194. url: String,
  195. downloadCallBack: DownloadCallBack,
  196. filePath: String? = null,
  197. folderPath: String? = null
  198. ) {
  199. try {
  200. if (filePath.isNullOrBlank() && folderPath.isNullOrBlank()) {
  201. downloadCallBack.onResult(
  202. false,
  203. errorMsg = context?.getString(R.string.common_download_erro_notag)
  204. )
  205. return
  206. }
  207. OkHttps.async(url).setOnResponse {
  208. exceptionCount = 0
  209. if (it.isSuccessful) {
  210. if (filePath != null && filePath.isNotEmpty()) {
  211. it.body
  212. .stepRate(0.01)
  213. .setOnProcess {
  214. downloadCallBack.onProcess(it)
  215. }
  216. .toFile(filePath)
  217. .setOnSuccess {
  218. downloadCallBack.onResult(true, file = it)
  219. }
  220. .setOnFailure {
  221. downloadCallBack.onResult(false, errorMsg = it.exception.toString())
  222. }.start()
  223. } else if (folderPath != null && folderPath.isNotEmpty()) {
  224. it.body
  225. .stepRate(0.01)
  226. .setOnProcess {
  227. downloadCallBack.onProcess(it)
  228. }
  229. .toFolder(folderPath)
  230. .setOnSuccess {
  231. downloadCallBack.onResult(true, file = it)
  232. }
  233. .setOnFailure {
  234. downloadCallBack.onResult(false, errorMsg = it.exception.toString())
  235. }.start()
  236. }
  237. } else {
  238. downloadCallBack.onResult(
  239. false,
  240. it.status,
  241. errorMsg = context?.getString(R.string.common_net_download)
  242. )
  243. }
  244. }.setOnException {
  245. evictHttpConnectPool(it)
  246. downloadCallBack.onResult(
  247. false,
  248. errorMsg = context?.getString(R.string.common_net_download)
  249. )
  250. }.get()
  251. } catch (e: Exception) {
  252. downloadCallBack.onResult(false, errorMsg = e.message)
  253. }
  254. }
  255. private fun evictHttpConnectPool(e: Exception) {
  256. try {
  257. if (e is SocketTimeoutException) {
  258. exceptionCount += 1
  259. if (exceptionCount >= 5) {
  260. exceptionCount = 0
  261. (myHttp as OkHttpClientWrapper).okClient().connectionPool().evictAll()
  262. }
  263. } else {
  264. exceptionCount = 0
  265. }
  266. } catch (e: Exception) {
  267. }
  268. }
  269. }