Kết thúc một hoạt động từ một hoạt động khác


100

Tôi muốn hoàn thành một hoạt động từ một hoạt động khác, như:

Trong Hoạt động [A], khi nhấp vào nút, tôi đang gọi Hoạt động [B] mà không kết thúc Hoạt động [A].

Bây giờ trong Hoạt động [B], có hai nút, MớiSửa đổi . Khi người dùng nhấp vào sửa đổi, sau đó bật một hoạt động [A] từ ngăn xếp với tất cả các tùy chọn được đánh dấu ..

Nhưng khi người dùng nhấp vào nút Mới từ Hoạt động [B], thì tôi sẽ phải hoàn thành Hoạt động [A] từ ngăn xếp và tải lại Hoạt động [A] đó vào ngăn xếp.

Tôi đang thử nhưng không thể hoàn thành Hoạt động [A] từ ngăn xếp ... Làm cách nào để thực hiện?

Tôi đang sử dụng mã dưới dạng:

Từ Hoạt động [A]:

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

Một phương pháp khác trong cùng một hoạt động

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

Và trong Hoạt động [B], khi nhấp vào nút:

setResult(1);
finish();

này, bạn muốn hoàn thành một hoạt động từ bên phải khác ... thì tôi đã đăng câu trả lời là chính xác. Nhưng, tại sao bạn lại bỏ phiếu?
Manjunath

Có một chủ đề với một vài câu trả lời hay ở đây: stackoverflow.com/questions/14355731/…
ab

Câu trả lời:


188
  1. Tạo hoạt động A của bạn trong tệp kê khai: launchMode = "singleInstance"

  2. Khi người dùng nhấp vào mới, hãy thực hiện FirstActivity.fa.finish();và gọi Ý định mới.

  3. Khi người dùng nhấp vào sửa đổi, hãy gọi Ý định mới hoặc chỉ cần kết thúc hoạt động B.

CÁCH ĐẦU TIÊN

Trong hoạt động đầu tiên của bạn, hãy khai báo một hoạt động Activity objectnhư thế này,

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

bây giờ sử dụng đối tượng đó trong một đối tượng khác Activityđể hoàn thành hoạt động đầu tiên như thế này,

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

CÁCH THỨ HAI

Trong khi gọi hoạt động FirstActivitymà bạn muốn kết thúc ngay khi tiếp tục, Bạn có thể thêm cờ trong khi gọiFirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Nhưng sử dụng cờ này, hoạt động sẽ hoàn thành nếu bạn không muốn. và đôi khi onBacknếu bạn muốn hiển thị, FirstActivitybạn sẽ phải gọi nó bằng ý định.


6
Câu trả lời chính xác..!!
Vaibhav Vajani

93
Bạn đang giữ một tham chiếu tĩnh cho một hoạt động. Điều này sẽ không bao giờ biến mất trừ khi bạn xóa nó theo cách thủ công từ đâu đó -> bạn đang tạo rò rỉ bộ nhớ!
DArkO

5
Được rồi, bạn có +1 của tôi cho suy nghĩ độc lập: D, tôi chỉ muốn đổi thành singleTop. tuy nhiên nó vẫn sẽ không phải là lựa chọn đầu tiên của tôi khi làm điều gì đó tương tự. bởi mã dọn dẹp, tôi có nghĩa là một cách để loại bỏ tham chiếu tĩnh để không bị rò rỉ bộ nhớ, nhưng điều đó phụ thuộc vào cấu trúc ứng dụng.
DArkO

6
Xin đừng ai sử dụng giải pháp đầu tiên, nó là hoàn toàn sai lầm. Bạn đang vượt qua khuôn khổ Android một cách thực sự khó hiểu khi tạo một đối tượng zombie. Sử dụng BroadcastReceiver.
S-K '

1
Giải pháp tuyệt vời. Làm việc rất tốt cho vấn đề của tôi, trong đó tôi đi từ các hoạt động A-> B-> C và trên onBackPressed của C, tôi đã khởi chạy phiên bản mới của B. Nhưng sau đó nếu tôi làm onBackPressed trên phiên bản B mới đó, nó đã từng chuyển đến phiên bản cũ của B thay vì phiên bản cũ của A (những gì tôi muốn). Vì vậy, tôi đi theo phương pháp đầu tiên của bạn trong onBackPressed của C, và nó đã cho tôi hành vi tôi muốn :) Cảm ơn tấn :)
SoulRayder

87

Điều đó bạn có thể làm, nhưng tôi nghĩ bạn không nên phá vỡ dòng hoạt động bình thường. Nếu bạn muốn kết thúc hoạt động của mình thì bạn chỉ cần gửi một chương trình phát sóng từ hoạt động B của mình đến hoạt động A.

