Autenticador Okhttp multihilo

Estoy utilizando la biblioteca okhttp en mi aplicación Android con varias solicitudes asíncronas. Todas las solicitudes requieren que el token se establezca en el encabezado. A veces necesito actualizar ese token usando RefreshToken proporcionado, así que decido usar la clase Authenticator de OkHttp.

¿Qué sucederá cuando 2 o más solicitudes asíncronas obtengan código 401 del servidor aproximadamente al mismo tiempo? ¿El método del Autenticador

@Override public Request authenticate(Proxy proxy, Response response) throws IOException { return null; } 

Ser llamado para cada solicitud, o se llamará sólo una vez para la primera solicitud, que tiene 401?

¿Cómo actualizar el token una sola vez?

Veo aquí dos escenarios basados ​​en cómo API que usted llama obras.

Primero uno es definitivamente más fácil de manejar – la llamada de nuevas credenciales (por ejemplo, token de acceso) no caduca una antigua. Para lograrlo, puede agregar una bandera adicional a sus credenciales para decir que las credenciales se están actualizando. Cuando obtuvo la respuesta 401, establezca el indicador en true, realice una solicitud para obtener nuevas credenciales y guárdelas sólo si flag es igual a true, de modo que sólo se manejará la primera respuesta y el resto se ignorará. Asegúrese de que su acceso a flag está sincronizado.

Otro escenario es un poco más complicado – cada vez que se llama nuevas credenciales de edad se establecen que se venció por lado del servidor. Para manejarlo, yo introduciría un nuevo objeto para ser usado como un semafore – sería bloqueado cada vez que 'las credenciales están siendo actualizadas'. Para cerciorarse de que usted hará solamente una llamada de las "credenciales de restauración", usted necesita llamarla en el bloque del código que se sincroniza con la bandera. Puede parecer:

 synchronized(stateObject) { if(!stateObject.isBeingRefreshed) return; Response response = client.execute(request); apiClient.setCredentials(response.getNewCredentials()); stateObject.isBeingRefreshed = false; } 

Como usted ha notado hay un cheque adicional if(!stateObject.isBeingRefreshed) return; Para cancelar la solicitud de nuevas credenciales siguiendo las solicitudes que recibieron respuesta 401.

En mi caso implementé el Authenticator usando el patrón Singleton. Puede sincronizar ese método para authenticate . En su implementación, compruebo si el token de la petición (obteniendo el objeto Request objeto Response recibido en el método params of authenticate) es el mismo que el guardado en el dispositivo ( SharedPreferences el token en un objeto SharedPreferences ).

Si el token es el mismo, significa que no se ha actualizado todavía, por lo que ejecuto la actualización de token y la solicitud actual de nuevo.

Si el token no es el mismo, significa que se ha actualizado antes, por lo que ejecuto la solicitud de nuevo, pero utilizando el token guardado en el dispositivo.

Si usted necesita más ayuda, por favor dígame y pondré un poco de código aquí.

  • OkHttp / tiempo de espera de retroactivación predeterminado
  • ¿Cómo obtener un cuerpo de respuesta para la excepción de actualización?
  • Retrofit + okhttp: Recuperar GZIPInputStream
  • Conexión de http de Android con OkHttp No funciona
  • CertPathValidatorException: Ancla de confianza para ruta de certificación no encontrada
  • Cómo hacer la solicitud https con certificado SSL en Retrofit
  • MultipartBuilder no se puede resolver en okhttp: 3.0.0-RC1
  • Android Retrofit2 Actualizar Oauth 2 Token
  • RETROFIT & AUTH COOKIE
  • InterruptedIOException al usar Retrofit2 con rx cuando retryOn
  • HTTPS con Retrofit y OkHttp Handshake falló
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.