Android : 백 스택에서 모든 이전 활동 제거


119

프로필 활동 에서 로그 아웃 버튼을 클릭 할 때 사용자가 새 자격 증명을 사용해야 하는 로그인 페이지로 이동 하고 싶습니다 .

따라서이 코드를 사용했습니다.

Intent intent = new Intent(ProfileActivity.this,
        LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

에서 onButtonClick로그 아웃 버튼.

그러나 문제는 로그인 활동에서 장치 뒤로 버튼을 클릭하면 ProfileActivity로 이동한다는 것입니다. LoginActivity에서 장치 뒤로 버튼을 누르면 응용 프로그램이 닫힐 것으로 예상했습니다.

내가 뭘 잘못하고 있죠?

또한 android:launchMode="singleTop"LoginActivity 의 매니페스트에 추가 했습니다.

감사합니다


@GauravVashisth 난 그냥이 솔루션은 다음되었다 stackoverflow.com/questions/5794506/...을
Archie.bpgc

@ abbas.aniefa 그 해결책은 조금 복잡합니다. 그것이 모든 백 스택을 지우는 유일한 방법입니다. 내가 그들 모두이 방송 코드를 작성해야한다 그래서 30 개 + 활동을 가지고 있기 때문에
Archie.bpgc

그런 다음 stackoverflow.com/questions/10961481/…을 시도하십시오 . 브로드 캐스트를 사용하는 것이 더 나은 솔루션입니다.
abbas.aniefa

로그 아웃에 사용할 수있는 또 다른 방법은 일단 로그 아웃하면 sharedpreferences에 플래그 하나를 저장하고 활동의 각 onRestart () 메서드에서이 변수 값이 true로 설정되어 있으면 현재 활동을 완료 할 수 있습니다. 그래서 배경에서 얼마나 많은 활동이 열려 있든 상관 없습니다. 이것은 당신의 모든 활동을 마칠 것입니다.
Hiren Dabhi

원래 코드는 실제로 API 레벨 11 이상에서 작동합니다. 한 번의 호출로 플래그를 모으기 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
만하면됩니다

답변:


303

여기 에서 제안 된 솔루션 이 저에게 효과적이었습니다.

자바

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Kotlin

val i = Intent(this, NewActivity::class.java)
// set the new task and clear flags
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)

그러나 API 레벨> = 11이 필요합니다.


여러분, 문서를 읽어보십시오. FLAG_ACTIVITY_CLEAR_TASK이것은 공식적인 방법입니다. 앱의 모든 활동을 변경할 필요가 없습니다.
AlikElzin-kilaka 2015

알림에 대해서는 작동하지 않습니다. stackoverflow.com/questions/24873131/…
Sam

나는 내 minAPI = 16을 가지고 있으므로 이것은 나를 위해 완벽하게 잘 작동합니다. 그러나 API> 21에서는 뷰 실행이 약간 느리고 API <21에서는 부드럽습니다. 같은 문제를 겪고있는 사람이 있습니까?
Red M

1
활동에 대한 새 작업이 생성됩니다
Rohit

@kgiannakakis 의심 할 여지없이 하나의 작업 (Activity Back stack) 만 있으면 솔루션이 작동하지만 여러 작업 (Activity stack)이있는 경우 작동하지 않습니다. 예를 들어 애플리케이션 A, B, C 및 D에 대해 4 개의 활동이 있다고 가정하겠습니다. 두 개의 활동 백 스택 A-> B-> C (배경) 및 D-> A-> B (전경) 및 If I 인 텐트 필터를 사용하여 현재 스택 (D-> A-> B)에서 활동 A를 호출하면 무슨 일이 일어날 지 제안한 것입니다. 현재 스택 (D-> A-> B)을 지우고 활동 A를 열고 다시 누르면 닫습니다. 그러나 최근 앱 버튼을 누르면 내 앱의 두 스택을 볼 수 있습니다.
Rahul Pareta

31

다음은 로그 아웃 버튼을 사용할 때 애플리케이션의 모든 활동을 지우는 한 가지 솔루션입니다.

