Khi đăng xuất, hãy xóa ngăn xếp lịch sử Hoạt động, ngăn không cho nút Quay lại của Google mở các hoạt động chỉ đăng nhập


235

Tất cả các hoạt động trong ứng dụng của tôi yêu cầu người dùng phải đăng nhập để xem. Người dùng có thể đăng xuất khỏi hầu hết mọi hoạt động. Đây là một yêu cầu của ứng dụng. Tại bất kỳ thời điểm nào nếu người dùng đăng xuất, tôi muốn gửi người dùng đến Đăng nhập Activity. Tại thời điểm này, tôi muốn hoạt động này ở dưới cùng của ngăn xếp lịch sử để nhấn nút "quay lại" sẽ đưa người dùng về màn hình chính của Android.

Tôi đã thấy câu hỏi này hỏi một vài nơi khác nhau, tất cả đều trả lời với câu trả lời tương tự (mà tôi phác thảo ở đây), nhưng tôi muốn đặt nó ở đây để thu thập phản hồi.

Tôi đã thử mở hoạt động Đăng nhập bằng cách đặt các Intentcờ của nó FLAG_ACTIVITY_CLEAR_TOPcó vẻ như được nêu trong tài liệu, nhưng không đạt được mục tiêu của tôi là đặt hoạt động Đăng nhập ở dưới cùng của ngăn xếp lịch sử và ngăn người dùng điều hướng trở lại cho các hoạt động đăng nhập đã thấy trước đó. Tôi cũng đã thử sử dụng android:launchMode="singleTop"cho hoạt động Đăng nhập trong tệp kê khai, nhưng điều này cũng không hoàn thành mục tiêu của tôi (và dường như không có tác dụng nào).

Tôi tin rằng tôi cần phải xóa ngăn xếp lịch sử hoặc hoàn thành tất cả các hoạt động đã mở trước đó.

Một tùy chọn là để onCreatekiểm tra trạng thái đăng nhập của từng hoạt động và finish()nếu không đăng nhập. Tôi không thích tùy chọn này, vì nút quay lại vẫn sẽ có sẵn để sử dụng, điều hướng trở lại khi các hoạt động tự đóng lại.

Tùy chọn tiếp theo là duy trì một LinkedListtham chiếu cho tất cả các hoạt động mở có thể truy cập tĩnh từ mọi nơi (có thể sử dụng các tham chiếu yếu). Khi đăng xuất, tôi sẽ truy cập danh sách này và lặp lại tất cả các hoạt động đã mở trước đó, gọi finish()từng hoạt động . Có lẽ tôi sẽ bắt đầu thực hiện phương pháp này sớm.

Tôi muốn sử dụng một số Intentthủ thuật cờ để thực hiện điều này, tuy nhiên. Tôi rất vui khi thấy rằng tôi có thể đáp ứng các yêu cầu của ứng dụng của mình mà không phải sử dụng một trong hai phương pháp mà tôi đã nêu ở trên.

Có cách nào để thực hiện điều này bằng cách sử dụng Intenthoặc cài đặt bảng kê khai, hoặc là tùy chọn thứ hai của tôi, duy trì một LinkedListhoạt động mở là lựa chọn tốt nhất? Hoặc có một lựa chọn khác mà tôi hoàn toàn nhìn ra?

Câu trả lời:


213

Tôi có thể đề nghị bạn một cách tiếp cận khác IMHO mạnh mẽ hơn. Về cơ bản, bạn cần phát thông báo đăng xuất tới tất cả các Hoạt động của bạn cần ở trạng thái đăng nhập. Vì vậy, bạn có thể sử dụng sendBroadcastvà cài đặt một BroadcastReceivertrong tất cả các tính năng. Một cái gì đó như thế này:

/** on your logout method:**/
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_LOGOUT");
sendBroadcast(broadcastIntent);

Người nhận (Hoạt động được bảo mật):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /**snip **/
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("com.package.ACTION_LOGOUT");
    registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("onReceive","Logout in progress");
            //At this point you should start the login activity and finish this one
            finish();
        }
    }, intentFilter);
    //** snip **//
}

