히스토리 스택에서 활동 제거


382

내 앱은 사용자가 앱을 처음 실행할 때 가입 활동을 보여줍니다.

  1. ActivitySplashScreen (게임에 오신 것을 환영합니다, 계정에 가입 하시겠습니까?)
  2. ActivitySplashScreenSignUp (위,이 정보를 입력하십시오)
  3. ActivityGameMain (메인 게임 화면)

사용자가 각 화면에서 버튼을 클릭하면 활동이 순서대로 정확하게 실행됩니다.

사용자가 활동 # 2에서 # 3으로 이동하면 내역 스택에서 # 1 및 # 2를 완전히 지울 수 있습니까? 사용자가 # 3에 있고 뒤로 버튼을 누르면 스플래시 화면으로 돌아 가지 않고 홈 화면으로 이동합니다.

나는 작업 으로이 작업을 수행 할 수 있다고 생각합니다 (즉, # 3에서 새 작업을 시작하십시오). 그러나 더 간단한 방법이 있는지 확인하고 싶었습니다.

감사


홈 화면에있는 후 사용자가 앱을 재개하면 ActivitySplashScreen 또는 ActivityGameMain으로 이동합니까?
Tamil

답변:


632

파일 의 관련 항목에서 android:noHistory 속성 을 로 설정하면 됩니다. 예를 들면 다음과 같습니다."true"<activity>AndroidManifest.xml

<activity
    android:name=".AnyActivity"
    android:noHistory="true" />

12
이것이 가장 좋은 방법입니다.
shkschneider

22
동등하게 사용할 수 있습니다 FLAG_ACTIVITY_NO_HISTORY.
Timmmm

34
코드에서 어떻게 이것을 달성 할 수 있습니까? 나는 항상 이것을하고 싶지 않기 때문에. 특정 조건 하에서 만 주어진 활동을 기록에서 제거하고 싶습니다.
Namratha

8
noHistory 속성을 사용하면 해당 활동이 완료되어 G + 로그인에서 예기치 않은 동작이 발생할 수 있습니다. 참조 : stackoverflow.com/questions/20383878/...이 내 응용 프로그램이 어떤 흔적도없이 충돌 유지로이 버그를 찾는 걸 렸어요.
Acapulco

13
필요한 플래그는 링크이므로 복사하기가 어렵 기 때문에 여기서 쉽게 복사 할 수 있습니다. android:noHistory="true"
MirroredFate

137

전달을 사용하여 다음 활동을 시작하는 동안 활동 스택에서 이전 활동을 제거 할 수 있습니다. APIDemos에 이것의 예가 있지만 기본적으로 당신이하는 일은 call finish()직후에 호출하는 것 startActivity()입니다.


1
안녕 다니엘, 나는 예제를 읽었지만 그것은 1 활동으로 기록 스택을 지우는 것입니까? 내 스택이 A, B처럼 보이고 C를 시작하는 경우 C를 새로운 루트로 만들고 A와 B를 완전히 지우고 싶습니다. SDK 예제에서 finish ()를 B에서 호출하면 A 스택이 남습니다. C, 그렇지 않습니까? 감사.
Mark

1
B를 시작하면 A를 지우고 C를 시작하면 B를 지울 수 있습니다. 그러나 원하는 경우 B에서 A로 되돌릴 수는 없다고 생각합니다. 그것이 문제라면 이것에 대해 더 생각해야 할 것입니다.
Dan Lew

3
Mark, 원하는 것을 달성하려면 FLAG_ACTIVITY_CLEAR_TOP 플래그를 사용해야합니다. 도움이 되길 바랍니다.
Francisco Junior

3
FLAG_ACTIVITY_CLEAR_TOPC가 이미 백 스택에 없기 때문에 작동하지 않습니다.
Timmmm

1
@DanielLew APIDemos에는 많은 예제가 있습니다. 예제의 이름이 제안 되었습니까?
Stephane

52

예, Intent.FLAG_ACTIVITY_NO_HISTORY를 살펴보십시오 .


46
이렇게하면 시작한 활동에 대한 기록이 설정되지 않습니다. 시작한 활동에 대한 기록이 없도록 android:noHistory="true"매니페스트에서 설정했습니다 .
georgiecasey 2012 년

1
이것은 잘 작동합니다. 를 사용 intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)하여이 플래그를 설정하십시오.
vovahost

