package com.example.firstapp.network
|
|
import android.content.Context
|
import android.content.Intent
|
import android.widget.Toast
|
import com.example.firstapp.activity.LoginActivity
|
import com.example.firstapp.utils.PreferencesManager
|
import okhttp3.Interceptor
|
import okhttp3.Response
|
import kotlin.concurrent.thread
|
|
class TokenExpiredInterceptor(private val context: Context) : Interceptor {
|
override fun intercept(chain: Interceptor.Chain): Response {
|
val response = chain.proceed(chain.request())
|
|
// 如果返回401或后端自定义的token失效状态码,说明token可能过期
|
if (response.code == 401 || isTokenInvalid(response)) {
|
// 清除本地token
|
PreferencesManager.clearUserData()
|
|
// 在主线程中显示提示并跳转到登录页面
|
thread {
|
android.os.Handler(context.mainLooper).post {
|
Toast.makeText(context, "登录已失效,请重新登录", Toast.LENGTH_LONG).show()
|
|
// 创建跳转到登录页面的Intent,并添加清除任务栈的标志
|
val intent = Intent(context, LoginActivity::class.java).apply {
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
}
|
context.startActivity(intent)
|
}
|
}
|
}
|
|
return response
|
}
|
|
// 检查响应是否表示token失效
|
private fun isTokenInvalid(response: Response): Boolean {
|
try {
|
// 尝试读取响应体,检查自定义的错误码
|
// 注意:这会消耗响应体,如果需要在后续处理中使用响应体,需要克隆
|
val responseBody = response.peekBody(4096).string()
|
|
// 根据您的后端逻辑,检查是否包含token失效的提示
|
// 这里假设后端在返回JSON中包含了错误码和消息
|
return responseBody.contains("\"code\":\"401\"") ||
|
responseBody.contains("token失效") ||
|
responseBody.contains("请重新登录")
|
} catch (e: Exception) {
|
return false
|
}
|
}
|
}
|