Как очистить стек истории активности при нажатии кнопки «Домой»?

Я пишу приложение, которое имеет два «режима»; один режим просмотра и один режим редактирования. Приложение предоставляет два основных действия/активности запуска (скажем, A и D), которые, в свою очередь, имеют свои собственные цепочки действий (B, C и E, F соответственно). Два действия точки входа A и D отобразят два значка с отдельными метками на главном экране, и две цепочки никогда не пересекаются, т. е. после запуска приложения в представлении режиме с действием A, единственный маршрут, по которому вы можете ходить туда и обратно, — это A, B, C, и если вы запускаете приложение в режиме редактирования с действием D, единственная доступная цепочка действий — D, E, F .

Теперь моя проблема в том, что если запустить приложение, например. режим просмотра (цепочка действий A, B, C) и нажмите кнопку «Домой» в любом действии в этой цепочке. Я возвращаюсь на главный экран. (конечно), но если я затем перезапущу приложение в режиме редактирования (цепочка действий D, E, F), я попаду в действие, которое я выполнял при нажатии кнопки «Домой» (то есть действие в неправильной цепочке) — не ожидаемая точка входа для режима редактирования; активность D.

Как решить эту проблему?

Я пробовал различные комбинации android:noHistory, android:clearTaskOnLaunch и других атрибутов в AndroidManifest.xml для задействованных действий. Но они, похоже, влияют только на саму деятельность, а не на всю цепочку.

Я хочу удалить всю цепочку действий (A, B, C или D, E, F) из стека истории при нажатии кнопки «Домой», но при этом сохранять стек неповрежденным, пока я все еще в цепочке (я хочу иметь возможность нажать кнопку «Назад» от, скажем, действия B и перейти к действию A).


person dbm    schedule 06.01.2012    source источник
comment
Вы должны следить за этим stackoverflow.com/questions/3473168/   -  person himanshu    schedule 06.01.2012
comment
@dbm : ты ищешь этот nisha113a5.blogspot.com?? вернуться   -  person Pratik Bhat    schedule 06.01.2012
comment
Привет @himanshu! Да, этот вопрос, вероятно, также привел бы меня к рабочему выводу. Спасибо за совет!   -  person dbm    schedule 08.01.2012
comment
Привет @android_hungry! Это решение, вероятно, сработает. Однако я не уверен, что выбрал бы его в качестве основной реализации. Для меня это немного похоже на темное творение, которое не работает на определенных устройствах. Это короткий путь, которым я не могу позволить себе роскошь.   -  person dbm    schedule 08.01.2012
comment
@dbm: да, ты прав, просто случайно просмотрел этот пост в тот же день, когда прочитал твой вопрос..   -  person Pratik Bhat    schedule 08.01.2012


Ответы (3)


Похоже, вам нужно использовать флаг Intent.FLAG_ACTIVITY_CLEAR_TOP в своих домашних действиях, но, конечно, вы не можете добавить эти флаги в файл AndroidManifest.xml. Возможно, у вас должна быть единая точка входа, которая затем запускает правильный Activity — вы можете использовать ссылку псевдоним активности, чтобы он выглядел как две точки входа для пользователя.

Например, вы определяете действия в файле манифеста:

   <activity-alias
        android:label="@string/edit_app_name"
        android:name="launch_edit"
        android:targetActivity=".activities.LaunchActivity">
        <meta-data android:name="launch_type" android:resource="@string/launch_edit" />
    </activity-alias>
    <activity-alias
        android:label="@string/view_app_name"
        android:name="launch_view"
        android:targetActivity=".activities.LaunchActivity">
        <meta-data android:name="launch_type" android:resource="@string/launch_view" />
    </activity-alias>

Затем в вашей LaunchActivity у вас есть:

ActivityInfo activityInfo = getPackageManager().getPackageInfo( this.getComponentName(), PackageManager.GET_ACTIVITIES|PackageManager.GET_META_DATA);
int launchTypeResource = activityInfo.metaData.getInt("launch_type");
String launchType = context.getString(launchTypeResource);
if(launchType == null) {
   // handle error
   throw new Exception();
}
Intent newIntent;
if(launchType.equals(context.getString(R.string.launch_view)) {
    newIntent = createIntent(ViewActivity.class);
} else if(launchType.equals(context.getString(R.string.launch_edit)) {
    newIntent = createIntent(EditActivity.class);
}
newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(newIntent);
person Martyn    schedule 06.01.2012
comment
Привет @Мартин! Я позволил себе немного изменить ваш фрагмент кода о том, как на самом деле получить метаданные, связанные с файлом activity-alias. Оказалось, что он не отправляется через вызывающий Intent, а считывается из структуры данных ActivityInfo. - person dbm; 08.01.2012
comment
Отличный ответ! Принимая во внимание количество усилий, которые вы приложили к этому, и тот факт, что ваш ответ был первым (правильным и рабочим, только что поставил вам зеленую галочку :-) - person dbm; 08.01.2012
comment
@Martyn, можете ли вы отредактировать свой ответ, чтобы он содержал правильное чтение данных? - person Ovidiu Latcu; 09.01.2012
comment
@OvidiuLatcu, я снова предложил предложенное мной исправление. К сожалению, у меня пока нет права редактировать вопросы/ответы других людей, поэтому я не могу сделать ничего большего, кроме как ждать обзора Мартина. - person dbm; 10.01.2012
comment
Извиняюсь - был в отпуске! :D Исправил код - спасибо, что указали. - person Martyn; 16.01.2012

Пожалуйста, используйте следующий метод при нажатии кнопки «Домой»:

Intent intent=new Intent(this, HomeClass.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
person jeet    schedule 06.01.2012
comment
Я предполагаю, что это будет самый простой способ решить мою проблему. Однако я буду использовать другую реализацию, которая на этот раз делает это решение не подходящим для моего приложения. Однако я кое-что узнал из вашего ответа, и за это я благодарю вас. - person dbm; 08.01.2012

Вы можете использовать только один Activity для каждой цепочки (это будут только A и D).

Затем внедрите содержимое A, B и C и D, E и F как фрагменты и просто измените фрагмент, показанный на Activity, при навигации вперед и назад.

Объедините это с android:noHistory, и вы должны получить желаемый эффект, хотя это потребует некоторой перезаписи и включения пакета совместимости в ваш проект, если вы планируете использовать версию ниже Honeycomb.

person kaspermoerch    schedule 06.01.2012
comment
На самом деле это было очень элегантное использование фрагментов, и, поскольку мое приложение уже построено из фрагментов, это даже не потребовало бы такой огромной переделки. Несмотря на то, что я думаю, что было справедливо принять ответ @Martyn, я думаю, что это архитектурный выбор, который я выберу в конце. Спасибо большое за идею! - person dbm; 08.01.2012