Selesaikan satu aktivitas dari aktivitas lain

101

Saya ingin menyelesaikan satu aktivitas dari aktivitas lain, seperti:

Dalam Aktivitas [A], saat mengklik tombol, saya memanggil Aktivitas [B] tanpa menyelesaikan Aktivitas [A].

Sekarang di Activity [B], ada dua tombol, New dan Modify . Saat pengguna mengklik ubah, lalu keluarkan aktivitas [A] dari tumpukan dengan semua opsi dicentang ..

Tetapi ketika pengguna mengklik tombol Baru dari Aktivitas [B], maka saya harus menyelesaikan Aktivitas [A] dari tumpukan dan memuat ulang Aktivitas [A] itu lagi ke tumpukan.

Saya mencobanya, tetapi saya tidak dapat menyelesaikan Aktivitas [A] dari tumpukan ... Bagaimana cara melakukannya?

Saya menggunakan kode sebagai:

Dari Aktivitas [A]:

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

Metode lain dalam aktivitas yang sama

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);
        }
    }
}

Dan di Aktivitas [B], saat mengklik tombol:

setResult(1);
finish();
Kanika
sumber
hei, Anda ingin menyelesaikan satu aktivitas dari yang lain kan ... maka saya telah memposting jawaban yang benar. Tapi, mengapa Anda memilihnya?
Manjunath
Ada utas dengan beberapa jawaban bagus di sini: stackoverflow.com/questions/14355731/…
ab

Jawaban:

189
  1. Jadikan aktivitas A Anda dalam file manifes: launchMode = "singleInstance"

  2. Saat pengguna mengklik baru, lakukan FirstActivity.fa.finish();dan panggil Intent baru.

  3. Saat pengguna mengklik ubah, panggil Intent baru atau cukup selesaikan aktivitas B.

CARA PERTAMA

Dalam aktivitas pertama Anda, nyatakan yang Activity objectseperti ini,

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

sekarang gunakan objek itu di tempat lain Activityuntuk menyelesaikan aktivitas pertama seperti ini,

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

CARA KEDUA

Saat memanggil aktivitas FirstActivityAnda yang ingin Anda selesaikan segera setelah Anda melanjutkan, Anda dapat menambahkan bendera saat meneleponFirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Tetapi dengan menggunakan flag ini, aktivitas akan selesai meskipun Anda tidak menginginkannya. dan terkadang onBackjika Anda ingin menunjukkannya, FirstActivityAnda harus memanggilnya menggunakan maksud.

MKJParekh
sumber
6
Jawaban yang bagus .. !!
Vaibhav Vajani
93
Anda memegang referensi statis ke suatu aktivitas. Ini tidak akan pernah hilang kecuali Anda menghapusnya secara manual dari suatu tempat -> Anda membuat kebocoran memori!
DArkO
5
Tidak apa-apa, Anda memiliki +1 untuk pemikiran out-of-the-box: D, saya hanya akan mengubah ke singleTop. Namun itu tetap bukan pilihan pertama saya ketika melakukan sesuatu yang serupa. dengan kode pembersihan yang saya maksud adalah cara untuk menyingkirkan referensi statis sehingga tidak ada kebocoran memori, tetapi itu tergantung pada struktur aplikasi.
DArkO
6
Harap tidak ada yang menggunakan solusi pertama, itu sepenuhnya salah. Anda melewati kerangka Android dengan cara yang benar-benar hack saat membuat objek zombie. Gunakan BroadcastReceiver.
S-K '
1
Solusi luar biasa. Bekerja dengan sangat baik untuk masalah saya di mana saya beralih dari aktivitas A-> B-> C dan onBackPressed dari C, saya meluncurkan instance baru B. Tapi kemudian jika saya melakukannya diBackPressed pada instance baru B itu, biasanya buka contoh lama B, bukan contoh lama A (yang saya inginkan). Jadi saya mengikuti metode pertama Anda di onBackPressed of C, dan itu memberi saya perilaku yang saya inginkan :) Terima kasih banyak :)
SoulRayder
87

Itu bisa Anda lakukan, tetapi saya pikir Anda tidak boleh merusak aliran aktivitas normal. Jika Anda ingin menyelesaikan aktivitas Anda, maka Anda cukup mengirim siaran dari aktivitas B Anda ke aktivitas A.

Buat penerima siaran sebelum memulai aktivitas Anda 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"));

Kirim siaran dari aktivitas B ke aktivitas A bila Anda ingin menyelesaikan aktivitas A dari B

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