활동을 시작할 때마다 다음과 같이 시작하십시오.

Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class);
startActivityForResult(myIntent, 0);

전체 앱을 닫으려면 다음을 수행하십시오.

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL은 모든 활동을 닫고 싶다는 신호를 보내는 고유 한 정수가있는 최종 전역 변수입니다.

그런 다음 모든 활동의 onActivityResult(...)콜백을 정의 하여 활동이 RESULT_CLOSE_ALL 값과 함께 반환되면 다음도 호출합니다 finish().

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

이것은 모든 활동을 닫는 계단식 효과를 유발합니다.

그러나 이것은 해킹이며 사용 startActivityForResult하도록 설계되지 않은 방식으로 사용합니다.

이를 수행하는 더 좋은 방법은 다음과 같이 브로드 캐스트 수신기를 사용하는 것입니다.

로그 아웃시 활동 내역 스택을 지우고 "뒤로"버튼이 로그인 전용 활동을 열지 못하도록합니다.

다른 방법에 대해서도 다음 스레드를 참조하십시오.

Android : 백 스택 지우기

모든 이전 활동 완료


4
역사상 약 30 개의 활동이있을 때 가능합니까 ??
Rakesh Gondaliya

4
해야한다. 그러나 역사상 30 개의 활동이 있다면 디자인 변경을 고려할 수 있습니다. 30은 너무 많은 것 같고 Android가 스스로 죽일 수 있습니다.
Anup Cowkur 2013 년

1
이것은 그것을하는 좋지 않은 방법으로 보입니다. @RakeshGondaliya의 답변 질문은 합법적 인 것 같습니다. 30은 '높은'활동 수를 나타내는 숫자 일 수 있습니다. 이 답변은 더 좋아 보입니다 : stackoverflow.com/a/3008684/243709
Aman Alam

이 대답은 훌륭합니다. EventBus 라이브러리를 사용하여 백 스택의 활동에 이벤트를 보낼 수도 있습니다. github.com/greenrobot/EventBus
Stan

사용 간단한와 'Intent.FLAG_ACTIVITY_CLEAR_TOP'플래그에 더 나은 의사
나빈 라오

18

활동 스택을 완전히 지우려면 TaskStackBuilder를 사용하여 새 작업 스택을 만들려고합니다. 예를 들면 다음과 같습니다.

Intent loginIntent = LoginActivity.getIntent(context);
TaskStackBuilder.create(context).addNextIntentWithParentStack(loginIntent).startActivities();

이렇게하면 새롭고 깨끗한 작업 스택이 생성 될뿐만 아니라 LoginActivity에 상위 활동이있는 경우 "up"버튼이 제대로 작동 할 수 있습니다.


1
이것이 최선의 방법입니다.
Paul Burke

FLAG_ACTIVITY_NEW_TASK또는 finishAffinity()나를 위해 일하지 않았습니다. 이 대답 만이 목적을 해결했습니다.
TM

뒤로 버튼을 통해 앱을 종료하고 앱 아이콘을 통해 돌아 오면 해당 메서드를 호출 한 활동에서 열립니다. 그래서 나를 위해 일하지 않습니다.
Tgo1014

17

finishAffinity()API 16에 추가되었습니다 ActivityCompat.finishAffinity(). 이전 버전에서 사용 합니다. 인 텐트를 사용하여 활동을 시작하고 현재 활동을 완료 할 때. 이제 ActivityCompat.finishAffinity()대신 사용하십시오 finish(). 현재 활동 아래의 모든 누적 활동을 완료합니다. 그것은 나를 위해 잘 작동합니다.


3
그것은 실제로ActivityCompat.finishAffinity()
Berga

finishAffinity()또한 동일한 선호도의 백 스택에있는 모든 활동으로 현재 활동을 완료합니다.
Neeraj Sewani

10

나를 위해 일한 것

Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

5

내가 제안 할 수있는 한 가지 가능한 해결책 android:launchMode="singleTop"은 내 ProfileActivity 에 대한 매니페스트에 추가 하는 것입니다 . 클릭하면 로그 아웃하고 u는 수 로그 오프 하면 다시 시작 LoginActivity합니다. 로그 아웃시 u는 이것을 부를 수 있습니다.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();