27
@Christopher, mỗi hoạt động đăng ký phát sóng khi nó được tạo. Khi nó đi đến nền (tức là, một hoạt động mới xuất hiện ở đầu ngăn xếp), onStop () của nó sẽ được gọi, nhưng nó vẫn có thể nhận được các chương trình phát sóng. Bạn chỉ cần đảm bảo rằng bạn gọi unregisterReceiver () trong onDestroy () chứ không phải trong onStop ().
Russell Davis

9
Điều này có hoạt động không nếu một hoạt động ở đâu đó trong ngăn xếp bị HĐH tắt để khôi phục bộ nhớ? I E. hệ thống sẽ xem xét nó thực sự kết thúc sau khi chương trình phát ở trên được gửi đi và sẽ không tạo lại nó khi nhấn nút quay lại?
Jan Żankowski

5
Mặc dù điều này có vẻ như là một giải pháp tao nhã, nhưng điều quan trọng cần lưu ý là điều này không đồng bộ.
Che Jami

34
Một giải pháp hay, nhưng thay vì sử dụng đăng ký máy thu Broadcast như được mô tả trong đoạn mã trên, bạn nên sử dụng LocalBroadcastManager.getInstance (this) .registerReceiver (...) và LocalBroadcastManager.getInstance (this) .unregisterReceiver (..) . Otherwiser ứng dụng của bạn có thể nhận được ý định từ bất kỳ ứng dụng nào khác (mối quan tâm bảo mật)
Uku Loskit

5
@Warlock Bạn đúng rồi. Cạm bẫy của phương pháp này là khi một Hoạt động trong ngăn xếp phía sau bị hệ thống phá hủy (có thể xảy ra vì nhiều lý do, chẳng hạn như kịch bản bộ nhớ thấp đã lưu ý). Trong trường hợp đó, đối tượng Activity sẽ không xuất hiện để nhận phát sóng. Nhưng hệ thống vẫn sẽ điều hướng trở lại thông qua Hoạt động đó bằng cách tạo lại nó. Điều này có thể được kiểm tra / sao chép bằng cách bật cài đặt của nhà phát triển "Đừng giữ hoạt động"
Eric Schlenz

151

Có vẻ như một nghi thức thông qua rằng một lập trình viên Android mới dành một ngày để nghiên cứu vấn đề này và đọc tất cả các luồng StackOverflow này. Bây giờ tôi mới được bắt đầu và tôi để lại ở đây dấu vết của kinh nghiệm khiêm tốn của tôi để giúp một người hành hương trong tương lai.

Đầu tiên, không có cách rõ ràng hoặc ngay lập tức để làm điều này theo nghiên cứu của tôi (as of September 2012).Bạn nghĩ rằng bạn có thể đơn giản startActivity(new Intent(this, LoginActivity.class), CLEAR_STACK)nhưng không .

Bạn CÓ THỂ làm startActivity(new Intent(this, LoginActivity.class))với FLAG_ACTIVITY_CLEAR_TOP- và điều này sẽ khiến khung tìm kiếm ngăn xếp, tìm phiên bản gốc của Đăng nhập ban đầu, tạo lại nó và xóa phần còn lại của ngăn xếp (hướng lên). Và vì Đăng nhập có lẽ ở dưới cùng của ngăn xếp, bây giờ bạn có một ngăn xếp trống và nút Quay lại chỉ cần thoát khỏi ứng dụng.

NHƯNG - điều này chỉ hoạt động nếu trước đó bạn để lại ví dụ ban đầu của Đăng nhập hoạt động ở cơ sở của ngăn xếp của bạn. Nếu, giống như nhiều lập trình viên, bạn đã chọn finish()điều đó LoginActivitymột khi người dùng đã đăng nhập thành công, thì nó không còn trên cơ sở của ngăn xếp và FLAG_ACTIVITY_CLEAR_TOPngữ nghĩa không áp dụng ... cuối cùng bạn sẽ tạo một cái mới LoginActivitytrên đầu ngăn xếp hiện có. Điều này gần như chắc chắn KHÔNG phải là những gì bạn muốn (hành vi kỳ lạ khi người dùng có thể 'quay lại' cách thoát khỏi đăng nhập vào màn hình trước đó).

Vì vậy, nếu trước đó bạn đã finish()'D LoginActivity, bạn cần phải theo đuổi một số cơ chế thanh toán bù trừ chồng bạn và sau đó bắt đầu một mới LoginActivity. Có vẻ như câu trả lời @doreamontrong chủ đề này là giải pháp tốt nhất (ít nhất là với con mắt khiêm tốn của tôi):