Saya harap ini akan berhasil untuk Anda ...

Bharat Sharma
sumber
Ini menunjukkan kesalahan ini "Kesalahan sintaks pada token, AnnotationName diharapkan sebagai gantinya" di "registerReceiver (broadcast_reciever, new IntentFilter (" finish_activity "));". Apa yang salah?
Behzad
2
"Anda tidak boleh merusak aliran normal aktivitas" +1 untuk ini
S-K
11
Jangan lupa untuk membatalkan pendaftaran broadcast_receiverdenganunregisterReceiver()
Jaec
Inilah solusinya. bagus
Parinda Rajapaksha
17

Ini adalah pertanyaan komunikasi yang cukup standar. Salah satu pendekatannya adalah dengan menggunakan ResultReceiver di Aktivitas 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);

lalu di Aktivitas B Anda bisa menyelesaikannya sesuai permintaan seperti:

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

Cobalah sesuatu seperti itu.

Femi
sumber
6
+1 saja, ((ResultReceiver) getIntent (). GetParcelableExtra ("finisher")). Send (1, new Bundle ());
Hamidreza Sadegh
12

Ada satu pendekatan yang dapat Anda gunakan dalam kasus Anda.

Langkah 1: Mulai Aktivitas B dari Aktivitas A

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

Langkah2: Jika pengguna mengklik tombol ubah, mulai Aktivitas A menggunakan FLAG_ACTIVITY_CLEAR_TOP.Juga, teruskan bendera secara ekstra.

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

Langkah3: Jika pengguna mengklik tombol Tambah, mulai Aktivitas A menggunakan FLAG_ACTIVITY_CLEAR_TOP.Juga, berikan bendera ekstra. FLAG_ACTIVITY_CLEAR_TOPakan menghapus semua aktivitas yang dibuka hingga target dan memulai ulang jika tidak ada mode peluncuran yang ditentukan dalam aktivitas target

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

Step4: Sekarang onCreate()metode Aktivitas A, perlu mengambil bendera itu.

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

Mulai aktivitas Anda dengan kode permintaan:

StartActivityForResult(intent,1234);

Dan Anda dapat menutupnya dari aktivitas lain seperti ini:

finishActivity(1234);
yaniv maymon
sumber
Dalam bahasa apa ??
Morten Holmgaard
5

Lihat jawaban saya untuk pertanyaan Stack Overflow Selesaikan Semua aktivitas sebelumnya .

Yang Anda butuhkan adalah menambahkan Intent.FLAG_CLEAR_TOP. Bendera ini memastikan bahwa semua aktivitas di atas aktivitas yang ditargetkan dalam tumpukan telah selesai dan yang ditampilkan.

Hal lain yang Anda butuhkan adalah SINGLE_TOPbendera. Dengan yang satu ini, Anda mencegah Android membuat aktivitas baru jika sudah ada yang dibuat di tumpukan.

Berhati-hatilah karena jika aktivitas sudah dibuat, maksud dengan tanda ini akan dikirimkan dalam metode yang dipanggil onNewIntent(intent)(Anda perlu membebani untuk menanganinya) dalam aktivitas target.

Kemudian di dalam onNewIntentAnda memiliki metode yang disebut restart atau sesuatu yang akan memanggil finish()dan meluncurkan maksud baru ke arah itu sendiri, atau memiliki repopulate()metode yang akan menyetel data baru. Saya lebih suka pendekatan kedua, lebih murah dan Anda selalu dapat mengekstrak onCreatelogika ke dalam metode terpisah yang dapat Anda panggil untuk diisi.

DArkO
sumber
4

Saya baru saja menerapkan solusi Nepster dan bekerja dengan sangat baik. Ada sedikit modifikasi untuk menjalankannya dari Fragmen.

Untuk Fragmen Anda

// 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);

Dan ke OnNewIntent () Anda dari Aktivitas, Anda ingin memulai ulang.

// 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);
}
koras
sumber
2

Saya pikir saya memiliki pendekatan termudah ... dengan menekan baru di B ..

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

dan di A mendapatkannya

  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);
    }
AndroidGeek
sumber
1

Saya tahu ini adalah pertanyaan lama, beberapa dari metode ini tidak berhasil untuk saya, jadi bagi siapa pun yang melihat ke masa depan atau mengalami masalah saya ini berhasil untuk saya

Saya mengesampingkan onPausedan memanggil ke finish()dalam metode itu.

Tony Kutzler
sumber
-1

Panggilan pertama startactivity()lalu gunakanfinish()

Dharmik Ghori
sumber