나는 이것을했고, 무슨 일이 일어 났는지 : 내가 뒤로 버튼을 클릭하면 내가 ProfileActivity에 왔던 Activty로 이동합니다
Archie.bpgc

이것은 u가 finish ()를 호출하지 않고 새 인 텐트를 호출하여 ProfileActivity에 왔기 때문에 발생할 수 있습니다. LoginActivty를 제외한 다른 활동에서 어떻게 ProfileActivity를 사용하고 있습니까?
안드로이드

나는 같은 질문을하고있다. memroy가 부족하여 로그인 의도가 시스템에 의해 파괴되면 작동하지 않을 것이라고 생각합니다.
user1914692

5

API 11+의 경우 다음 Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK과 같이 사용할 수 있습니다 .

Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);

모든 이전 활동을 완전히 지우고 새로운 활동을 시작합니다.


4

시도해 볼 수 있으며 finishAffinity()모든 현재 활동을 닫고 Android 4.1 이상에서 작동합니다.


1
API 16에 finishAffinity ()가 추가되었습니다. 이전 버전에서는 ActivityCompat.finishAffinity ()를 사용하십시오. 나는 나를 위해 잘 작동합니다.
Anurag Srivastava 2015

2

저도 같은 문제에 직면하고 있습니다 ..

로그인 활동에서 내가하는 일은.

    Intent myIntent = new Intent(MainActivity.this, ActivityLoggedIn.class);
    finish();
    MainActivity.this.startActivity(myIntent);  

로그 아웃시

   Intent myIntent = new Intent(ActivityLoggedIn.this, MainActivity.class);
   finish();
   ActivityLoggedIn.this.startActivity(myIntent);

이것은 잘 작동하지만 내가 ActivityLoggedIn에 있고 앱을 최소화하고 앱 서랍에서 실행기 버튼 아이콘을 클릭하면 MainActivity가 다시 시작됩니다 :-/ 플래그를 사용하고 있습니다

android:LaunchMode:singleTask 

MainActivity.


2

다음을 사용하십시오. activity

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

조각 사용을 위해 CLEAR_TASK 플래그를 제거 합니다.

나는 이것이 어떤 사람들에게 사용될 수 있기를 바랍니다.


1

계속 유지

Intent intent = new Intent(ProfileActivity.this,
    LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

4
작동하지 않습니다. 여전히 뒤로 버튼을 사용하여 ProfileActivity로 이동할 수 있습니다.
Archie.bpgc

1

의도 플래그 중 어느 것도 나를 위해 일하지 않았지만 이것이 내가 수정 한 방법입니다.

사용자가 한 활동에서 로그 아웃하면 해당 활동에서 메시지를 브로드 캐스트 한 다음 종료하려는 활동에서 수신 한 다음 finish (); 꽤 잘 작동합니다.


1

이것을 시도하면 작동합니다.

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();

1

API 레벨 11 이상에서는 Intent를 사용 FLAG_ACTIVITY_CLEAR_TASK하고 FLAG_ACTIVITY_NEW_TASK플래그를 지정하여 모든 활동 스택을 지 웁니다.

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |  Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

0

이것을 사용하십시오

Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

setFlags와 addFlags를 알고 계셨습니까?
GvSharma

0

활동을 위해 매니페스트에 추가 android:launchMode="singleTask"


0

재사용 가능한 고급 Kotlin :

setter 메서드를 사용하여 직접 플래그를 설정할 수 있습니다. 코 틀린에 or는 IS 교체 자바 비트 또는에 대한 |.

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

이것을 정기적으로 사용하려면 Intent 확장 기능을 만드십시오.

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

그런 다음 인 텐트를 시작하기 전에이 함수를 직접 호출 할 수 있습니다.

intent.clearStack()

다른 상황에서 추가 플래그를 추가하는 옵션이 필요한 경우 확장 함수에 선택적 매개 변수를 추가하십시오.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.