安卓应用崩溃: retrofit2.HttpException: HTTP 401

问题描述 投票:0回答:1

enter image description here有时在API响应中,我得到 401 未授权状态码。 我试图在我的 网络拦截器,但仍然应用程序崩溃。不知道我做错了什么,希望能得到帮助。

以下是我的RetrofitFactory类

object RetrofitFactory {

private val retrofit = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .client(
        OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .addInterceptor(
                object : Interceptor {
                    override fun intercept(chain: Interceptor.Chain): Response {
                            val request: Request = chain.request()
                                .newBuilder()
                                .build()
                            return chain.proceed(request)
                    }
                }
            )
            .addNetworkInterceptor(
                Interceptor { chain ->
                    val original = chain.request()
                    val requestBuilder = original.newBuilder()
                    val request = requestBuilder.build()
                    val response = chain.proceed(request)
                    Log.e("request", request.headers.toString())
                    Log.e("Response Body", response.body!!.toString())
                    when (response.code) {
                        HttpURLConnection.HTTP_OK -> return@Interceptor response
                        HttpURLConnection.HTTP_UNAUTHORIZED -> sessionExpired(
                            BaseApplication.getApplication()
                        )
                        HttpURLConnection.HTTP_FORBIDDEN -> sessionExpired(
                            BaseApplication.getApplication()
                        )
                    }
                    response
                }
            )
            .build()
    )
    .build()

@JvmStatic
fun <S> createService(serviceClass: Class<S>): S {
    return retrofit.create(serviceClass)
}
}

我想把用户移动到登录界面。所以这里是应该被调用的函数,但没有调用。

fun sessionExpired(application: Application) {
    val intent = Intent(application, LogInActivity::class.java)
    intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
    application.startActivity(intent)
}

这里是我的依赖关系。

//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.7.2'
//logging interceptor
implementation "com.squareup.okhttp3:logging-interceptor:4.4.0"

我还看了 此处 以及许多其他类似的问题,但没有找到帮助!

更新一下我是如何调用API:

在viewmodel中用这个

 viewModelScope.launch(Dispatchers.IO) {
        val apiResponse = apiEndPointsInterface.loginUser(loginRequestModel)
        returnLoginResponse(apiResponse)
    } 

而APIEndPointInterface是这样的。

@POST(AppConstants.APIEndPoints.LOGIN_USER)
    suspend fun loginUser(
        @Body requestLoginModel: LoginRequestModel
    ): LoginResponseModel
android kotlin retrofit retrofit2
1个回答
2
投票

你应该在改造请求的onFailure方法中调用sessionExpired函数。

override fun onFailure(call: Call<Model.Result>, t: Throwable) {
                if(t is HttpException && t.statusCode==401)
                    sessionExpired(BaseApplication.getApplication())
            }

如果你使用的是Kotlin coroutines。你应该把 await 调用包在 try catch 块中,然后在 catch 块中调用函数。请看下面的代码。

val response: String
    val getPlacesDeferred = PlaceAPI.retrofitService.getPlacesAsync()
        response = getPlacesDeferred.await())
        } catch (exception:Exception) {
            if(exception is HttpException && t.statusCode==401)
               sessionExpired(BaseApplication.getApplication())
        }

0
投票

为了解决这种问题,在进行任何api调用或使用retrofit时,你必须使用缓存策略。你必须使用缓存策略,使用Retrofit和Okhttp来解决你的问题。它还可以帮助你防止在调用api的过程中出现任何不必要的应用程序崩溃,即使你的应用程序没有连接到互联网。

© www.soinside.com 2019 - 2024. All rights reserved.