В моем приложении для Android, когда пользователь пытается перейти от одного действия к другому, может быть какое-то глобальное состояние, которое указывает, что им нужно сначала выполнить некоторые другие действия.
Для этого я написал класс со следующим кодом:
private static WeakReference<Activity> oldActivityReference;
private static Intent waitingIntent;
public static void pushActivity(Activity currentActivity, Intent newActivityIntent) {
Intent blockingIntent = ThisClass.getBlockingActivity();
if (blockingIntent != null) {
ThisClass.oldActivityReference = new WeakReference<Activity>(currentActivity);
ThisClass.waitingIntent = newActivityIntent;
currentActivity.startActivity(blockingIntent);
return;
}
currentActivity.startActivity(newActivityIntent);
}
Когда завершающая операция заканчивается, она вызывает ThisClass.blockingActivityFinished(). Это проверит, будет ли слабая ссылка на старую активность все еще существовать и, если это так, запустить исходное намерение из этого действия. Если нет, он запустит исходное намерение из моего контекста приложения.
Мой вопрос:
Звучит ли это здорово? Существуют ли какие-либо потенциальные проблемы с утечкой памяти с помощью этой техники? Есть ли лучший способ достичь этого?
РЕДАКТИРОВАТЬ - Чтобы быть ясным, типы событий, которые могут вызвать прерывание, это: 1) пинг сервера, указывающий, что текущая версия приложения устарела. 2) любой RPC сервера, указывающий, что учетные данные пользователя больше не действительны. Я не хочу добавлять логику к каждой Деятельности, чтобы обрабатывать ее проверку и возобновлять бизнес, как обычно, после завершения. Это нарушение СУХОЙ и подвержено ошибкам в командной среде.
Звучит ли это правильно?
Я бы никогда не использовал эту технику. Могучие статические элементы данных опасны, WeakReference
несмотря на это. В частности, я ожидаю, что это провалится, если пользователь сделает немыслимое и, скажем, использует свой телефон в качестве телефона или иным образом оставляет поток приложений в течение длительного периода времени. Ваши действия могут быть уничтожены, а ваш процесс завершен, чтобы освободить оперативную память, но действия будут оставаться в задаче и могут быть возобновлены. В этот момент ваше состояние ударило, потому что статика получила нук.
Существуют ли какие-либо потенциальные проблемы с утечкой памяти с помощью этой техники?
У вас утечка Intent
.
Есть ли лучший способ сделать это?
В целях остальной части этого ответа я буду ссылаться на вашу отправную точку как на активность A, на "какое-то другое действие" как на активность B, а желаемый конец - на активность C. Итак, в вашем коде, newActivityIntent
- для операции C, blockingIntent
- для активности B, а currentActivity
- активность A.
Вариант №1: Поместите процесс принятия решений в действие C, а не на операцию A. Запустите операцию C, проверьте условие в onCreate()
и немедленно вызовите startActivity()
для операции B, если условия требуют, чтобы активность B отображалась.
Вариант № 2: Оставьте процесс принятия решений в Activity A, но передайте логическое значение (например, true
для "мы должны показать Activity B" ) в Intent
extra для вызова startActivity()
для Activity C. Активность C проверяет логическое значение в onCreate()
и сразу вызывает startActivity()
для Activity B, если это так.
В этих вариантах вы избегаете статики.