https://stackoverflow.com/a/9580057/614880

Tôi hoàn toàn nghi ngờ rằng những hệ lụy phức tạp của việc bạn có còn tồn tại Đăng nhập hay không đang gây ra nhiều nhầm lẫn này.

Chúc may mắn.


5
Câu trả lời tốt. Thủ thuật FLAG_ACTIVITY_CLEAR_TOP, mà hầu hết mọi người khuyên nên sử dụng, sẽ không hoạt động nếu bạn đã hoàn thành Đăng nhập.
Konsumierer

Cảm ơn câu trả lời. Kịch bản khác giống như khi có một phiên (ví dụ như fb) thậm chí chúng tôi không gọi hoạt động Đăng nhập để không có điểm hoạt động Đăng nhập trong ngăn xếp. Sau đó, cách tiếp cận được đề cập ở trên là vô ích.
Prashanth Debbadwar

118

CẬP NHẬT

finishAffinity()phương pháp siêu sẽ giúp giảm mã nhưng đạt được như vậy. Nó sẽ kết thúc hoạt động hiện tại cũng như tất cả các hoạt động trong ngăn xếp, sử dụng getActivity().finishAffinity()nếu bạn đang ở trong một đoạn.

finishAffinity(); 
startActivity(new Intent(mActivity, LoginActivity.class));

CÂU TRẢ LỜI

Giả sử rằng Đăng nhậpActivity -> HomeActivity -> ... -> Cài đặt Cuộc gọi hoạt động SignOut ():

void signOut() {
    Intent intent = new Intent(this, HomeActivity.class);
    intent.putExtra("finish", true);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // To clean up all activities
    startActivity(intent);
    finish();
}

Trang chủ Hoạt động:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    boolean finish = getIntent().getBooleanExtra("finish", false);
    if (finish) {
        startActivity(new Intent(mContext, LoginActivity.class));
        finish();
        return;
    }
    initializeView();
}

Điều này làm việc cho tôi, hy vọng rằng nó cũng hữu ích cho bạn. :)


1
Tôi nghĩ rằng giải pháp của bạn giả định rằng người dùng sẽ nhấp vào SignOut và quay lại chỉ một hoạt động (HomeActivity). Nếu bạn có 10 hoạt động trên stack thì sao?
IgorGanapolsky 17/03/2016

11
Nếu bạn có 10 hoạt động trên đỉnh HomeActivity, cờ FLAG_ACTIVITY_CLEAR_TOP sẽ giúp xóa tất cả chúng.
thanhbinh84

1
Điều này chỉ có thể hoạt động nếu khi bắt đầu HomeActivity, bạn nhận được OnCreate của HomeActivity. Đơn giản chỉ cần bắt đầu hoạt động tại nhà sẽ không nhất thiết phải tạo lại nó trừ khi nó đã kết thúc hoặc bị phá hủy. Nếu HomeActivity không cần phải được tạo lại, OnCreate sẽ không được gọi và sau khi bạn đăng xuất, bạn sẽ ngồi vào hoạt động tại nhà.
topwik

1
Đây là một giải pháp khả thi và liên quan đến việc mã hóa ít hơn một tính năng đơn giản (dành cho người dùng) như đăng xuất.
Subin Sebastian

2
Cờ Intent.FLAG_ACTIVITY_CLEAR_TOP giúp dọn sạch tất cả các hoạt động bao gồm HomeActivity, do đó phương thức onCreate () sẽ được gọi khi bạn bắt đầu lại hoạt động này.
thanhbinh84

73

Nếu bạn đang sử dụng API 11 trở lên, bạn có thể thử điều này: FLAG_ACTIVITY_CLEAR_TASK- dường như đang giải quyết chính xác vấn đề bạn gặp phải. Rõ ràng, đám đông trước API 11 sẽ phải sử dụng một số kết hợp để tất cả các hoạt động kiểm tra thêm, như @doreamon gợi ý hoặc một số mánh khóe khác.

(Cũng lưu ý: để sử dụng cái này bạn phải truyền vào FLAG_ACTIVITY_NEW_TASK)

