NetHttpManager.kt 8.5 KB

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