Я в тупике. Я использую Dagger 2 для инъекций зависимостей, но я теряю состояние, когда приложение переходит в фоновый режим. Вот сценарий: приложение запускается и создает зависимости. Все работает отлично, пока приложение остается на переднем плане. Однако есть сценарий, когда приложение должно заходить в фоновый режим. Когда он возвращается, значения, хранящиеся в одном из моих введенных классов, теряются.Кинжал 2 Сохранение и восстановление состояния при остановке активности
Для моих введенных классов, которые не имеют собственных зависимостей, все, кажется, восстанавливается правильно. Тем не менее, есть один введенный класс, у которого есть вложенная зависимость, и это тот, который не восстанавливается. Вот как я устанавливаю его:
AppComponent.java
@Singleton
@Component(
modules = {
AppModule.class
}
)
public interface AppComponent {
SessionKeyExchangerService provideSessionKeyExchangerService();
AESCipherService provideCipherService();
void inject(LoginActivity loginActivity);
}
AppModule.java
@Module
public class AppModule {
@Provides @Singleton
AESCipherService provideCipherService() {
return new AESCipherService();
}
@Provides @Singleton
SessionKeyExchangerService provideSessionKeyExchangerService(AESCipherService service) {
return new SessionKeyExchangerService(service);
}
}
А потом, когда я иду, чтобы ввести эту зависимость, я это делаю например:
LoginActivity.java
@Inject
SessionKeyExchangerService sessionKeyExchangerService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Injector.INSTANCE.getAppComponent().inject(this);
if (savedInstanceState != null) {
sessionKeyExchangerService = savedInstanceState.getParcelable(SESSION_KEY_PARCEL);
Log.d(Constants.TAG, "session key retrieved in on create: " + sessionKeyExchangerService.getCipherService().getBase64EncodedSessionKey());
}
}
Итак, мой фундаментальный вопрос заключается в том, чтобы поддерживать состояние Dagger 2 нагнетаемый класса. Я рад поделиться больше кода, но это основная идея.
Спасибо за любую помощь.
EDIT Предполагая, что я сделал выше в порядке, позвольте мне перейти к тому, как я сохранять и извлекать значения, хранящиеся в этих инжектированных объектов. Это покажет, что есть проблема где-то.
Когда я ухожу на задний план, а затем возвращаюсь, я вижу, что получаю новый PID. Я также могу видеть, что я могу правильно хранить и получать введенные значения в классе LoginActivity. Однако другие классы, которые также имеют ссылку на введенное значение , теперь имеют разные значения, что означает, что их ссылка относится к другой ячейке памяти, не так ли?
Мое лучшее предположение о том, где я ошибаюсь, находится в LoginActivity onCreate, где я восстанавливаю значение sessionKeyExchangerService
из сохраненной посылки. Я думаю, что я создаю новые значения, которые не распознаются в приложении, как вложенные зависимости, но я не знаю, почему это неправильно или как это исправить.
Этот код также в LoginActivity.java:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(SESSION_KEY_PARCEL, sessionKeyExchangerService);
Log.d(Constants.TAG, "session key saved: " + sessionKeyExchangerService.getCipherService().getBase64EncodedSessionKey());
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
sessionKeyExchangerService = savedInstanceState.getParcelable(SESSION_KEY_PARCEL);
Log.d(Constants.TAG, "session key retrieved in on restore state: " + sessionKeyExchangerService.getCipherService().getBase64EncodedSessionKey());
}
Вот вывод на консоль, которая иллюстрирует проблему. Примечание 1), как изменяется PID после onStop()
называется, и 2), как класс Authenticator
(который имеет ссылку на AESCipherService
имеет другое значение ключа сеанса:
1398-1398/com.mysite.myapp Д/MYTAG: при сохранении состояния экземпляра
1398-1398/com.mysite.myapp D/MYTAG: сохранен ключ сеанса: 93Zuy8B3eos + eCfBQk9ErA ==
1398-1398/com.mysite.MyApp D/MyTag: на остановки
3562-3562/com.mysite.myapp D/MyTag: ключ сеанса извлекаться в на создание: 93Zuy8B3eos + eCfBQk9ErA ==
3562-3562/com.mysite.myapp D/MyTag: при запуске
3562-3562/com.mysite.myapp D/MYTAG: ключ сеанса восстановлен в состоянии восстановления: 93Zuy8B3eos + eCfBQk9ErA ==
3562-3562/com.mysite.myapp D/MYTAG: класс аутентификатора говорит, что ключ сеанса: 28HwdRCjBqH3uFweEAGCdg ==
SessionKeyExchangerService.java
protected SessionKeyExchangerService(Parcel in) {
notifyOn = in.readString();
sessionKeyExchangeAttempts = in.readInt();
MAX_SESSION_KEY_EXCHANGE_ATTEMPTS = in.readInt();
sessionKeyExchangeHasFailed = (in.readByte() == 1);
cipherService = in.readParcelable(AESCipherService.class.getClassLoader());
}
public static final Creator<SessionKeyExchangerService> CREATOR = new Creator<SessionKeyExchangerService>() {
@Override
public SessionKeyExchangerService createFromParcel(Parcel in) {
return new SessionKeyExchangerService(in);
}
@Override
public SessionKeyExchangerService[] newArray(int size) {
return new SessionKeyExchangerService[size];
}
};
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(notifyOn);
dest.writeInt(sessionKeyExchangeAttempts);
dest.writeInt(MAX_SESSION_KEY_EXCHANGE_ATTEMPTS);
dest.writeByte((byte) (hasSessionKeyExchangeFailed() ? 1 : 0));
dest.writeParcelable(cipherService, flags);
}
AESCipherService.java
protected AESCipherService(Parcel in) {
sessionKeyBytes = in.createByteArray();
ivBytes = in.createByteArray();
sessionId = in.readLong();
mIsSessionKeyEstablished = (in.readByte() == 1);
verbose = (in.readByte() == 1);
}
public static final Creator<AESCipherService> CREATOR = new Creator<AESCipherService>() {
@Override
public AESCipherService createFromParcel(Parcel in) {
return new AESCipherService(in);
}
@Override
public AESCipherService[] newArray(int size) {
return new AESCipherService[size];
}
};
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByteArray(sessionKeyBytes);
dest.writeByteArray(ivBytes);
dest.writeLong(sessionId);
dest.writeByte((byte) (isSessionKeyEstablished() ? 1 : 0));
dest.writeByte((byte) (verbose ? 1 : 0));
}
Можете ли вы предоставить код, в котором вы вводите свою деятельность, а также где вы строите график? – Ognyan
Я как раз возвращаюсь к этому вопросу. Я переписал вопрос, чтобы сосредоточиться на том, как я настроил инъекцию зависимостей, а не сравнительные. Я довольно уверен, что правильно делаю эту часть, поэтому ошибка должна быть в части Dagger 2. – Alex
Я считаю, что вам нужно будет сериализовать состояние того, что вы предоставляете в своем модуле, с помощью 'onSaveInstanceState()' и взломать его обратно в 'onRestoreInstanceState()', учитывая, что процесс смерти убивает весь процесс подачи заявки, и выживают только пакеты. Вероятно, вам нужно будет создать свой компонент в 'onRestoreInstanceState()', если он не существует, и вернуть его один раз, создав свои зависимости через методы предоставления компонентов. – EpicPandaForce