1
@georgiecasey 이것은 때때로 당신이 역사에 그것을 유지하고 때로는 역사에 그것을 원하지 않을 때 유용합니다.
Vihaan Verma

24

이것은 이상적인 방법은 아닙니다. 누군가가 더 나은 방법을 가지고 있다면 그것을 구현하기를 고대 할 것입니다. 여기에 방법은 내가 이전 버전-11 SDK이 특정 작업을 수행.

명확한 시간에 떠나고 싶은 각 수업에서 다음을 수행해야합니다.

    ... interesting code stuff ...
    Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == R.string.unwind_stack_result_id) {
        this.setResult(R.string.unwind_stack_result_id);
        this.finish();
    }
}

스택에서 팝 체인을 설정 해야하는 것은 시작하려는 경우 이것을 호출해야합니다.

NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();

그런 다음 활동은 스택에 없습니다!
사람들을 기억하십시오. 활동을 시작한 다음 정리를 시작할 수 있습니다. 실행은 단일 (ui) 스레드를 따르지 않습니다.


누군가 나중에이 문제가 발생하는 경우 화면을 회전하면 Android가 스택의 마지막 활동을 표시 할 때 응용 프로그램을 유용하게 다시 시작하는 것이 중요하다는 것을 알고 있다고 생각했습니다. 이것 만 알아 두세요!
트래비스

당신은 단지 조건부 사용자가 +1 다음 활동에서 무엇을하는지에 따라 스택에서 활동을 제거하려는 경우 좋은 답변입니다
theMothaShip

23

API 11 이전에 작동하는 한 가지 방법은 ActivityGameMain먼저 시작한 다음 onCreate해당 활동에서 활동을 시작하는 것 ActivitySplashScreen입니다. 은 ActivityGameMain당신이 너무 빨리 시작에 대한 startActivity를 전화로 나타나지 않습니다.

그런 다음 Intent에서 다음 플래그를 설정하여 시작할 때 스택을 지울 수 있습니다ActivityGameMain .

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

또한 이것을 ActivitySplashScreen에 추가해야합니다.

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

따라서 해당 활동을 다시 눌러도 귀하의 (으)로 돌아 가지 않습니다 ActivityGameMain.

스플래시 화면이 다시 돌아 가지 않기를 원한다고 가정 noHistory합니다 AndroidManifest.xml. 그런 다음 대신 클래스에 goBackPressed코드를 넣으십시오 ActivitySplashScreenSignUp.

그러나 나는 이것을 깨는 몇 가지 방법을 발견했다. 알림 ActivitySplashScreenSignUp이 표시 되는 동안 알림에서 다른 앱을 시작 하면 이전 기록이 재설정되지 않습니다.

이 문제를 해결하는 유일한 방법은 API 11입니다.

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

20

이 방법을 사용합니다.

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

감사. 내 메뉴에 홈 버튼이있는 경우이 기능이 유용하다는 것을 알았으며 사용자가 거기에서 집을 클릭하면 누적 된 활동이 표시되는 것을 원하지 않았습니다.
ghitesh 2016 년

8

