在DI模块中提供改造时,如何从元数据中读取主机名?

时间:2018-11-08 10:35:20

标签: android retrofit dagger

我正在使用Dagger 2 + Retrofit来实现我的接口,该接口向Web服务发送数据/从Web服务接收数据

我正在按以下方式引用Philippe BOISNEY的AppModule.java

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

但是我有一个问题,如果我有多个Web服务主机,例如 Production Staging Development ?< / p>

我已经在AndroidManifest.xml中设置了连接到Build Config的那些不同的主机,但是我不知道如何读取AppModule中的元数据,以便用相应的Build Config替换BASE_URL

请给我建议,谢谢

2 个答案:

答案 0 :(得分:2)

您可以在build.gradle中定义几种风味类型,例如dev,prod和stage,并为每种风味定义build config变量

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\""
    }
}

然后使用它

private static String BASE_URL = BuildConfig.SERVER_URL;

如果您想使用匕首动态提供它,可以用这种方式实现

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

使用匕首动态提供服务器URL的另一种方法-使用构建器。例如,

@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();

答案 1 :(得分:0)

我放弃了从AndroidManefist中的元数据中读取相应主机的方法,而是转而引用@ConstOrVar的建议

这是我的app / build.gradle,我有2种口味分别描述了我的暂存和生产主机

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

然后这是我在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;
    }
}

这样做,Retrofit会自动基于BuildVariant告知要与之通信的Web服务主机