Я использую Sync Adapter вместе с Dagger 2 для внедрения зависимостей. Я застрял, так как не могу понять, где мне использовать XYZ.inject, поскольку класс SyncAdapter не предоставляет OnCreate или Activity, которых можно придерживаться. Может ли кто-нибудь предложить, как бороться с инъекцией зависимостей в случае классов Sync Adapter, которые не принадлежат к активности / фрагменту? PS: Я рассмотрел несколько похожих вопросов, но не смог найти решения своей проблемы.
SyncAdapter.java
public class SyncAdapter extends AbstractThreadedSyncAdapter {
ContentResolver mContentResolver;
//Injects here
@Inject
SyncCenterPresenter mSyncCenterPresenter;
private final AccountManager mAccountManager;
Context context;
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
mContentResolver = context.getContentResolver();
mAccountManager = AccountManager.get(context);
this.context=context;
}
Account mainAccount;
public static final int SYNC_INTERVAL = 60 * 1;
public static final int SYNC_FLEXTIME = SYNC_INTERVAL/3;
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.v("Sync class me","sync adapter on perform sync");
if (mSyncCenterPresenter == null){
Log.v("messsage","null");
} else {
Log.v("messsage","not null");
mSyncCenterPresenter.loadDatabaseCenterPayload();
mSyncCenterPresenter.syncPayload();
}
}
/**
* Helper method to schedule the sync adapter periodic execution
*/
public static void configurePeriodicSync(Context context, int syncInterval, int flexTime) {
Account account = myAccount;
String authority = "com.mifos.provider";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// we can enable inexact timers in our periodic sync
SyncRequest request = new SyncRequest.Builder().
syncPeriodic(syncInterval, flexTime).
setSyncAdapter(account, authority).
setExtras(new Bundle()).build();
ContentResolver.requestSync(request);
} else {
ContentResolver.addPeriodicSync(account,
authority, new Bundle(), syncInterval);
}
}
static Account myAccount;
public static void onAccountCreated(Account newAccount, Context context) {
/*
* Since we've created an account
*/
myAccount = newAccount;
SyncAdapter.configurePeriodicSync(context, SYNC_INTERVAL, SYNC_FLEXTIME);
/*
* Without calling setSyncAutomatically, our periodic sync will not be enabled.
*/
ContentResolver.setSyncAutomatically(newAccount, "com.mifos.provider", true);
/*
* Finally, let's do a sync to get things started
*/
syncImmediately(context);
}
public static Account getSyncAccount(Context context) {
// Create the account type and default account
Account newAccount = new Account(
context.getString(R.string.app_name), "com.mifos");
return newAccount;
}
/**
* Helper method to have the sync adapter sync immediately
* @param context The context used to access the account service
*/
public static void syncImmediately(Context context) {
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(getSyncAccount(context),
"com.mifos.provider", bundle);
}
}
SyncCenterPresenter.java
public class SyncCenterPresenter {
private final DataManagerCenter mDataManagerCenter;
private CompositeSubscription mSubscriptions;
List<CenterPayload> centerPayloads;
int mCenterSyncIndex = 0;
@Inject
public SyncCenterPresenter(DataManagerCenter dataManagerCenter) {
Log.v("messsage","const me");
mDataManagerCenter = dataManagerCenter;
mSubscriptions = new CompositeSubscription();
centerPayloads = new ArrayList<>();
}
public void loadDatabaseCenterPayload() {
Log.v("messsage","load me");
mSubscriptions.add(mDataManagerCenter.getAllDatabaseCenterPayload()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<List<CenterPayload>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<CenterPayload> centerPayloads) {
showCenters(centerPayloads);
}
}));
}
public void syncCenterPayload(CenterPayload centerPayload) {
mSubscriptions.add(mDataManagerCenter.createCenter(centerPayload)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Observer<SaveResponse>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(SaveResponse center) {
showCenterSyncResponse();
}
}));
}
public void deleteAndUpdateCenterPayload(int id) {
mSubscriptions.add(mDataManagerCenter.deleteAndUpdateCenterPayloads(id)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Observer<List<CenterPayload>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<CenterPayload> centerPayloads) {
showPayloadDeletedAndUpdatePayloads(centerPayloads);
}
}));
}
public void showCenters(List<CenterPayload> centerPayload) {
centerPayloads = centerPayload;
}
public void showCenterSyncResponse() {
deleteAndUpdateCenterPayload(centerPayloads
.get(mCenterSyncIndex).getId());
}
public void showPayloadDeletedAndUpdatePayloads(List<CenterPayload> centers) {
mCenterSyncIndex = 0;
this.centerPayloads = centers;
}
public void syncPayload() {
for (int i = 0; i < centerPayloads.size(); ++i) {
if (centerPayloads.get(i).getErrorMessage() == null) {
syncCenterPayload(centerPayloads.get(i));
mCenterSyncIndex = i;
break;
} else {
Log.v("messsage","else block");
}
}
}
}
ActivityComponent
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules =
ActivityModule.class)
public interface ActivityComponent {
void inject(LoginActivity loginActivity);
void inject(PassCodeActivity passCodeActivity);
//other methods
void inject(SyncAdapter syncAdapter);
}
ActivityModule
@Module
public class ActivityModule {
private Activity mActivity;
public ActivityModule(Activity activity) {
mActivity = activity;
}
@Provides
Activity provideActivity() {
return mActivity;
}
@Provides
@ActivityContext
Context providesContext() {
return mActivity;
}
}
РЕДАКТИРОВАТЬ SyncService.java
public class SyncService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static SyncAdapter sSyncAdapter = null;
@Override
public void onCreate() {
synchronized (sSyncAdapterLock) {
if (sSyncAdapter == null) {
sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
}
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return sSyncAdapter.getSyncAdapterBinder();
}
}
Может ли кто-нибудь помочь мне заставить это работать? поскольку я не могу понять, где использовать инъекцию и как это сделать без компонента деятельности? Также будет оценен другой и лучший подход. Спасибо




Вы можете реализовать конструктор, поэтому, пожалуйста, использовать инъекцию конструктора для инициализации вашего адаптера.
public class SyncAdapter extends AbstractThreadedSyncAdapter {
// ...
@Inject
public SyncAdapter(Context context, boolean autoInitialize) { /*...*/ }
}
Затем вы просто вставляете службу, которая возвращает SyncAdapter, как и все остальное ...
public class SyncService extends Service {
@Inject SyncAdapter syncAdapter;
@Override
public void onCreate() {
AndroidInjection.inject(this);
// or
DaggerSyncServiceComponent.create().inject(this);
}
@Override
public IBinder onBind(Intent intent) {
return syncAdapter;
}
}
Вот и все.
@Falcon AndroidInjection предназначен для случаев, когда вы используете dagger.android, DaggerSyncServiceComponent следует заменить любым компонентом, который вы хотите использовать для внедрения своей службы. Просто введите его, как если бы вы делали свою деятельность и т. д.
Спасибо за ответ, попробую. Есть ли альтернативный способ сделать это без использования dagger.android в gradle, поскольку это проект с открытым исходным кодом, и я не хочу ничего ломать, и добавление dagger.android дало мне много ошибок.
@Falcon Вы можете использовать любой из ваших компонентов, чтобы внедрить его или создать для него новый, выделенный. В конце концов, вам просто нужно вызвать someComponent.inject(this), чтобы ввести поля.
Не удается разрешить символ AndroidInjection или DaggerSyncServiceComponent. Что мне не хватает?