Закінчіть діяльність з іншої діяльності


101

Я хочу закінчити одну діяльність з іншої діяльності, наприклад:

У розділі Діяльність [A] при натисканні кнопки я викликаю активність [B], не закінчуючи активність [A].

Зараз у діяльності [B] є дві кнопки: Нова та Модифікація . Коли користувач натискає на модифікацію, тоді виведіть активність [A] зі стека з усіма параметрами, що відмічаються ..

Але коли користувач натисне кнопку " Нова" з "Діяльність [B]", тоді мені доведеться закінчити "Активність" [A] зі стека і знову перезавантажити цю активність [A] в стек.

Я намагаюся це зробити, але я не в змозі закінчити Activity [A] зі стека ... Як це зробити?

Я використовую код як:

З діяльності [A]:

Intent GotoB = new Intent(A.this,B.class);
startActivityForResult(GotoB,1);

Ще один метод у тій же діяльності

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == 1)
    {
        if (resultCode == 1) {
            Intent i = getIntent();
            overridePendingTransition(0, 0);
            i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();

            overridePendingTransition(0, 0);
            startActivity(i);
        }
    }
}

І в діяльності [B] натисніть кнопку:

setResult(1);
finish();

Ей, ти хотів закінчити одну діяльність з іншого праворуч ... тоді я опублікував відповідь, яка є правильною. Але, чому ти проголосив це?
Манджунат

Тут є нитка з кількома приємними відповідями: stackoverflow.com/questions/14355731/…
ab

Відповіді:


189
  1. Зробіть свою діяльність A у файлі маніфесту: launchMode = "singleInstance"

  2. Коли користувач натискає нове, зробіть FirstActivity.fa.finish();і зателефонуйте новій намірі.

  3. Коли користувач натискає зміни, зателефонуйте до нового наміру або просто закінчіть діяльність B.

ПЕРШИЙ ШЛЯХ

У першій своїй діяльності заявіть про Activity objectподібне,

public static Activity fa;
onCreate()
{
    fa = this;
}

тепер використовуйте цей об’єкт в іншому, Activityщоб закінчити першу діяльність, як це,

onCreate()
{
    FirstActivity.fa.finish();
}

ДРУГИЙ ШЛЯХ

Під час виклику своєї діяльності, FirstActivityяку ви хочете закінчити, як тільки рухаєтесь далі, ви можете додавати прапор під час дзвінкаFirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Але використовуючи цей прапор, активність буде готовою, якщо ви цього не хочете. а onBackколи- небудь, якщо ви хочете показати, FirstActivityвам доведеться зателефонувати, використовуючи наміри.


6
Чудова відповідь .. !!
Вайбхав Ваджані

93
Ви зберігаєте статичну посилання на діяльність. Це ніколи не піде, якщо ви не очистите його вручну звідкись -> ви створюєте витік пам'яті!
DArkO

5
Ну добре, у вас є мій +1 для нестандартного мислення: D, я б просто змінився на SingleTop. однак це все одно не буде моїм першим вибором, коли я роблю щось подібне. під кодом очищення я мав на увазі спосіб позбутися статичної довідки, щоб не було протікання пам’яті, але це залежить від структури програми.
DArkO

6
Будь ласка, ніхто не використовує перше рішення, це абсолютно неправильно. Ви обходите рамку Android по-справжньому хакі, створюючи об’єкт зомбі. Використовуйте широкомовний приймач.
S-K

1
Дивовижні рішення. Дуже добре працював над моєю проблемою, в якій я переходив від діяльності A-> B-> C і onBackPress з C, я запускав новий екземпляр B. Але тоді, якщо я зробив onBackPress на новому екземплярі B, він раніше перейти до старого екземпляра B замість старого екземпляра A (чого я хотів). Тому я дотримувався вашого першого методу в onBackPress з C, і це дало мені поведінку, яку я хотів :) Дякую тонну :)
SoulRayder

87

Це ви можете зробити, але я думаю, ви не повинні порушувати нормальний потік діяльності. Якщо ви хочете закінчити свою діяльність, ви можете просто надіслати трансляцію зі своєї діяльності B на активність A.

Створіть приймач широкомовної програми перед початком своєї діяльності B:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context arg0, Intent intent) {
        String action = intent.getAction();
        if (action.equals("finish_activity")) {
            finish();
            // DO WHATEVER YOU WANT.
        }
    }
};
registerReceiver(broadcastReceiver, new IntentFilter("finish_activity"));

Надішліть трансляцію з активності B на активність A, коли ви хочете закінчити діяльність A з B

