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
- Subida de archivos con okhttp
- OkHttp 3 y HttpURLConnection
- okHTTP utilizado internamente en dispositivos Android> 4.4 cuando se utiliza HttpUrlConnection?
- Com.android.volley.NoConnectionError después de detener la aplicación
- Causado por: java.lang.NoClassDefFoundError: Clase no encontrada usando el cargador de clase de arranque; No hay rastro de la pila disponible
@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?
- Retrofit ETAG y almacenamiento en caché
- ¿Cómo implementar Android Volley con OkHttp 2.0?
- Progreso de descarga con RxJava, OkHttp y Okio en Android
- ¿Cómo usar http / 2 con Okhttp en dispositivos Android?
- No se puede obtener la respuesta de OkHttp.body.toString () para devolver una cadena
- Retrofit invoca el método failure () incluso cuando el código de estado de los encabezados es 200
- ¿Android usa OkHttp internamente?
- Detectar si la respuesta OkHttp proviene de caché (con Retrofit)
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í.