[안드로이드] Activity launch 모드 정리 + Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASKg해결하기

Lee Yongin·3일 전
0

안드로이드

목록 보기
24/27

에러현상

카카오 로그인을 구현하던 중 아래와 같은 오류가 발생했다.

android.util.AndroidRuntimeException: Calling
startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:974)

에러원인

startActivity는 하나의 Activity가 다른 Activity를 호출할 때 사용한다. 만약 Activity 밖에서 호출하게 되면 위의 에러가 발생할 수 있다.

해결 및 원리

마니페스트 파일 launchMode 추가하기

아래와 같이 android:launchMode = "singleTask" 속성을 추가하면 Activity 인스턴스가 하나만, 위에 존재하도록 설정할 수 있다.

 <activity
                android:name=".presentation.MainActivity"
                android:exported="true"
           android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

android:launchMode

아래와 같이 총 5개의 모드가 있다. 액티비티를 호출할 때 새로운 인스턴스의 생성 유무, 스택구조, 동일 액티비티를 여러번 오픈하는 유무에서 차이가 있다.

android:launchMode=["standard" | "singleTop" |
                              "singleTask" | "singleInstance" | "singleInstancePerTask"]

launchMode:standard

기본 값으로 지정된 모드이다.

새로운 인스턴스가 항상 생성된다.
기존 인스턴스가 있어도 무조건 새로운 액티비티를 생성하고 스택에 쌓는다.
동일한 액티비티를 여러 번 열 수 있다.

A → B → B → B (B 여러 개 생성 가능)

launchMode:singleTop

현재 태스크의 맨 위에 동일한 액티비티가 있다면 새로 생성하지 않고 기존 인스턴스를 재사용하는 것이다.
A->B->B 호출순서라면, 스택에서는 Top에 있는 B를 재사용해서 A->B 밖에 없는 상태이다.

A → B → B (B가 Top에 있으면 새로 안 만들어짐, 아니면 새로 생성)

launchMode:singleTask

테스크 내에 동일한 액티비티가 존재하면 새로운 인스턴스를 만들지 않고 기존 인스턴스를 재사용하는 것이다. singleTop은 스택의 위쪽(Top)에 있는 인스턴스를 대상으로만 하는 반면에, singleTask는 스택 내 모든 인스턴스를 대상으로 재사용하고, 해당 액티비티 위의 모든 액티비티를 제거한 후 최상단에 위치시킨다.

A → B → C → D → B (B는 기존 인스턴스를 사용하고, C, D는 스택에서 제거됨)

launchMode:singleInstance

오직 하나의 인스턴스만 생성되며, 별도의 태스크에서 실행된다.
다른 액티비티에서 singleInstance로 지정한 액티비티로 이동하면 새로운 테스크가 생성된다.
절대 다른 액티비티 위에 추가되지 않는 특성이 있어서, 뒤로 가기 시 새로운 태스크에서 실행된 액티비티는 완전히 사라진다.

Task 1: A → B → C
Task 2: D (singleInstance, 독립 실행)
Task 1: C → B → A

그외 방법

flag 추가하기

해결방법을 보면 알 수 있듯이 startActivity를 호출할 때 오류메세지가 알려주는 대로 FLAG를 추가해해도 된다.

Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 추가하기
context.startActivity(i); 

이렇게 하면 기존 MainActivity가 아닌 새롭게 MainActivity가 생성된다.

pendingIntent 사용하기

내부적으로는 flag 추가와 같은 효과를 낸다고 한다.

참고자료

https://developer.android.com/guide/topics/manifest/activity-element?hl=ko
https://m.blog.naver.com/kkson50/222528329342
https://velog.io/@wyt_cpri/Android-LaunchMode-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0

                                                                                                  
profile
⚡실력으로 말하는 개발자가 되자⚡p.s.기록쟁이

0개의 댓글