Intent intent = new Intent(this, LoginActivity.class);
intent.putExtra("finish", true); // if you are checking for this in your other Activities
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | 
                Intent.FLAG_ACTIVITY_CLEAR_TASK |
                Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();

1
Làm việc như một cơ duyên. Cảm ơn rât nhiều! Khi tôi phát triển trên API tối thiểu 14, đó là điều duy nhất để thực hiện.
AndyB

1
Tôi nghĩ rằng chúng tôi không cần FLAG_ACTIVITY_CLEAR_TOP khi sử dụng giải pháp này cho Đăng nhập.
Bharat Dodeja

Tôi nghĩ chỉ cần finish();làm công việc để ngăn chặn quay trở lại sau khi đăng xuất. Nhu cầu thiết lập cờ là gì?
Pankaj

Điều này tạo ra một ngoại lệ Gọi startActivity () từ bên ngoài ngữ cảnh Hoạt động yêu cầu cờ FLAG_ACTIVITY_NEW_TASK
Aman

31

Tôi cũng đã dành vài giờ cho việc này ... và đồng ý rằng FLAG_ACTIVITY_CLEAR_TOP nghe giống như những gì bạn muốn: xóa toàn bộ ngăn xếp, ngoại trừ hoạt động được khởi chạy, vì vậy nút Quay lại thoát khỏi ứng dụng. Tuy nhiên, như Mike Repass đã đề cập, FLAG_ACTIVITY_CLEAR_TOP chỉ hoạt động khi hoạt động bạn khởi chạy đã có trong ngăn xếp; khi hoạt động không có ở đó, cờ không làm gì cả.

Phải làm sao? Đặt hoạt động đang khởi chạy trong ngăn xếp với FLAG_ACTIVITY_NEW_TASK , điều này làm cho hoạt động đó bắt đầu một tác vụ mới trên ngăn xếp lịch sử. Sau đó thêm cờ FLAG_ACTIVITY_CLEAR_TOP.

Bây giờ, khi FLAG_ACTIVITY_CLEAR_TOP đi tìm hoạt động mới trong ngăn xếp, nó sẽ ở đó và được kéo lên trước khi mọi thứ khác bị xóa.

Đây là chức năng đăng xuất của tôi; tham số View là nút mà chức năng được đính kèm.

