Establecer url de base dinámica utilizando Retrofit 2.0 y Dagger 2
Estoy tratando de realizar una acción de inicio de sesión utilizando Retrofit 2.0 con Dagger 2
Así es como configuro la dependencia de Retrofit
- Retrofit 2: responseBodyConverter convierte a objeto nulo
- ¿Es posible mostrar la barra de progreso cuando se carga la imagen a través de Retrofit 2
- Retrofit v2 ¿Call.cancel () elimina la devolución de llamada?
- Establecimiento de una etiqueta en una llamada de Retrofit para cancelar por etiqueta más tarde
- Utilizar RxJava para encadenar la solicitud en un solo hilo
@Provides @Singleton Retrofit provideRetrofit(Gson gson, OkHttpClient client) { Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson) .client(client) .baseUrl(application.getUrl()) .build(); return retrofit; }
Aquí está la interfaz de la API.
interface LoginAPI { @GET(relative_path) Call<Boolean> logMe(); }
Tengo tres usuarios diferentes de las URL de la base pueden abrir una sesión. Por lo tanto, no puedo establecer un URL estático al configurar la dependencia de Retrofit. He creado un setUrl () y métodos getUrl () en la clase de aplicación. Tras el inicio de sesión del usuario, establezco la URL en la aplicación antes de invocar la llamada a la API.
Yo uso la inyección perezoso para retrofit como este
Lazy<Retrofit> retrofit
De esta manera, Dagger inyecta la dependencia sólo cuando puedo llamar
retrofit.get()
Esta parte funciona bien. Tengo la url ajustada para mejorar la dependencia. Sin embargo, el problema surge cuando el usuario escribe una URL incorrecta de base (por ejemplo, mywifi.domain.com), entiende que es incorrecta y la cambia (por ejemplo, a mydata.domain.com). Ya que Dagger ya creó la dependencia para la adaptación, no volverá a hacerlo. Así que tengo que volver a abrir la aplicación y el tipo de la url correcta.
He leído diferentes publicaciones para configurar urls dinámicas en Retrofit usando Dagger. Nada realmente funcionó bien en mi caso. ¿Extraño algo?
- Problema del tipo de contenido de Retrofit-2
- Android Retrofit 2 + RxJava: escuchar stream sin fin
- Cómo saber cuándo finaliza una llamada de Retrofit
- Apoyo de mejora SNI
- Retrofit 2 - Parámetro de consulta de URL
- Retrofit 2 imprime cuerpo de respuesta vacío en registro con HttpLoggingInterceptor.Level.BODY
- SocketTimeoutException actualización de Android
- Retrofit, Generic Tipo de llamada
El soporte para este caso de uso se eliminó en Retrofit2. La recomendación es usar un interceptor OkHttp en su lugar.
HostSelectionInterceptor
hecho por swankjesse
import java.io.IOException; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; /** An interceptor that allows runtime changes to the URL hostname. */ public final class HostSelectionInterceptor implements Interceptor { private volatile String host; public void setHost(String host) { this.host = host; } @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); String host = this.host; if (host != null) { //HttpUrl newUrl = request.url().newBuilder() // .host(host) // .build(); HttpUrl newUrl = HttpUrl.parse(host); request = request.newBuilder() .url(newUrl) .build(); } return chain.proceed(request); } public static void main(String[] args) throws Exception { HostSelectionInterceptor interceptor = new HostSelectionInterceptor(); OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(interceptor) .build(); Request request = new Request.Builder() .url("http://www.coca-cola.com/robots.txt") .build(); okhttp3.Call call1 = okHttpClient.newCall(request); okhttp3.Response response1 = call1.execute(); System.out.println("RESPONSE FROM: " + response1.request().url()); System.out.println(response1.body().string()); interceptor.setHost("www.pepsi.com"); okhttp3.Call call2 = okHttpClient.newCall(request); okhttp3.Response response2 = call2.execute(); System.out.println("RESPONSE FROM: " + response2.request().url()); System.out.println(response2.body().string()); } }
O puede reemplazar su instancia de Retrofit (y posiblemente almacenar la instancia en un RetrofitHolder
en el que puede modificar la instancia en sí, y proporcionar el titular a través de Dagger) …
public class RetrofitHolder { Retrofit retrofit; //getter, setter }
O vuelva a usar su instancia actual de Retrofit e invente la nueva URL con reflexión, porque atornille las reglas. Retrofit tiene un parámetro baseUrl
que es private final
, por lo tanto, se puede acceder sólo con la reflexión.
Field field = Retrofit.class.getDeclaredField("baseUrl"); field.setAccessible(true); okhttp3.HttpUrl newHttpUrl = HttpUrl.parse(newUrl); field.set(retrofit, newHttpUrl);
La biblioteca Retrofit2 viene con una anotación @Url
. Puede reemplazar baseUrl
esta manera:
Interfaz de la API:
public interface UserService { @GET public Call<ResponseBody> profilePicture(@Url String url); }
Y llame a la API de esta manera:
Retrofit retrofit = Retrofit.Builder() .baseUrl("https://your.api.url/"); .build(); UserService service = retrofit.create(UserService.class); service.profilePicture("https://s3.amazon.com/profile-picture/path");
Para más detalles, consulte este enlace: https://futurestud.io/tutorials/retrofit-2-how-to-use-dynamic-urls-for-requests
- Descomposición de un androide apk?
- Pegar texto en el portapapeles del emulador de Android con el shell de adb