활동이 애플리케이션의 활동 스택에서 마지막 활동인지 확인하는 방법은 무엇입니까?


답변:


116

업데이트 (2015 년 7 월) :

이후 getRunningTasks () API (21)로부터 팔로우하는 것이 좋습니다, 사용되지 않는 얻을 raukodraug의 대답 이나 에드 Burnette 하나를 (내가 두 번째 선호).


ActivityManager를 사용하여 현재 작업과 스택을 확인할 수 있습니다 .

따라서 활동이 마지막 활동인지 확인하려면 :

  • 매니페스트에서 android.permission.GET_TASKS 권한을 요청합니다.
  • 다음 코드를 사용하십시오.

    ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
    
    List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
    
    if(taskList.get(0).numActivities == 1 &&
       taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
        Log.i(TAG, "This is last activity in the stack");
    }

위의 코드는 단일 작업이있는 경우에만 유효합니다. 애플리케이션에 대한 작업 수가 존재할 가능성이있는 경우-다른 taskList 요소 를 확인해야합니다 . 작업 작업 및 백 스택 에 대해 자세히 알아보기



25
H9kDroid가 올바른 제안을했습니다. 선택한 답변은 해킹입니다. 방법을 사용하여 올바른 방법으로해야합니다 isTaskRoot().
Sufian

@Sufian 특히 해킹은 어디입니까? 코드는 논리적이며 사용하려는 방식으로 개방형 Android API를 사용합니다 (예 : getRunningTasks를 사용하여 실행중인 작업을 가져와야하며 이러한 작업을 분석 할 목적으로 만 호출 할 수 있습니다). get (0)의 사용법은 잘 문서화되어 있고 논리적입니다. '현재 실행중인 작업 목록을 반환합니다. 가장 최근 작업은 첫 번째 작업이고 오래된 작업은 순서대로 반환합니다.'
sandrstar

2
getRunningTasks은 () API 레벨 21에서 더 이상 사용되지 않습니다
gilchris

조각에도 똑같이 할 수 있습니까? 그렇다면 어떻게? 도와주세요
사가르 Devanga

1
Mr.Drew는 @ raukodraug에서 가장 높은 투표 대답을 참조 @
데이비드 WASSER

167

비슷한 질문을 가진 사람들을 위해 여기 에 @ H9kDroid 의 댓글을 베스트 답변으로 게시 하겠습니다.

isTaskRoot () 를 사용 하여 활동이 작업의 루트인지 여부를 알 수 있습니다 .

이게 도움이 되길 바란다


1
isTaskRoot를 사용하는 방법을 명확히 할 수 있도록 한 줄의 코드를 제공해 주시겠습니까? 감사.
Kaveesh Kanwal 2015 년

18
@TheHunterif (isTaskRoot()) { // do something }
howettl

3
유일한 문제는 <= 4.4에서> = 5.x에서와 다른 동작을하는 것으로 보입니다. 항상 거짓을 반환하는 것 같습니다.
chubbsondubs

댓글에 제공된 샘플 코드를 답변에 통합하여 향후 독자가 더 쉽게 이해할 수 있도록해야한다고 생각합니다.
Isac

훌륭한 대답입니다. 제 경우에는 사용자가 알림을 클릭 한 후 이전에 애플리케이션을 닫은 경우 활동이 루트가 될 수 있습니다.
dave o grady

19

이것이 새로운 초보자에게 도움이되기를 바랍니다. 위의 답변을 기반으로 잘 작동하며 코드 스 니펫을 공유하여 구현하기 쉽습니다.

솔루션 : 내가 사용 isTaskRoot()반환하는 진정한 경우 현재의 활동 만 스택에서 활동 한다면 나는 또한의 경우를 처리 이외의 내가 대신 새로운 개방의 스택의 마지막 활동 스택 이동에서 일부 활동이 사용자 정의 하나.

당신의 활동에서

   @Override
    public void onBackPressed() {

        if(isTaskRoot()){
            startActivity(new Intent(currentActivityName.this,ActivityNameYouWantToOpen.class));
            // using finish() is optional, use it if you do not want to keep currentActivity in stack
            finish();
        }else{
            super.onBackPressed();
        }

    }


5

이것을 달성하는 방법이있을 수 있지만 (다른 답변 참조) 그렇게하지 말 것을 제안합니다. 일반 Android 애플리케이션은 홈 화면이 표시 될 것인지 여부를 알 필요가 없습니다.

데이터를 저장하려는 경우 데이터 저장 코드를 onPause () 메서드에 넣으십시오. 사용자에게 기존 애플리케이션에 대한 마음을 바꿀 수있는 방법을 제공하려는 경우 Back 키 및 onBackPressed () 메서드에 대한 키 위 / 아래를 가로 채서 "Are you sure?"를 표시 할 수 있습니다. 신속한.


1
사용자가 활동을 떠나지 않는 한 서비스를 실행해야한다면 어떨까요? 화면이 꺼진 후에 호출 될 수 있기 때문에 onStop과 같은 기능을 트랩 할 수 없습니다.
Michael

2
백그라운드 서비스가 활동을 시작하는 경우 스택의 유일한 활동인지 여부를 알고 싶을 것입니다.
Matt W

4

이를 추적하는 한 가지 방법은 새 활동을 시작할 때 마커를 포함하고 마커가 있는지 확인하는 것입니다.

새 활동을 시작할 때마다 마커를 삽입하십시오.

newIntent=new Intent(this, NextOne.class);
newIntent.putExtra(this.getPackageName()+"myself", 0);
startActivity(newIntent);

그런 다음 다음과 같이 확인할 수 있습니다.

boolean islast=!getIntent().hasExtra(this.getPackageName()+"myself")

1
활동이 종료되고 활동 스택이 재구성되면 작동하지 않습니다 (요구에 따라 각 활동).
AlikElzin-kilaka

3

사용하는 sandrstar 솔루션의 문제점은 다음과 같습니다 ActivityManager. 이런 방식으로 작업을 가져 오려면 권한이 필요합니다. 더 나은 방법을 찾았습니다.

getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)