나는 이것에 늦었다는 것을 알고 있습니다 (질문이 제기 된 지 2 년이 지났습니다). 그러나 뒤로 버튼 누름을 가로 채서 이것을 달성했습니다. 특정 활동을 확인하는 대신 카운트를보고 3보다 작 으면 단순히 앱을 뒤로 보냅니다 (앱을 일시 중지하고 시작하기 전에 실행중인 모든 항목으로 사용자를 반환). 소개 화면이 하나 밖에 없기 때문에 3 개 미만을 확인합니다. 또한 앱을 통해 사용자가 메뉴를 통해 홈 화면으로 돌아갈 수 있으므로 카운트를 확인하므로 스택에 소개 화면 이외의 활동이있는 경우 일반과 같은 다른 화면을 통해 백업 할 수 있습니다.

//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
@Override
public void onBackPressed() {
    //Check the activity stack and see if it's more than two deep (initial screen and home screen)
    //If it's more than two deep, then let the app proccess the press
    ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
    int activityCount = tasks.get(0).numActivities;

    if (activityCount < 3)
    {
        moveTaskToBack(true);
    }
    else
    {
        super.onBackPressed();
    }
}

7

매니페스트에서 다음을 추가 할 수 있습니다.

android:noHistory="true"

<activity
android:name=".ActivityName"
android:noHistory="true" />

전화 할 수도 있습니다

finish()

startActivity (..)를 호출 한 직후


2
매니페스트에 물건을 넣는 것보다 활동 플래그를 사용하는 것이 좋습니다.
Trevor Hart


4

아무도이 우아한 해결책을 언급하지 않은 것은 미안합니다. 이것이 정답입니다.

SplashActivity -> AuthActivity -> DashActivity

if (!sessionManager.isLoggedIn()) {
    Intent intent = new Intent(context, AuthActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    context.startActivity(intent);
    finish();
} else {
   Intent intent = new Intent(context, DashActivity.class);
   context.startActivity(intent);
    finish();
}

여기서 핵심 intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 은 중개자 용 Activity입니다. 중간 링크가 끊어 DashActivity지면 스택의 첫 번째 링크 와 마지막 링크입니다 .

android:noHistory="true"Activity콜백으로 의존 할 때 문제가 발생하기 때문에 나쁜 해결책 onActivityResult입니다. 이것은 권장되는 솔루션이며 수락해야합니다.


1
그 깃발은 너무 좋아서 사실이 아니 었습니다. FLAG_ACTIVITY_NO_HISTORY는 훌륭하게 작동하며 스택 상단에 플래그가있는 활동을하는 동안 앱을 백그라운드에 놓은 다음 다시 포 그라운드 할 때까지 예상대로 작동합니다. 배경으로 이동하면 활동이 파괴됩니다. 앱으로 돌아 오면 스택에서 이전 활동이 표시됩니다. 나는 그런 행동을 원하지 않았다.
NeverwinterMoon

4

너무 늦었지만 도움이 되길 바랍니다. 대부분의 답변이 올바른 방향을 가리키고 있지 않습니다. 그러한 것에 대한 두 가지 간단한 플래그가 있습니다.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

안드로이드 문서에서 :

public static final int FLAG_ACTIVITY_CLEAR_TASK API 레벨 11에 추가됨

If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the

활동이 시작되기 전에 지워질 활동. 즉, 활동이 빈 작업의 새 루트가되고 이전 활동이 완료됩니다. FLAG_ACTIVITY_NEW_TASK와 함께 만 사용할 수 있습니다.


1

다음과 같이 startActivity (intent) 전에 this.finish ()를 호출하십시오.

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

"이", "ActivityOne.this"로 변경해야한다에 오류가있는 사용자
ninbit

1

히스토리에서 활동 제거가 수행되었습니다. 원하지 않는 활동 전에 플래그를 설정하여

A-> B-> C-> D

B와 C를 지우고 플래그를 설정하려는 경우 A, B, C 및 D가 4 활동이라고 가정하십시오.

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

활동 A와 B에서

여기 코드 비트가 있습니다

Intent intent = new Intent(this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);

0
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            super.finishAndRemoveTask();
        }
        else {
            super.finish();
        }

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.