Слабая ссылка на активность (Android) - PullRequest
1 голос
/ 10 сентября 2010

В моем приложении для 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 сервера, указывающий, что учетные данные пользователя больше не действительны.Я не хочу добавить логику к каждому действию, чтобы обрабатывать их проверку и возобновлять обычную работу после их завершения.Это нарушение СУХОГО и подвержено ошибкам в командной среде.

1 Ответ

4 голосов
/ 10 сентября 2010

Это звучит нормально?

Я бы никогда не использовал эту технику. Изменяемые статические члены данных опасны, несмотря на WeakReference. В частности, я ожидаю, что это потерпит неудачу, если пользователь сделает немыслимое и, скажем, использует свой телефон в качестве телефона или иным образом покинет поток ваших приложений на длительный период времени. Ваши действия могут быть уничтожены, а ваш процесс остановлен, чтобы освободить ОЗУ, однако действия останутся в задании и могут быть возобновлены. В этот момент ваше состояние ненормально, потому что статика обстреляна.

Есть ли потенциальные проблемы с утечкой памяти при использовании этого метода?

Вы пропускаете Intent.

Есть ли лучший способ сделать это?

В целях оставшейся части этого ответа я буду называть вашу отправную точку как Действие A, «некоторое другое действие» как Действие B, а желаемый конец - как Действие C. Итак, в вашем коде , newActivityIntent для Деятельности C, blockingIntent для Деятельности B и currentActivity для Деятельности A.

Вариант № 1: Поместите процесс принятия решений в действие C, а не в действие A. Пусть действие C проверит условие в onCreate() и немедленно вызовет startActivity() для действия B, если условия требуют отображения действия B .

Вариант № 2: Оставить процесс принятия решения в Деятельности A, но передать логическое значение (например, true для «мы должны показать Мероприятие B») в дополнительном Intent для вызова startActivity() для Деятельности C. Упражнение C проверяет логическое значение в onCreate() и немедленно вызывает startActivity() для действия B, если логическое значение говорит об этом.

В этих вариантах вы избегаете статики.

...