public void onLogoutClick(final View view) {
    Intent i = new Intent(this, Splash.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    finish();
}

1
Không hoạt động trên API <= 10 như FLAG_ACTIVITY_CLEAR_TASKchưa được thêm vào
Youans 11/11/13

1
@christinac Bạn đang nói về FLAG_ACTIVITY_CLEAR_TOP và đoạn mã của bạn có FLAG_ACTIVITY_CLEAR_TASK; cái nào hợp lệ thì sao?
Mary Paździoch

10

Rất nhiều câu trả lời. Có thể cái này cũng sẽ giúp-

Intent intent = new Intent(activity, SignInActivity.class)
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
this.finish();

Phiên bản Kotlin-

Intent(this, SignInActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.also { startActivity(it) }
finish()

4

Sử dụng nó sẽ hữu ích cho bạn. Trả lời xbakesx một chút.

Intent intent = new Intent(this, LoginActivity.class);
if(Build.VERSION.SDK_INT >= 11) {
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
} else {
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(intent);

4

Giải pháp được chấp nhận là không chính xác, nó có vấn đề vì sử dụng một máy thu phát sóng không phải là một ý tưởng tốt cho vấn đề này. Nếu hoạt động của bạn đã được gọi là phương thức onDestroy (), bạn sẽ không nhận được người nhận. Giải pháp tốt nhất là có một giá trị boolean trên các tùy chọn chia sẻ của bạn và kiểm tra nó trong phương thức onCreate () của activty của bạn. Nếu không nên gọi khi người dùng chưa đăng nhập, thì kết thúc hoạt động. Đây là mã mẫu cho điều đó. Vì vậy, đơn giản và làm việc cho mọi điều kiện.

protected void onResume() {
  super.onResume();
  if (isAuthRequired()) {
    checkAuthStatus();
  }
}

private void checkAuthStatus() {
  //check your shared pref value for login in this method
  if (checkIfSharedPrefLoginValueIsTrue()) {
    finish();
  }
}

boolean isAuthRequired() {
  return true;
}

1
Đã nhiều năm, nhưng tôi tin rằng tôi đã làm cả hai. Mỗi Hoạt động mở rộng LoggedInActivity, đã kiểm tra trạng thái đăng nhập của người dùng trong onCreate (). LoggedInActivity cũng lắng nghe chương trình phát "người dùng đã đăng xuất" và làm bất cứ điều gì cần làm để đáp ứng điều này.
skyler

2
có lẽ bạn nên đặt checkAuthStatus trong onResume()methode. Bởi vì khi bạn nhấn nút quay lại, hoạt động có nhiều khả năng được nối lại thay vì được tạo.
maysi

1
@maysi Cảm ơn bạn đã gợi ý, có, nút quay lại này cũng sẽ hoạt động chính xác, tôi đã cập nhật mục nhập
Yekmer Simsek

3

Thỉnh thoảng finish() không làm việc

Tôi đã giải quyết vấn đề đó với

finishAffinity()


3

Tôi muốn đề xuất một cách tiếp cận khác cho câu hỏi này. Có thể nó không phải là cách hiệu quả nhất, nhưng tôi nghĩ nó dễ áp ​​dụng nhất và yêu cầu rất ít mã. Viết mã tiếp theo trong hoạt động đầu tiên của bạn (đăng nhập hoạt động, trong trường hợp của tôi) sẽ không cho phép người dùng quay lại các hoạt động đã khởi chạy trước đó sau khi đăng xuất.

@Override
public void onBackPressed() {
    // disable going back to the MainActivity
    moveTaskToBack(true);
}

Tôi giả định rằng LoginActivity kết thúc ngay sau khi người dùng đăng nhập, để anh ta không thể quay lại sau bằng cách nhấn nút quay lại. Thay vào đó, người dùng phải nhấn nút đăng xuất bên trong ứng dụng để đăng xuất đúng cách. Nút đăng xuất này sẽ thực hiện như thế nào là một mục đích đơn giản như sau:

Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();

Tất cả các đề xuất đều được chào đón.


2

Câu trả lời được lựa chọn là thông minh và khó khăn. Đây là cách tôi đã làm:

LoginActivity là hoạt động gốc của tác vụ, đặt android: noHistory = "true" thành nó trong Manifest.xml; Giả sử bạn muốn đăng xuất khỏi SettingsActivity, bạn có thể thực hiện như sau:

    Intent i = new Intent(SettingsActivity.this, LoginActivity.class);
    i.addFlags(IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
            | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(i);

2

Đây là giải pháp tôi đã đưa ra trong ứng dụng của mình.

Trong phần Đăng nhập của tôi, sau khi xử lý đăng nhập thành công, tôi bắt đầu đăng nhập khác theo cách khác tùy thuộc vào cấp độ API.

Intent i = new Intent(this, MainActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    startActivity(i);
    finish();
} else {
    startActivityForResult(i, REQUEST_LOGIN_GINGERBREAD);
}

Sau đó, trong phương thức onActivityForResult của Đăng nhập của tôi:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB &&
        requestCode == REQUEST_LOGIN_GINGERBREAD &&
        resultCode == Activity.RESULT_CANCELED) {
    moveTaskToBack(true);
}

Cuối cùng, sau khi xử lý đăng xuất trong bất kỳ Hoạt động nào khác:

Intent i = new Intent(this, LoginActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Khi trên Gingerbread, hãy làm như vậy nếu tôi nhấn nút quay lại từ MainActivity, thì Đăng nhập ngay lập tức bị ẩn. Trên Honeycomb và sau đó, tôi chỉ cần hoàn thành Đăng nhập sau khi xử lý đăng nhập và nó được tạo lại đúng cách sau khi xử lý đăng xuất.


Nó không làm việc cho tôi. Trong trường hợp của tôi, tôi đã sử dụng phân mảnh. Phương pháp Onactivityresult không được gọi.
Mohamed Ibrahim

1

Điều này làm việc cho tôi:

     // After logout redirect user to Loing Activity
    Intent i = new Intent(_context, MainActivity.class);
    // Closing all the Activities
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

    // Add new Flag to start new Activity
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    // Staring Login Activity
    _context.startActivity(i);

Bạn có thể vui lòng giải thích thêm câu trả lời của bạn thêm một chút mô tả về giải pháp bạn cung cấp không?
abarisone

0

Bắt đầu hoạt động với StartActivityForResult và trong khi bạn đăng xuất đặt kết quả của bạn và theo kết quả, bạn kết thúc hoạt động của mình

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivityForResult(intent, BACK_SCREEN);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case BACK_SCREEN:
        if (resultCode == REFRESH) {
            setResult(REFRESH);
            finish();
        }
        break;
    }
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        AlertDialog alertDialog = builder.create();

        alertDialog
                .setTitle((String) getResources().getText(R.string.home));
        alertDialog.setMessage((String) getResources().getText(
                R.string.gotoHome));
        alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                            int whichButton) {

                        setResult(REFRESH);
                        finish();
                    }

                });

        alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "No",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                            int whichButton) {
                    }
                });
        alertDialog.show();
        return true;
    } else
        return super.onKeyDown(keyCode, event);

}

