Попросить, чтобы Кинжал повторно ввел пост строительства?

У меня есть активность, которая делает начальный ввод, чтобы получить некоторые значения. Затем он подписывается (конечно, используя Otto) на изменения из IntentService (который выполняет простую синхронизацию с моим внутренним сервером). После этого он начинает выполнять некоторую обработку со значениями из базы данных, которых у него не было изначально (т.е. во время создания).

По сути, я хочу попросить Кинжал сделать "повторную инъекцию" для модуля из-за обновленной информации из-за внешних обстоятельств.

В настоящее время я внедряю класс родительского модуля, а затем вручную снова вызываю метод обеспечивает, чтобы получить последнюю информацию.

Вот как выглядит мой модуль

@Module(
    injects = { MyActivity.class}
)
public class SessionModule {

    private Event _currentEvent;

    @Provides
    @Singleton
    SessionModule provideSessionModule() {
        return this;
    }

    @Provides
    @Singleton
    @Named("current")
    public Event provideCurrentEvent() {

        if (_currentEvent == null) {
            _currentEvent = getCurrentEvent_fromStoredPreferencesId();
        }

        if (_currentEvent == null) {
            _currentEvent = getCurrentEvent_fromFirstEventInDatabase();
        }

        return _currentEvent;
    }

    private Event getCurrentEvent_fromStoredPreferencesId() {
        return Event.findEventById(SharedPrefs.getIntPref(KEY_CURRENT_EVENT_ID));
    }

    private Event getCurrentEvent_fromFirstEventInDatabase() {
        List<Event> events = Event.getAll();

        if (events.isEmpty()) {
            return null;
        }

        Event firstEvent = events.get(0);
        PkkSharedPreferencesHelper.setIntPref(KEY_CURRENT_EVENT_ID, firstEvent.getId());
        return firstEvent;
    }

    public void clearAllSessionInformation() {
        _currentEvent = null;
        _currentUser = null;
    }
}

И теперь в моей деятельности происходит следующее:

public class MyActivity
    extends BaseActivity {

    @Inject @Named("current") Event _currentEvent;
    @Inject SessionModule _session;

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

        // ...
        MyApp.get(this).inject(this);
        getBus().register(this);
        // ...

        // _currentEvent is null, because SharedPrefs & Db both don't have any info yet.

        startAnIntentService_ForSyncingLatestData();
    }

    // ...

    @Subscribe
    public void onSyncFinished(SyncIntentService.SyncFinishedEvent syncFinishedEvent) {

        assert(_currentEvent == null);  // arr.. _currentEvent is null

        // because the database populated some events only "after" the sync
        // and didn't have anything when Dagger did the initial bootstrap/injection.

        // manually get the event from the @Module
        _currentEvent = _session.provideCurrentEvent();

        assert(_currentEvent != null);
    }
}

Это работает, но:

  • Есть ли какой-нибудь метод, который я могу сделать, чтобы "запустить" повторную инъекцию?
  • Я в основном использую Dagger неправильно или это справедливая игра?
  • Если это неправильная стратегия, есть ли лучшая для решения этого конкретного случая?

1 ответ

Решение

Кошик,

Вы можете использовать инъекцию в конструктор, напрямую обращаясь к графу объектов и передавая класс, который вы запрашиваете, в данном случае, Event.

Хотя это был бы способ повторно внедрить объект, я не думаю, что это хороший вариант использования для Dagger, вам лучше создавать этот класс во время выполнения. Разве есть веская причина использовать Dagger в этом случае?

Крис

Другие вопросы по тегам