Android 如何使用匕首2活页夹

Android 如何使用匕首2活页夹,android,dagger-2,Android,Dagger 2,我正在使用Dagger 2构建一个Android应用程序,如果可以的话,它支持蓝牙。我想用Dagger注入BluetoothAdapter依赖项 我知道用Dagger注入null值的一种方法,就是用@Nullable注释模块中的Provider方法、组件中的依赖项声明和注入站点上的参数。但是为了更清楚地说明BluetoothAdapter是一个可选的依赖项(应用程序的其余部分也可以在没有BT的情况下工作,并且也应该在emulator上工作),我想将该依赖项声明为所述的可选的 我的模块中有一个提供

我正在使用Dagger 2构建一个Android应用程序,如果可以的话,它支持蓝牙。我想用Dagger注入BluetoothAdapter依赖项

我知道用Dagger注入
null
值的一种方法,就是用
@Nullable
注释模块中的Provider方法、组件中的依赖项声明和注入站点上的参数。但是为了更清楚地说明BluetoothAdapter是一个可选的依赖项(应用程序的其余部分也可以在没有BT的情况下工作,并且也应该在emulator上工作),我想将该依赖项声明为所述的
可选的

我的模块中有一个提供程序方法:

@Provides
static BluetoothAdapter providesBluetoothAdapter(MainApplication application) {
    ...
}
以及组件中的相应声明:

BluetoothAdapter bluetoothAdapter();
根据说明,我将注射位置更改为
可选
,将模块抽象化,并在模块中添加以下抽象方法:

@BindsOptionalOf abstract BluetoothAdapter optionalBluetoothAdapter();
但是,它仍然会失败,出现
java.lang.NullPointerException:在模拟器上运行时,无法从非@Nullable@Provides方法
异常返回null。 这时我想我可能误解了
@BindsOptionalOf
的目的,删除了
BluetoothAdapter()来自我的组件的声明,以查看它是否取决于是否在组件中声明了依赖项。还是不行


我错过了什么?既然用
@BindsOptionalOf
注释的方法必须是抽象的,那么有可能用可选绑定完成我想做的事情吗?

您没有完全按照@BindsOptionalOf的使用方式来使用它@BindsOptionalOf最适合于编译时可能存在或不存在的绑定,因此最适合于可重用模块。它对运行时的存在或不存在都没有帮助

假设您正在构建一个可重用的库:

@Module public abstract class BluetoothAdapterModule {
  @Provides
  static BluetoothAdapter providesBluetoothAdapter(MainApplication application) {
    ...
  }
}

@Module public interface FooModule {
  // This consumes BluetoothAdapter when it happens to be present.
  @BindsOptionalOf BluetoothAdapter bindOptionalBluetoothAdapter();

  // Assume the Foo implementation injects Optional<BluetoothAdapter>.
  @Binds Bar bindBar(Foo foo);
}
@Module公共抽象类BluetoothAdapterModule{
@提供
静态蓝牙适配器提供蓝牙适配器(主应用程序){
...
}
}
@模块公共接口模块{
//这会在BluetoothAdapter出现时消耗它。
@bindsoptionalofBluetoothAdapter bindsoptionalBluetoothAdapter();
//假设Foo实现注入可选的。
@绑定条bindBar(Foo-Foo);
}
这里,当FoodModule和BluetoothAdapterModule绑定到同一个组件中时,BluetoothAdapter将有一个绑定。在未包含BluetoothAdapter模块的其他组件或应用程序中,BluetoothAdapter将没有绑定,如果直接从Foo依赖BluetoothAdapter(包括
@Nullable BluetoothAdapter
),编译将失败

但是,使用@BindsOptionalOf,您可以依靠Dagger通知您是否存在
蓝牙适配器
:改为注入
可选
。如果绑定可用,可选的将是“present”,并且
get
将返回BluetoothAdapter;如果不可用,则可选选项将为“缺席”。(当然,如中所述,您还可以插入
Optional
Optional
等,以进一步控制对象实例化的时间和地点。)

在这些情况下,
@BindsOptionalOf
只需向Dagger确认它应该管理可选实例的创建;否则,它将抛出编译时异常,前提是您犯了错误,忘记绑定您创建的可选实例


为了反映只有在运行时才知道是否存在蓝牙,您需要使用
@Nullable
或您编写的单独的可注入
BluetoothAdapterHolder
。您还可以如上所述显式绑定一个
可选的
,显式地创建一个符合您需求的存在或不存在特征。在这一点上,你不会使用@BindsOptionalOf,因为你不依赖Dagger来反映存在/不存在:你自己控制着它。

请欣赏答案,尽管在目前的解释风格中很难理解。