How to dynamically pass different urls in retrofit

2019-08-31 01:11发布

  1. In the ApplicationClass I'm passing one url and i use it in ActLogin.java
  2. Now I want to pass ActUpcomingEvents another url different than ActLogin.java
  3. How to achieve this

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 ****************/

In my kotlinClass I am injecting like

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条回答
走好不送
2楼-- · 2019-08-31 01:35

Unfortunately, retrofit (current version 2.5.0) has to be initialized with a baseUrl, which can't be changed afterwards. However, in your interface endpoints definition you can pass @Url annotated param (see previous answer from Nanda Z) or you can created multiple Retrofit instances (with different baseUrl, using @Named annotation) which will be provided by Dagger. For instance:

@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;
}

And for injecting you have to use proper @Named annotation as well.

@Inject
@Named("myCoolRetrofitInstance1") // or @Named("myCoolRetrofitInstance2")
lateinit var retforit: Retforit
查看更多
ゆ 、 Hurt°
3楼-- · 2019-08-31 01:48

If you mean, you have another base url. you can do something like this;

public interface YourAPIInterface {

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

}

@Url annotation on a parameter to allow specifying a full host name dynamically. Then you can call it the normal way in Refrofit

查看更多
登录 后发表回答