0

Giải pháp @doreamon cung cấp hoạt động tốt cho tất cả các trường hợp ngoại trừ một trường hợp:

Nếu Sau khi đăng nhập, người dùng màn hình Giết đăng nhập sẽ điều hướng trực tiếp đến màn hình giữa. ví dụ: Trong luồng A-> B-> C, điều hướng như: Đăng nhập -> B -> C -> Nhấn phím tắt về nhà. Sử dụng FLAG_ACTIVITY_CLEAR_TOP chỉ xóa hoạt động C, vì Nhà (A) không có trong lịch sử ngăn xếp. Nhấn Back trên màn hình A sẽ đưa chúng ta trở lại B.

Để giải quyết vấn đề này, chúng ta có thể giữ một ngăn xếp hoạt động (Arraylist) và khi nhấn nhà, chúng ta phải hủy tất cả các hoạt động trong ngăn xếp này.


0

Có thể bằng cách quản lý một cờ trong SharedPreferences hoặc trong Hoạt động ứng dụng.

Khi bắt đầu ứng dụng (trên Màn hình Splash), đặt cờ = false; Khi đăng xuất, sự kiện Click chỉ cần đặt cờ đúng và trong OnResume () của mọi hoạt động, kiểm tra xem cờ có đúng không sau đó gọi kết thúc ().

Nó hoạt động như một say mê :)


0

khi nhấp vào Đăng xuất, bạn có thể gọi đây

private void GoToPreviousActivity() {
    setResult(REQUEST_CODE_LOGOUT);
    this.finish();
}

onActivityResult () của Hoạt động trước gọi lại mã ở trên cho đến khi bạn hoàn thành tất cả các hoạt động.


1
Điều đó có nghĩa là nó phải duyệt qua tất cả các hoạt động một cách tuyến tính, thay vì phát tất cả kết thúc () cùng một lúc?
IgorGanapolsky 17/03/2016

@Igor G. vâng, đó là cách thay thế để hoàn thành tuần tự
Mak

-1

Một tùy chọn là để kiểm tra trạng thái đăng nhập của từng hoạt động và kết thúc () nếu không đăng nhập. Tôi không thích tùy chọn này, vì nút quay lại vẫn sẽ có sẵn để sử dụng, điều hướng trở lại khi các hoạt động tự đóng lại.

Những gì bạn muốn làm là gọi logout () và finish () trên các phương thức onStop () hoặc onPause () của bạn. Điều này sẽ buộc Android gọi onCreate () khi hoạt động được đưa trở lại vì nó sẽ không có trong ngăn xếp hoạt động của nó nữa. Sau đó, làm như bạn nói, trong onCreate () kiểm tra trạng thái đăng nhập và chuyển tiếp đến màn hình đăng nhập nếu không đăng nhập.

Một điều khác bạn có thể làm là kiểm tra trạng thái đăng nhập trong onResume () và nếu không đăng nhập, kết thúc () và khởi chạy hoạt động đăng nhập.


Tôi không muốn đăng xuất trên mỗi hoạt động tạm dừng hoặc dừng. Ngoài ra, ứng dụng bắt đầu đăng xuất hoặc đăng nhập, vì vậy tôi không cần phải kiểm tra nếu đăng nhập, thực sự.
skyler

@Ricardo: không phải giải pháp của bạn yêu cầu BroadcastReceiver?
IgorGanapolsky 17/03/2016
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.