注入 GoogleApiClient

Injection of GoogleApiClient

我想在项目的不同部分注入 Google api 客户端的实例,但是我没能成功。

@Provides @Named("geodata_api")
    @Singleton
    GoogleApiClient providesGoogleApiClient(Context context) {
            return new GoogleApiClient.Builder(context)
                    .addApi(Places.GEO_DATA_API)
                    .build();
        }

  @Provides @Named("location_api")
    @Singleton
    GoogleApiClient providesGoogleApiClient(Context context) {
        return new GoogleApiClient.Builder(providesContext())
                .addApi(LocationServices.API)
                .build();
    }

问题是 Dagger 无法提供回调,因为回调是实现细节,而不是依赖项——并且回调通常在构建客户端之前设置(有关回调的更多信息,请参见下面的选项 2 ).

一个选项是让 Dagger 提供 GoogleApiClient.Builder,然后您的实现必须通过设置回调并调用 build():

来完成链
@Provides
@Named("location_api")
GoogleApiClient.Builder provideLocationClient(Context context) {
    return new GoogleApiClient.Builder(context)
            .addApi(LocationServices.API);
}

@Provides
@Named("geodata_api")
GoogleApiClient.Builder provideGeodataClient(Context context) {
    return new GoogleApiClient.Builder(context)
            .addApi(Places.GEO_DATA_API);
}

注意变化:

  1. @Named(..) 已经是一个范围,因此您应该删除 @Singleton —— 它不需要。
  2. 这两个提供程序方法需要以不同的方式命名(provideLocationClientprovideGeodataClient
  3. 模块没有返回 GoogleApiClient,而是返回 GoogleApiClient.Builder

现在要使用该依赖项,您需要注入构建器,然后附加回调并构建客户端:

@Inject @NamedScope("location_api") GoogleApiClient.Builder mLocationClientBuilder;

...

mComponent.inject(this);
mClient = mLocationClientBuilder.<addCallbacks(...)>.build();
mClient.connect();

使用单元测试模拟框架模拟此构建器时,您必须做的一件事是保留对回调的引用,并在调用 connect() 时调用 onConnected(Bundle) 回调方法.


另一种选择是像您一样提供 GoogleApiClient,但是您必须记住在连接之前注册您的回调,并且您必须记住在完成后注销这些回调(以防止内存泄漏)。参见 GoogleApiClient#registerConnectionCallbacks()