如何注入SyncAdapter
我刚开始学习如何使用Dagger,并且我已将自己的Backend
连接类转换为自动注入。如何注入SyncAdapter
该类处理Retrofit并执行网络请求。它曾经有过的静态方法,但现在它是一个对象,例如:
Backend.fetchPost(context, 42); // old way
mBackend.fetchPost(42); // mBackend is an injected field
上下文用于检索提供OAuth令牌与我的后端服务器的AccountManager
。这现在被自动注入。
在活动和片段中效果很好,但我无法弄清楚如何注入我的SyncAdapter
类。
事实上,它是一个我无法控制的框架对象,并且AndroidInjections
没有准备好注入这种类的静态方法。
下面是我想获得工作的代码:
/**
* Handle the transfer of data between the backend and the app, using the Android sync adapter framework.
*/
public class SyncAdapter extends AbstractThreadedSyncAdapter {
@Inject
public Backend mBackend; // can't use constructor injection,
// so might aswell use a public field
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {
super(context, autoInitialize, allowParallelSyncs);
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
List<Post> posts = mBackend.getPosts();
// do stuf with the posts
}
}
所以我知道我应该在构造函数中调用某个地方@#!.inject(this)
,但我完全不知道我应该如何做到这一点:
- 使用的应用程序类的静态字段检索依赖图的头,让它浏览它,直到它可以注入的所有字段
- 创建一个工厂类和接口,如FO使用的一个r活动和片段
- 别的东西?
更多关于我的dagger2实现细节:
-
的
Backend
类有一个@Inject
构造,所以匕首应该能够构建它,只要它可以得到API和GSON解析器的实例:@Inject public Backend(BackendApi api, @UploadGson Gson uploadGson) { mApi = api; mUploadGson = uploadGson; }
- 的
BackendModule
匕首模块具有@Provide
方法用于@UploadGson Gson
对象,并从依赖关系列表一个BackendApi
(改型)到应用程序类(通过各种对象,如注射器或记录器) - 的
BackendModule.class
在modules = {}
声明本申请的@Component
所以基本上被引用时,给定的应用对象,匕首应能够实例化类Backend
的对象,我想将其注入到我的SyncAdapter
类中。
我只是不知道如何实际触发注射。 PS:如上所述,我昨天学了匕首,所以请告诉我,如果你认为我的执行被破坏了,
我想我在这里过得太快。我认为,框架实例化我SyncAdapter
,但是我在做我自己:
public class SyncService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static SyncAdapter sSyncAdapter = null;
/**
* Instantiate the sync adapter object.
*/
@Override
public void onCreate() {
synchronized (sSyncAdapterLock) {
if (sSyncAdapter == null) {
sSyncAdapter = new SyncAdapter(getApplicationContext(), true); // bingo!
}
}
}
/**
* Return an object that allows the system to invoke the sync adapter.
*/
@Override
public IBinder onBind(Intent intent) {
return sSyncAdapter.getSyncAdapterBinder();
}
}
所以我只需要注入的服务,我完成了。以下是如何解决这个问题:
public class SyncService extends Service {
@Inject
SyncAdapter sSyncAdapter;
/**
* Instantiate the sync adapter object.
*/
@Override
public void onCreate() {
AndroidInjection.inject(this);
}
/**
* Return an object that allows the system to invoke the sync adapter.
*/
@Override
public IBinder onBind(Intent intent) {
return sSyncAdapter.getSyncAdapterBinder();
}
}
这里的同步适配器:默认的构造函数隐藏(不公开)和新的构造方法制作的匕首:它直接SyncService
预计为背景和注入后端和其他对象(在我的情况下,一个存储库类)。
public class SyncAdapter extends AbstractThreadedSyncAdapter {
private static final String TAG = SyncAdapter.class.getSimpleName();
private Backend mBackend;
private PostRepository mRepository;
@Inject
SyncAdapter(SyncService service, Backend backend, PostRepository repo) {
this(service, true);
mBackend = backend;
mRepository = repo;
}
private SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
新的子组件的服务注入:
@Subcomponent(modules = {})
public interface SyncServiceSubcomponent extends AndroidInjector<SyncService> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<SyncService> {
}
}
下面是引用子模块。它提供了SyncService
(和AuthenticatorService
,这是完全相同的行为实施)由SyncAdapter
构造(RESP Authenticator
)预计:
/**
* Used to provide/bind services with a factory
* Services can't be injected in the constructor so this is required
*/
@Module(subcomponents = {
SyncServiceSubcomponent.class,
AuthenticatorServiceSubcomponent.class,
})
public abstract class ServicesModule {
@Binds
@IntoMap
@ServiceKey(SyncService.class)
abstract AndroidInjector.Factory<? extends Service> bindSyncServiceInjectorFactory(SyncServiceSubcomponent.Builder builder);
@Binds
@IntoMap
@ServiceKey(AuthenticatorService.class)
abstract AndroidInjector.Factory<? extends Service> bindAuthenticatorServiceInjectorFactory(AuthenticatorServiceSubcomponent.Builder builder);
}
所以同步适配器具有以下依存关系:
- 同步服务:由
ServicesModule
提供 - 后端,存储库等:应用程序逻辑
- 服务注入:子组件
也许这可以帮助某人。