我正在使用Dagger 2构建一个Android应用程序,如果可用的话,它支持蓝牙.我想用Dagger注入BluetoothAdapter依赖项.
我知道null使用Dagger 注入值的一种方法,即注释模块中的Provider方法,Component中的依赖项声明和注入站点的参数@Nullable.但是为了更清楚地说明BluetoothAdapter是一个可选的依赖项(应用程序的其余部分也可以在没有BT的情况下工作,并且也应该在模拟器上工作),我想要声明依赖关系,Optional<BluetoothAdapter>如官方文档中所述.
我的模块中有一个Provider方法:
@Provides
static BluetoothAdapter providesBluetoothAdapter(MainApplication application) {
...
}
Run Code Online (Sandbox Code Playgroud)
以及组件中的相应声明:
BluetoothAdapter bluetoothAdapter();
Run Code Online (Sandbox Code Playgroud)
根据说明,我将注入站点更改为Optional<BluetoothAdapter>,使我的模块抽象化并在模块中添加以下抽象方法:
@BindsOptionalOf abstract BluetoothAdapter optionalBluetoothAdapter();
Run Code Online (Sandbox Code Playgroud)
但是,java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method在模拟器上运行时,它仍会失败并出现异常.那时我想,也许我误解了目的,@BindsOptionalOf并BluetoothAdapter bluetoothAdapter();从我的组件中删除了声明,看它是否取决于是否在组件中声明了依赖项.仍然无法正常工作.
我错过了什么?是否可以通过可选绑定完成我想要做的事情,因为注释的方法@BindsOptionalOf必须是抽象的?
Jef*_*ica 10
你并没有像使用@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();
@Binds Bar bindBar(Foo foo);
}
Run Code Online (Sandbox Code Playgroud)
这里,当FooModule和BluetoothAdapterModule绑定到同一个Component时,会有一个绑定BluetoothAdapter,因此Optional<BluetoothAdapter>可以注入并get返回BluetoothAdapter.在没有包含BluetoothAdapterModule的单独组件中,BluetoothAdapter没有绑定.如果您直接从Foo依赖BluetoothAdapter,包括@Nullable BluetoothAdapter,您的编译将失败.但是,使用时@BindsOptionalOf,您可以依赖注入Optional<BluetoothAdapter>,当包含BluetoothAdapterModule时会出现注入,并且在排除时不存在.
要在运行时反映蓝牙的存在与否,您需要使用@Nullable或单独注射BluetoothAdapterHolder您编写的注射.您还可以Optional<BluetoothAdapter>显式绑定,并使用您期望的存在或不存在特征显式创建它; 在这一点上,你不会使用@BindsOptionalOf,因为你并不依赖Dagger来反映存在/不存在:你自己控制它.
| 归档时间: |
|
| 查看次数: |
1388 次 |
| 最近记录: |