안드로이드 : Clear Activity Stack


132

신청서에 몇 가지 활동이 있습니다. 흐름이 매우 복잡합니다. Logout 응용 프로그램을 클릭하면 로그인 화면으로 이동하고 거기에서 사용자가 취소 버튼을 눌러 종료 할 수 있습니다 (호출 system.exit(0))

내가 종료하거나 다시 버튼을 때, 시스템은 스택에서 활동을 호출 :( 내가 로그인 화면이 표시되면? 스택의 모든 활동을 취소 호출 할 수있는 방법은 finish()있다 이렇게 많은 활동이없는 일부 활동이없는 경우 닫아야으로 실용적이지 못하다 기본 카메라 호출 활동과 같은 활성입니다.

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);


답변:


339

대부분의 사람들이 틀 렸습니다. 내용에 관계없이 기존 활동 스택을 닫고 새 루트를 작성하려면 올바른 플래그 세트는 다음과 같습니다.

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

문서에서 :

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

에 전달 된 의도로 설정된 Context.startActivity()경우이 플래그는 활동이 시작되기 전에 활동과 연관된 기존 태스크가 지워지게합니다. 즉, 활동이 빈 작업의 새 루트가되고 이전 활동이 완료됩니다. 이것은와 함께 만 사용할 수 있습니다 FLAG_ACTIVITY_NEW_TASK.


완벽하게 작동했습니다. 감사. minSDK = 9에서 이상하게 오류가 발생하지 않았습니다.
Mahm00d

솔직히 저는이 기능을 사용하지 않았으며, 충돌 후 부활하는 등 충돌을 일으킨 문제를 해결하는 데 집중했습니다.)
Cynichniy Bandera

IntentCompat.makeRestartActivityTask지원 라이브러리 에서도 동일한 기능을 제공합니다 .
sealskej

이 두 플래그 만 추가하면 활동 스택 트랙이 뒤에 남고 (이전 플래그의 맨 위에서 시작) Intent.FLAG_ACTIVITY_CLEAR_TOP을 추가하여 애플리케이션을 다시 시작한 다음 완전히 종료합니다. 명시 적으로 활동에 플래그를 추가하지 않았습니다. 무엇이 문제 일 수 있습니까?
Farid

1
최고의 시작 중 하나 : "대부분의 사람들이 틀 렸습니다."
nibbana

31

당신이 호출 할 때 startActivity마지막 활동에 항상 사용할 수 있습니다

Intent.FLAG_ACTIVITY_CLEAR_TOP

그 의도에 대한 플래그로.

국기에 대한 자세한 내용은 여기를 참조하십시오 .


