如何使用dagger 2在Android服务中注入单例

tas*_*ula 7 android dagger dagger-2

我正在尝试将单身经理添加到Android服务中.问题是注入的管理器与ViewModel中的管理器不同.

匕首组件

@Singleton
@Component(modules = {ApplicationModule.class, AppScreenModule.class, ServiceModule.class})
public interface AppComponent {

    void inject(App application);

    void inject(OpportunisticService opportunisticService);

    @Component.Builder
    interface Builder {
        AppComponent build();

        Builder applicationModule(ApplicationModule applicationModule);
    }
}
Run Code Online (Sandbox Code Playgroud)

模块

@Module
class ApplicationModule {    
    private final App mApp;

    ApplicationModule(App app) {
        mApp = app;
    }

    @Provides
    @Named("ApplicationContext")
    Context provideContext() {
        return mApp.getApplicationContext();
    }

    @Provides
    App provideApplication() {
        return mApp;
    }

    @Provides
    PeersManager providePeersManager() {
        return new PeersManager();
    }
}

@Module
abstract class ServiceModule {

    @ContributesAndroidInjector
    abstract OpportunisticService bindOpportunisticService();
}
Run Code Online (Sandbox Code Playgroud)

初始化

public class Components {
    private static AppComponent sComponent;

    public static void initialize(App app) {
        // Initialize the AppComponent
        Preconditions.checkState(sComponent == null, "AppComponent already initialized");
        sComponent = DaggerAppComponent.builder()
                                       .applicationModule(new ApplicationModule(app))
                                       .build();
    }

    public static AppComponent app() {
        if (BuildConfig.DEBUG)
            Preconditions.checkState(sComponent == null, "AppComponent not initialized");
        return sComponent;
    }
}

public class App extends Application implements HasActivityInjector, HasServiceInjector {
    @Inject
    DispatchingAndroidInjector<Activity> mActivityDispatchingAndroidInjector;

    @Inject
    DispatchingAndroidInjector<Service> mServiceDispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();

        // Initialize the AppComponent
        Components.initialize(this);
        Components.app().inject(this);
    }

    @Override
    public AndroidInjector<Activity> activityInjector() {
        return mActivityDispatchingAndroidInjector;
    }

    @Override
    public AndroidInjector<Service> serviceInjector() {
        return mServiceDispatchingAndroidInjector;
    }
}
Run Code Online (Sandbox Code Playgroud)

声明PeerManager:

@Singleton
public class PeersManager {

    @Inject
    public PeersManager() {
    }
}
Run Code Online (Sandbox Code Playgroud)

使用PeersManager:

public class ViewModel {
    private final PeersManager mPeersManager;

    @Inject
    public ViewModel (PeersManager peersManager) {
        mPeersManager = peersManager;
    }
}

public class OpportunisticService extends Service {
    @Inject
    PeersManager mPeersManager;

    @Override
    public void onCreate() {
        super.onCreate();
        AndroidInjection.inject(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,ViewModel.mPeersManager它不同于OpportunisticService.mPeersManager,并且我希望它们是相同的,因为它PeersManager被标记为单身.

我希望这是因为不同的发生AndroidInjectorS代表Activity/ FragmentService.

Jef*_*ica 0

您已将类注释为@Singleton类级注释,但 Dagger 忽略该注释,转而采用更显式的@Provides绑定。使用得当,这将允许您覆盖来自类本身的任何范围,因为 Dagger 假设无论类附带的“默认”如何,您都会显式列出组件上的模块和绑定。Dagger 无法看到@Provides方法本身的内部,因此它不知道该实例是否来自构造函数、静态方法返回值、Module 实例字段或其他一些更复杂的逻辑。在这里,Dagger 看到一个@Provides未知实现的无作用域,并相信您可以自己管理作用域,而不管任何作用域注释或@Inject构造函数注释。

因此,您可以选择以下两个选项之一:

  • 在 AppModule 中标记@Singleton您的@Provides PeersManager providePeersManager()方法。这允许您显式调用 PeersManager 构造函数,就像您在此处所做的那样。此时,您可以选择删除@SingletonPeersManager 类本身的注释,因为 Dagger 不会读取它:它显式地遵循您的模块的范围配置。

  • @Provides PeersManager完全删除您的方法@Inject并向 PeersManager 添加一个带注释的构造函数。此时,Dagger 负责创建 PeersManager,因此它将观察@SingletonPeersManager 类上的范围注释。

    如果您有接口-impl 拆分,例如接口 PeersManager 和实现类 DefaultPeersManager,那么您可以将其表示为类@Binds中的绑定。在这种情况下,Dagger 会发现您正在将 PeersManager 重定向到 DefaultPeersManager,但 Dagger 知道如何向 DefaultPeersManager 提供其构造函数和注释。abstract @Moduleabstract @Binds PeersManager providePeersManager(DefaultPeersManager impl)@Inject@Singleton