Как динамически передавать разные URL-адреса в Retrofit2 Android с помощью Dagger - PullRequest
0 голосов
/ 18 января 2019
  1. В ApplicationClass я передаю один URL и использую его в ActLogin.java
  2. Теперь я хочу передать ActUpcomingEvents другой URL, отличный от ActLogin.java
  3. Как этого добиться

NetModule.java

@Module
public class NetModule {

    String mBaseUrl;
    Application mApplication;

    // Constructor needs one parameter to instantiate.
    public NetModule(String baseUrl, Application application) {
        this.mBaseUrl = baseUrl;
        this.mApplication = application;
    }

    // Dagger will only look for methods annotated with @Provides
    @Provides
    @Singleton
    // Application reference must come from AppModule.class
    SharedPreferences providesSharedPreferences(Application application) {
        return PreferenceManager.getDefaultSharedPreferences(application);
    }



    @Provides
    @Singleton
    Cache provideOkHttpCache(Application application) {
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(application.getCacheDir(), cacheSize);
        return cache;
    }

    @Provides
    @Singleton
    Gson provideGson() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        return gsonBuilder.create();
    }

    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(Cache cache) {
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.cache(cache);
        client.addInterceptor(new RequestInterceptor(mApplication));
        client.readTimeout(Keys.READ_TIMEOUT, TimeUnit.SECONDS);
        client.connectTimeout(Keys.CONNECTION_TIMEOUT, TimeUnit.SECONDS);
        client.writeTimeout(Keys.WRITE_TIMEOUT, TimeUnit.SECONDS);
        return client.build();
    }

    @Provides @Named("auth")
    @Singleton
    Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(mBaseUrl)
                .client(okHttpClient)
                .build();
        return retrofit;
    }

}

AppModule.java

@Module
public class AppModule {
    Application mApplication;

    public AppModule(Application mApplication) {
        this.mApplication = mApplication;
    }

    @Provides
    @Singleton
    Application provideApplication() {
        return mApplication;
    }
}

SessionModule.java

@Module
public class SessionModule {

    Application mApplication;

    public SessionModule(Application mApplication) {
        this.mApplication = mApplication;
    }

    @Provides
    @Singleton
    // Application reference must come from AppModule.class
    CaringSession providesCaringSession() {
        return new CaringSession(mApplication);
    }
}

NetComponent.java

@Singleton
@Component(modules = {AppModule.class,NetModule.class,SessionModule.class})
public interface NetComponent {
    void inject(ActUpcomingEvents activity);
    void inject(ActLogin activity);
}

ApplicationClass

public class CaringApp extends Application {

    static CaringApp appInstance;
    public static final String TAG = CaringApp.class.getSimpleName();
    private NetComponent mNetComponent;
    ANRWatchDog anrWatchDog = new ANRWatchDog(2000);
    private RxBus bus;

    private static CaringSession mSession;

    @Override
    public void onCreate() {
        super.onCreate();
        appInstance = this;
        mSession = new CaringSession(appInstance);
        //Initialize the crashlytics
        initCrashlytics();
        //Initialize the watch dog
        initAnrWatchDog();
        //Initialize retrofit
        retrofitInit();
        //Rx Bus Init
    }



    public RxBus getBus() {
        return bus;
    }

    private void initAnrWatchDog() {
        anrWatchDog.setANRListener(new ANRWatchDog.ANRListener() {
            @Override
            public void onAppNotResponding(ANRError error) {
                Log.e("ANR-Watchdog", "Detected Application Not Responding!");

                // Some tools like ACRA are serializing the exception, so we must make sure the exception serializes correctly
                try {
                    new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(error);
                }
                catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
                Crashlytics.logException(new RuntimeException(error.getStackTrace().toString()));
                Crashlytics.log(Log.ERROR, "ANR-LOG", error.getStackTrace().toString());
                Log.i("ANR-Watchdog", "Error was successfully serialized");

                throw error;
            }
        });

        anrWatchDog.start();
    }


    /**************** Init  ****************/
    /** Init retrofit **/
    private void retrofitInit() {
        try{
            mNetComponent = DaggerNetComponent.builder()
                    .appModule(new AppModule(this))
                    .netModule(new NetModule(Keys.BASE_URL,this))
                    .sessionModule(new SessionModule(getAppInstance()))
                    .build();
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

    /** Init crashlytics **/
    private void initCrashlytics() {
        Fabric.with(this, new Crashlytics());
    }
    /**************** Init  ****************/


    /**************** Getters ****************/
    /** Net component **/
    public NetComponent getNetComponent() {
        return mNetComponent;
    }

    /** App Instance **/
    public static CaringApp getAppInstance() {
        if (appInstance == null) {
            appInstance = new CaringApp();
        }
        return appInstance;
    }

    public static CaringSession getmSession() {
        return mSession;
    }
    /**************** Getters ****************/

В моем kotlinClass я делаю инъекцию как

class ActLogin : AppCompatActivity(), IntDataLogin {

 @set:Inject var retrofit: Retrofit? = null

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        (application as CaringApp).netComponent.inject(this)
    }

}

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

К сожалению, модификация ( текущая версия 2.5.0 ) должна быть инициализирована с baseUrl , которая не может быть изменена впоследствии. Однако в определении конечных точек вашего интерфейса вы можете передать аннотированный параметр @ Url (см. Предыдущий ответ от Nanda Z) или вы можете создать несколько экземпляров Retrofit (с другим baseUrl, используя @ Named аннотацию ), который будет предоставлен Dagger. Например:

@Provides
@Named("myCoolRetrofitInstance1")
@Singleton
Retrofit provideRetrofit1(Gson gson, OkHttpClient okHttpClient) {
    Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl(SOME_URL_1)
            .client(okHttpClient)
            .build();
    return retrofit;
}

@Provides
@Named("myCoolRetrofitInstance2")
@Singleton
Retrofit provideRetrofit2(Gson gson, OkHttpClient okHttpClient) {
    Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl(SOME_URL_2)
            .client(okHttpClient)
            .build();
    return retrofit;
}

А для инъекций вы должны также использовать правильную аннотацию @Named.

@Inject
@Named("myCoolRetrofitInstance1") // or @Named("myCoolRetrofitInstance2")
lateinit var retforit: Retforit
0 голосов
/ 18 января 2019

Если вы имеете в виду, у вас есть другой базовый URL. Вы можете сделать что-то вроде этого;

public interface YourAPIInterface {

    @GET
    Call<POJO> doAllItems(@Url String url);

}

@Url аннотация параметра, позволяющая динамически указывать полное имя хоста. Тогда вы можете назвать это обычным способом в Refrofit

...