그것은 또한 도움이되지 않습니다. 방금 dat가 finish ()로 끝나지 않는 활동을 나타냅니다. :(
Jay Mayu

FLAG_ACTIVITY_CLEAR_TOP에서 상단의 액티비티를 지운 것 같습니다. 내 문제는 바닥에 활동입니다 :(
Jay Mayu

흐름이 실제로 어떻게되는지에 달려 있다고 생각합니다. 당신은 여기에 대한 자세한 내용을 읽어야 developer.android.com/reference/android/content/...developer.android.com/guide/topics/fundamentals/...을
데이비드 올슨에게

7
올바른 자료를 보여 주셔서 감사합니다. 내가 한 실수는 로그인 활동을 닫는 것이 었습니다. 닫아서는 안됩니다. 활동이 처음로드 된시기 따라서 Clear_top 플래그를 사용하여 다시 호출하면 로그인 활동이 맨 위에있는 모든 활동을 지 웁니다. 로그인은 첫 번째 추적 활동이므로 이후에 시작된 모든 활동을 지 웁니다. 그래서 빙고 그것은 일했다 :)
Jay Mayu

13
문서에서 FLAG_ACTIVITY_CLEAR_TOP 은 특정 활동이 "현재 작업에서 이미 실행 중"인 경우에만 스택을 지 웁니다.
AlikElzin-kilaka

16

다음은 API 레벨 4에서 현재 버전 17까지 작동하는 새로운 최상위 활동으로 새 활동을 시작하는 간단한 헬퍼 방법입니다.

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

현재 활동에서 다음과 같이 호출하십시오.

startNewMainActivity(this, MainActivity.class);

1
항상 intent.addFlags (0x8000);를 사용하는 것만은 아닙니다. 그리고 단순화?
Davor

이 플래그는 Honeycomb에서 처음 소개되었으므로 이전 버전에서 어떤 영향을 줄지 잘 모릅니다. 그래서 이것은 제가 precaucios 인 것입니다. 그러나 나는 conditial을 제거하는 것이 문제가되지 않아야한다고 생각합니다.
whlk

1
API 레벨은 당신이해야 할 다음 <11 때 해당 플래그를 추가 할 Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB다른 intent.addFlags(0x8000);추가하지 않습니다
밀짚 모자

의도를 통해 사용자가 여러 가지 활동으로 차례로 이동하도록하고 있습니다. 앱이 스택에서 너무 많은 활동으로 충돌하지 않도록하기 위해 무엇을해야합니까? 감사!
Ruchir Baronia

9

아래 코드로 Activity Backstate를 지우 십시오.

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

끝난


의도를 통해 사용자가 여러 가지 활동으로 차례로 이동하도록하고 있습니다. 앱이 스택에서 너무 많은 활동으로 충돌하지 않도록하기 위해 무엇을해야합니까? 감사!
Ruchir Baronia

@ RuchirBaronia, 당신이 가면 A-> B-> C-> D-> E-> F-> G-> H, 이제 H-> 나는 마지막 활동이 될 것보다 코드를 작성하고 뒤로 버튼을 누릅니다. 앱에 백 스테이트 활동이 없으므로 앱이 종료됩니다. 도움이 되길 바랍니다.
Hiren Patel

그래도해야합니까? 활동 스택을 정리하지 않으면 어떻게됩니까?
Ruchir Baronia

@RuchirBaronia, Backpress : H -> G -> F -> E -> D -> C -> B ->은
Hiren 파텔

그러나 새로운 활동을 부르는 동안 흰색 화면이 나타납니다. 이 문제를 해결하기 위해 호?
Sagar

4

필자의 경우 LoginActivity도 닫혔습니다. 결과적으로

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

도와주지 않았다.

그러나 설정

Intent.FLAG_ACTIVITY_NEW_TASK

나를 도와 주었다.


의도를 통해 사용자가 여러 가지 활동으로 차례로 이동하도록하고 있습니다. 앱이 스택에서 너무 많은 활동으로 충돌하지 않도록하려면 어떤 조치를 취해야합니까? 감사!
Ruchir Baronia

3
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();

1
왜 둘 다 사용 this.finish()하고 setFlags()현재 활동을 지우는가?
Sagar

3

나는 당신이에 의존하지 않는 해결책을 요구 finish()했지만, 이것이 도움이 될지 궁금합니다.

종료 플래그가 정적 클래스 변수로 발생하는지 추적하여 전체 앱 수명 동안 유지됩니다. 각에서 관련 활동의 onResume()사용

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

ExitHelper 클래스

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

설정할 수있는 -의이 mainActivity에서, 사용자가 출구 버튼을 누르면 생각한 ExitHelper.isExitFlagRaised = true;다음과 finish(). 그 후 자동으로 재개되는 다른 관련 활동도 완료됩니다.


MainActivity onresume () 코드를 사용한 다음 두 번째 활동 onbackpress
Mithu

3

이 결정은 잘 작동합니다.

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

그러나 새로운 활동이 오래 시작되고 어느 정도 흰색 화면이 표시됩니다. 이것이 중요한 경우이 해결 방법을 사용하십시오.

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

사용 방법 :

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

단점 : 스택에서 닫아야하는 모든 활동은 BaseActivity를 확장해야합니다.


2

Xamarin 개발자의 경우 다음을 사용할 수 있습니다.

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);

1

코 틀린 사용하기 :

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

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

이것을 정기적으로 사용하려는 경우 의도 확장 기능을 작성하십시오.

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

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

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