Tạo bộ thu phát sóng trước khi bắt đầu hoạt động B của bạn:

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

Gửi chương trình phát sóng từ hoạt động B đến hoạt động A khi bạn muốn kết thúc hoạt động A từ B

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

Tôi hy vọng nó sẽ hiệu quả với bạn ...


Nó hiển thị lỗi này "Lỗi cú pháp trên mã thông báo, AnnotationName mong đợi thay thế" trên "registerReceiver (broadcast_reciever, new IntentFilter (" finish_activity "));". Chuyện gì vậy?
Behzad

2
"bạn không nên phá vỡ luồng hoạt động bình thường" +1 cho điều này
S-K

11
Đừng quên hủy đăng ký broadcast_receivervớiunregisterReceiver()
Jaec


Đây là giải pháp. đẹp một
Parinda Rajapaksha

17

Đây là một câu hỏi giao tiếp khá chuẩn. Một cách tiếp cận sẽ là sử dụng ResultReceiver trong Hoạt động 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);

và sau đó trong Hoạt động B, bạn có thể hoàn thành nó theo yêu cầu như sau:

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

Hãy thử một cái gì đó như vậy.


6
+1 just, ((ResultReceiver) getIntent (). GetParcelableExtra ("finish")). Send (1, new Bundle ());
Hamidreza Sadegh

12

Có một cách tiếp cận mà bạn có thể sử dụng trong trường hợp của mình.

Bước 1: Bắt đầu Hoạt động B từ Hoạt động A

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

Bước 2: Nếu người dùng nhấp vào nút sửa đổi, hãy bắt đầu Hoạt động A bằng cách sử dụng FLAG_ACTIVITY_CLEAR_TOP.Also, vượt qua cờ thêm.

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

Bước 3: Nếu người dùng nhấp vào nút Thêm, hãy bắt đầu Hoạt động A bằng cách sử dụng FLAG_ACTIVITY_CLEAR_TOP.Also, vượt qua cờ thêm. FLAG_ACTIVITY_CLEAR_TOPsẽ xóa tất cả các hoạt động đã mở cho đến mục tiêu và khởi động lại nếu không có chế độ khởi chạy nào được xác định trong hoạt động mục tiêu

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

Bước 4: Bây giờ onCreate()phương pháp của Activity A, cần lấy lại cờ đó.

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

6

Bắt đầu hoạt động của bạn với mã yêu cầu:

StartActivityForResult(intent,1234);

Và bạn có thể đóng nó từ bất kỳ hoạt động nào khác như sau:

finishActivity(1234);

Bằng ngôn ngữ nào ??
Morten Holmgaard

5

Xem câu trả lời của tôi cho câu hỏi Stack Overflow Kết thúc Tất cả các hoạt động trước đó .

Những gì bạn cần là thêm Intent.FLAG_CLEAR_TOP. Cờ này đảm bảo rằng tất cả các hoạt động phía trên hoạt động được nhắm mục tiêu trong ngăn xếp đã kết thúc và một hoạt động được hiển thị.

Một thứ khác mà bạn cần là SINGLE_TOPcờ. Với điều này, bạn ngăn Android tạo một hoạt động mới nếu đã có một hoạt động trong ngăn xếp.

Chỉ cần cảnh giác rằng nếu hoạt động đã được tạo, ý định với các cờ này sẽ được phân phối trong phương thức được gọi onNewIntent(intent)(bạn cần phải quá tải nó để xử lý) trong hoạt động đích.

Sau đó, trong onNewIntentbạn có một phương thức được gọi là khởi động lại hoặc một thứ gì đó sẽ gọi finish()và khởi chạy một ý định mới đối với chính nó, hoặc có một repopulate()phương thức sẽ thiết lập dữ liệu mới. Tôi thích cách tiếp cận thứ hai hơn, nó ít tốn kém hơn và bạn luôn có thể trích xuất onCreatelogic thành một phương pháp riêng biệt mà bạn có thể gọi để điền.


4

Tôi vừa mới áp dụng giải pháp của Nepster và hoạt động như một sự quyến rũ. Có một sửa đổi nhỏ để chạy nó từ Fragment.

Đến mảnh vỡ của bạn

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

Và với OnNewIntent () của Activity, bạn muốn khởi động lại.

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

Tôi nghĩ rằng tôi có cách tiếp cận dễ dàng nhất ... nhấn mới trong B..

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

và trong A có được nó

  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

Tôi biết đây là một câu hỏi cũ, một vài trong số những phương pháp này không phù hợp với tôi, vì vậy đối với bất kỳ ai đang tìm kiếm trong tương lai hoặc gặp khó khăn, điều này đã hiệu quả với tôi

Tôi ghi đè onPausevà gọi finish()bên trong phương thức đó.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.