如何在非Activity/Fragment的SyncAdapter中使用Dagger2依赖注入?
解决SyncAdapter结合Dagger2的依赖注入问题
我明白你现在的困境——SyncAdapter既没有onCreate生命周期方法,也不依附于Activity/Fragment,找不到合适的时机调用注入方法导致mSyncCenterPresenter一直为null。其实这类系统托管的非UI组件,咱们可以通过构造方法注入来解决,下面是具体的实现步骤:
1. 确保你的Dagger组件配置正确
首先,要保证你的全局AppComponent能够提供SyncCenterPresenter的实例,并且包含针对SyncAdapter的注入方法:
@Singleton @Component(modules = {DataManagerCenterModule.class, /* 你的其他Module */}) public interface AppComponent { // 添加针对SyncAdapter的注入方法 void inject(SyncAdapter syncAdapter); // 如果你需要直接提供Presenter实例,也可以添加,但这里Presenter构造方法已经用@Inject标注,组件会自动处理 SyncCenterPresenter provideSyncCenterPresenter(); }
同时,你的Application类需要持有AppComponent的实例,并对外提供获取方法:
public class MyApp extends Application { private AppComponent appComponent; @Override public void onCreate() { super.onCreate(); // 初始化Dagger组件 appComponent = DaggerAppComponent.builder() .dataManagerCenterModule(new DataManagerCenterModule()) // 传入其他必要的Module .build(); } public AppComponent getAppComponent() { return appComponent; } }
2. 在SyncAdapter的构造方法中完成注入
SyncAdapter的实例是由系统通过关联的SyncAdapterService创建的,而构造方法是我们能控制的第一个执行时机,在这里注入刚好能保证onPerformSync调用前,mSyncCenterPresenter已经初始化完成。修改你的SyncAdapter构造方法:
public SyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); mContentResolver = context.getContentResolver(); mAccountManager = AccountManager.get(context); this.context = context; // 核心:从Application获取Dagger组件,完成注入 ((MyApp) context.getApplicationContext()).getAppComponent().inject(this); }
3. 验证注入是否生效
现在当系统创建SyncAdapter实例时,Dagger会自动为你初始化mSyncCenterPresenter,你可以在onPerformSync中看到打印"not null",并且能正常调用loadDatabaseCenterPayload()和syncPayload()方法。
额外注意事项
- 因为SyncAdapter运行在后台线程,确保你的
SyncCenterPresenter及其依赖(比如DataManagerCenter)是线程安全的,或者在Presenter内部处理好线程切换(你的代码里已经用了RxJava的subscribeOn和observeOn,这部分没问题)。 - 如果你的SyncAdapter是手动实例化的(不推荐,通常由系统托管),也要在实例化后立即调用注入方法。
内容的提问来源于stack exchange,提问作者Falcon
相关产品推荐
相关产品推荐

