How to read hostname from meta-data when providing

2019-08-24 10:15发布

I am using Dagger 2 + Retrofit to implement my interfaces which sends/receives data to/from my web service

I am referring Philippe BOISNEY's AppModule.java as below

private static String BASE_URL = "https://api.github.com/";

@Provides
Gson provideGson() { return new GsonBuilder().create(); }

@Provides
Retrofit provideRetrofit(Gson gson) {
    Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl(BASE_URL)
            .build();
    return retrofit;
}

However I have a question that what if I have multiple hosts of my web services, such as Production, Staging and Development?

I already setup those different hosts connected to Build Config in my AndroidManifest.xml, but I don't have an idea how to read meta-data in AppModule, in order to replace BASE_URL with corresponding build config

Please kindly advice me, thank you

2条回答
beautiful°
2楼-- · 2019-08-24 10:30

You can define in build.gradle several flavor types like dev, prod and stage and for each flavor define build config variable

productFlavors {
    dev {
        buildConfigField "String", "SERVER_URL", "\"your dev url\""
    }
    stage {
        buildConfigField "String", "SERVER_URL", "\"your stage url\""
    }
    prod {
        buildConfigField "String", "SERVER_URL", "\"your prod url\""
    }
}

And after that use it

private static String BASE_URL = BuildConfig.SERVER_URL;

If you like to provide it dynamically using dagger, you can do it in that way

@Module
public class AppModule {
    @Named("server_url")
    @Provides
    String provideServerUrl() {
        return "https://api.github.com/";
    }

    @Provides
    Retrofit provideRetrofit(Gson gson, @Named("server_url") String url) {
        Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl(url)
            .build();
        return retrofit;
    }
}

Another way of dynamically providing server url using dagger - using builder. For example,

@Component(AppModule.class)
interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder serverUrl(@Named("server_url") String url);

        AppComponent build();
    }
}

@Module
public class AppModule {
    @Provides
    Retrofit provideRetrofit(Gson gson, @Named("server_url") String url) {
        Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl(url)
            .build();
        return retrofit;
    }
}

DaggerAppComponent.Builder()
    .appModule(new AppModule())
    .serverUrl("https://api.github.com/")
    .build();
查看更多
The star\"
3楼-- · 2019-08-24 10:47

I give up reading corresponding host from meta-data in AndroidManefist, instead, I switch to another approach by referring @ConstOrVar's suggestion

Here is my app/build.gradle, I have 2 flavors which describes my staging and production host respectively

productFlavors {
    production {
        buildConfigField("String", "SERVER_HOST", "\"myproductionost.com\"")
    }
    staging {
        buildConfigField("String", "SERVER_HOST", "\"mystaginghost.com\"")
    }
}

Then here is my codes in my AppModule.java

@Module
public class AppModule {

    @Provides
    Retrofit provideRetrofit(Gson gson) {
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson)) 
                .baseUrl("https://" + BuildConfig.SERVER_HOST)
                .build();
        return retrofit;
    }
}

By doing so, Retrofit will tells which host of webservice it shall talk with based on BuildVariant automatically

查看更多
登录 后发表回答