Activity다른 활동을하지해야하는 동안 스택 하단은에 allways 기본적으로이 범주를 받아야합니다.
그러나 이것이 일부 장치에서 실패하더라도 다음을 시작하는 동안 설정할 수 있습니다 Activity.

Intent intent = new Intent(startingActivity, SomeActivityClass.class);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
activity.startActivity(intent);

활동이 푸시 알림에서 열리면 어떻게됩니까? 그들은 CATEGORY LAUNCHER가 없습니다
nbtk

내 대답의 두 번째 부분이 여전히 적용된다는 것을 확신합니다. 인 텐트에서 카테고리를 힌트로 설정할 수 있습니다. 이 경우 알림 컨텍스트의 의도 일 수 있습니다. 그 외에는 플래그를 사용할 수도 있습니다. 의도가있는 알림 생성은이 링크를 참조하십시오. stackoverflow.com/questions/13716723/…
A. Binzxxxxxx

그래도 가장 오래된 활동이 MainActivity이고 이제 재개 된 다음 푸시 알림을 받고 CATEGORY_LAUNCHER로 열도록 pendingIntent를 설정하면이 범주에 2 개의 활동이 있습니다. 아마도 다른 작업에있을 것입니다
nbtk

알림과 어떻게 작동하는지 정확히 모르겠습니다. 나는 당신이 여기서하는 것처럼 그들을 사용하지 않았습니다. 이 방법으로 쉽게 할 수있는 방법이 있다고 확신하지만 2014 년 1 분기 이후로 안드로이드 코드를 건드리지 않았습니다.이 경우에 두 번째 카테고리를 사용하고 싶습니까? 아니면 깃발? 그러나 나는 그 정신이 이렇게 작동한다고 생각합니다. 주 활동을 시작하고 올바른 활동을 열기 위해 일종의 메타 정보를 추가하는 것은 어떻습니까?
A. Binzxxxxxx

2

내 모든 활동에 대한 기본 클래스를 만들고 AppCompatActivity를 확장하고 정적 카운터가 있습니다.

public abstract class BasicActivity extends AppCompatActivity {
    private static int activityCounter = 0;

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

    @Override
    public void onDestroy() {
        super.onDestroy();
        --activityCounter;
        if(activityCounter==0) {
            // Last instance code...
        }
    }

    public boolean isLastInstance() { return (activityCounter==1); }
}

이것은 지금까지 충분히 잘 작동했습니다. 그리고 API 버전에 관계없이. 물론 모든 활동이이 기본 클래스를 확장해야합니다. 제 경우에는 그렇게합니다.

편집 : 앱이 완전히 종료되기 전에 카운터가 0으로 내려가는 경우가 하나 있는데, 이는 방향이 변경되고 하나의 활동 만 열려있는 경우입니다. 방향이 변경되면 활동이 닫히고 다른 활동이 만들어 지므로 onDestroyed마지막 활동에 대해 onCreate호출 된 다음 변경된 방향으로 동일한 활동이 생성 될 때 호출됩니다. 이 동작을 고려해야합니다. OrientationEventListener를 사용할 수 있습니다.


0

Android는 활동 스택을 구현합니다 . 여기에서 이에 대해 읽어 보시기 바랍니다 . 하지만 원하는 것은 호출 활동을 검색하는 것 getCallingActivity()입니다. 현재 활동이 애플리케이션의 첫 번째 활동이고 애플리케이션이 홈 화면에서 시작된 경우을 반환해야합니다 null.


9
startActivityForResult ()를 통해 활동이 시작되지 않은 경우 getCallingActivity ()가 null을 반환하므로 작동하지 않습니다.
H9kDroid 2011-06-03

0

여기서 놓친 한 가지는 "홈 키"클릭입니다. 활성화되면 활동에서이를 감지 할 수 없으므로 "뒤로 키"누르기를 처리하고 필요한 활동으로 이동하여 프로그래밍 방식으로 활동 스택을 제어하는 ​​것이 좋습니다. 필요한 단계 만 수행합니다.

또한 "최근 활동"목록에서 활동을 시작하는 경우 일부 추가 데이터를 활동을 열기위한 의도로 사전 설정하여 감지 할 수 있는지 확신 할 수 없습니다.이 경우 재사용되기 때문입니다.

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