Intent intent = new Intent("finish_activity");
sendBroadcast(intent);

Сподіваюся, це спрацює для вас ...


Він показує цю помилку "Синтаксична помилка на лексемах; очікується замість AnnotationName" на "registerReceiver (Broadcast_reciever, новий IntentFilter (" закінчити_активність "));". Що не так?
Бехзад

2
"Ви не повинні порушувати нормальний потік діяльності" +1 для цього
S-K

11
Не забудьте скасувати реєстрацію broadcast_receiverзunregisterReceiver()
Jaec


Це рішення. приємний
Парінда Раджапакша

17

Це досить стандартне питання спілкування. Одним із підходів буде використання ResultReceiver у діяльності A:

Intent GotoB=new Intent(A.this,B.class);
GotoB.putExtra("finisher", new ResultReceiver(null) {
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        A.this.finish();
    }
});
startActivityForResult(GotoB,1);

а потім у Activity B ви можете просто закінчити його на вимогу так:

((ResultReceiver)getIntent().getExtra("finisher")).send(1, new Bundle());

Спробуйте щось подібне.


6
+1 просто, ((ResultReceiver) getIntent (). GetParcelableExtra ("фінішер")). Send (1, новий Bundle ());
Хамідреза Садег

12

Є один підхід, який ви можете використовувати у вашому випадку.

Крок 1: Почніть активність B з діяльності A

startActivity(new Intent(A.this, B.class));

Крок 2: Якщо користувач натискає на кнопку змінити, запустіть Активність A, використовуючи FLAG_ACTIVITY_CLEAR_TOP. Так само, передайте прапор додатково.

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "modify");
startActivity(i);
finish();

Крок 3: Якщо користувач натискає кнопку "Додати", запустіть "Активність", використовуючи FLAG_ACTIVITY_CLEAR_TOP. FLAG_ACTIVITY_CLEAR_TOPочистить всі відкриті дії до цілі та перезапустить, якщо в цільовій діяльності не визначений режим запуску

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "add");
startActivity(i);
finish();

Крок 4: Тепер onCreate()методом діяльності А потрібно отримати цей прапор.

String flag = getIntent().getStringExtra("flag");
if(flag.equals("add")) {
    //Write a code for add
}else {
    //Write a code for modifying
}


5

Дивіться мою відповідь на питання переповнення стека Завершити Усі попередні дії .

Що вам потрібно - це додати Intent.FLAG_CLEAR_TOP. Цей прапор гарантує, що всі дії над цільовою активністю в стеку завершені, і те, що відображається.

Ще одна річ, яка вам потрібна - це SINGLE_TOP прапор. За допомогою цього ви запобігаєте Android створювати нову активність, якщо в стеку вже створена така.

Просто будьте обережні, що якщо діяльність вже створена, наміри з цими прапорами будуть доставлені методом, який називається onNewIntent(intent)(вам потрібно перевантажити його для обробки) у цільовій діяльності.

Тоді у onNewIntentвас є метод, який називається перезапуск або щось, що викликатиме finish()і запускає новий намір до себе, або є repopulate()метод, який встановлює нові дані. Я вважаю за краще другий підхід, він дешевший, і ви завжди можете витягнути onCreateлогіку в окремий метод, який ви можете закликати для заповнення.


4

Я щойно застосував рішення Непстера і працює як шарм. Існує незначна модифікація, щоб запустити його з фрагмента.

До вашого Фрагменту

// sending intent to onNewIntent() of MainActivity
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("transparent_nav_changed", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

А до вашого OnNewIntent () діяльності ви хочете перезапустити.

// recreate activity when transparent_nav was just changed
if (getIntent().getBooleanExtra("transparent_nav_changed", false)) {
    finish(); // finish and create a new Instance
    Intent restarter = new Intent(MainActivity.this, MainActivity.class);
    startActivity(restarter);
}

2

Я думаю, що у мене найпростіший підхід ... про натискання нового в B ..

Intent intent = new Intent(B.this, A.class);
intent.putExtra("NewClicked", true);
 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

і в А отримаєте це

  if (getIntent().getBooleanExtra("NewClicked", false)) {
        finish();// finish yourself and make a create a new Instance of yours.
      Intent intent = new Intent(A.this,A.class);
      startActivity(intent);
    }

1

Я знаю, що це давнє запитання, деякі з цих методів не спрацювали для мене, тому для тих, хто дивиться в майбутнє або має мої проблеми, це спрацювало для мене

Я переоцінив onPauseі закликав finish()всередину цей метод.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.