[Android] Flag란? Intent Flag 사용

Oxong·2021년 7월 2일
0

21.07.02
공부한 것을 정리하는 용도의 글이므로 100% 정확하지 않을 수 있습니다.
참고용으로만 봐주시고, 내용이 부족하다고 느끼신다면 다른 글도 보시는 것이 좋습니다.
+ 틀린 부분, 수정해야 할 부분은 언제든지 피드백 주세요. 😊
                                            by. ryalya



들어가기 전

요즘은 안 그렇지만 예전에는 안드로이드 어플을 사용하다 보면 가끔 back 버튼을 눌렀을 때, 같은 화면이 한 번 더 보이는 현상이 흔하게 보였다.

액티비티로 작업을 할 때, 흔하게 볼 수 있는데
예를 들어 A와 B화면을 번갈아서 A→B→A→B 화면 교체를 했다고 가정해보자.

사용자 입장에서는 A가 사라지고 B가 생긴 것이지만 스택 입장에선 그렇지 않다.
스택에는 계속 A→B→A→B→A→B 순서대로 차곡차곡 쌓여 있다.

따라서 사용자가 back버튼을 누르면 쌓여있던 화면들이 하나씩 등장하게 되므로 계속해서 이전 화면이 한 번 더 보이게 되는 것이다.

이렇게 스택에 계속해서 새로운 액티비티가 쌓이는 것을 막으려면? Flag를 사용하면 된다!



Flag란?

task

안드로이드의 화면 구성은 기본적으로 Activity로 이루어진다.

Task는 stack구조로 되어있는 Activity를 보관하고 관리하는 것을 말한다.

우리는 Intent를 사용하여 Activity를 교체하고, 통신도 한다.

아래와 같은 코드를 많이 이용해봤을 것이다.

Intent intent = new Intent(A.this, B.class)
startActivity(intent)

위의 코드에서 처럼 new를 사용하여 Intent를 교체하게 되면 task라고 불리는 Activity stack에 Activity들이 차곡차곡 쌓이게 된다.

효과적인 UX Flow를 구축하기 위해서는 Flag를 이용하여 Activity의 중복 문제, 흐름 등을 제어(통제)할 수 있다.



Flag 사용법

Flag는 Manifest에서 사용하는 방법과 Java 소스코드로 사용하는 방법이 있다.

1. Manifast 사용법

Android Manifest.xml파일에 아래 코드 추가

<activity android:launchMode="사용하고자 하는 Flag"

위의 ""안에는 아래 속성들 중 원하는 속성을 선택하여 Activity에 적용하면 된다.

ㆍ standard

→ 별도의 Task를 생성하지 않고, 스택 중 어느곳에나 위치 가능하며, 여러개의 Instance 생성 가능.

ㆍ singleTop

→ 이 Flag를 Activity에 설정하면 Task의 Top에 생성하려는 Activity가 존재하는 경우 새로운 Activity를 Top에 올리지않고 기존의 Activity를 재사용한다.

여기서 재사용이란 Activity가 재사용되서 활성화가 될때 Activity의 Instance가 생성되는 것이 아니라 하나의 Instance가 onPause() -> onNewIntent() -> onResume() 생명주기만을 반복하는 것을 의미한다.

ㆍ singleTask

→ RootActivity로만 존재하며 하나의 Instance만 생성 가능. (다른 Task에서도 동일한 Activity 실행 불가) but, 다른 액티비티 실행 시 동일 Task내에서 실행 가능.

ㆍ singleInstance

→ RootActivity로만 존재하며 하나의 Instance만 생성가능하고 Task내에 해당 Activity 하나만 속할 수 있어 다른 Activity를 실행시키면 새로운 Task가 생성되어 (FLAG_ACTIVITY_NEW_TASK와 동일) 그 Task내에 포함된다.


2. 소스 코드 사용법

Java Class내에서 intent.addFlags 또는 intent.setFlags() 함수를 사용하여 flag를 적용할 수 있다.

<예시>
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

여기서 Intent.addFlags()를 사용하면 새로운 flag를 기존 flag에 붙이는 것이고,
Intent.setFlags()를 사용하면 오래된 flag 전체를 대체하는 것이다.



Flag 정리

ㆍ FLAG_ACTIVITY_CLEAR_TOP

→ 호출하는 Activity가 stack에 존재할 경우, 해당 Activity를 최상위로 올리면서, 그 위에 존재하던 액티비티들은 모두 삭제하는 flag

예를 들어 ABCDE가 존재하는 상태에서 C를 호출하게 되면 ABC만 남게 된다.

cf) onCreate()가 아닌 재사용만 하고 싶을 경우, FLAG_ACTIVITY_SINGLE_TOP 속성과 같이 사용하면 됨

ㆍ FLAG_ACTIVITY_SINGLE_TOP

→ 호출되는 Activity가 최상위에 존재할 경우에는 해당 Activity를 다시 생성하지 않고, 존재하던 Activity를 다시 사용함.

예를 들면 ABC가 존재하는 경우에 C를 호출하게 되면 기존과 동일하게 ABC가 나옴.

ㆍ FLAG_ACTIVITY_FORWARD_RESULT

→ startActivityForResult를 이용하여 Activity를 호출할 경우에, 호출하는 쪽이 아닌 한번 더 거쳐서 Result를 받고 싶은 경우에 사용.

A->B->C 일 경우에 C에서 setResult를 설정하여주고, B에서 finish를 하게 되면 A에서는 C의 값을 받을수 있다.

ㆍ FLAG_ACTIVITY_NEW_TASK

→ 새로운 task를 생성하여 그 task 안에 Activity를 추가할때 사용.

단, 기존에 존재하는 task들 중에 생성하려는 Activity와 동일한 affinity를 가지고 있는 task가 있다면 그곳으로 Activity가 들어가게 된다.

하나의 어플리케이션안에서는 모든 Activity가 기본 affinity를 가지고 같은 테스크안에서 동작하는 것이 기본적이지만, FLAG_ACTIVITY_MULTIPLE_TASK flag와 함께 사용 하지 않을 경우, 무조건적으로 task가 새로 생성되는것은 아니므로 주의해야 한다.

ㆍ FLAG_ACTIVITY_MULTIPLE_TASK

→ FLAG_ACTIVITY_NEW_TASK와 함께 사용하여야 하며 혼자만 사용할 경우 아무 소용 없음.

2개의 flag를 동시에 사용할 경우 새로운 task는 재활용되지 않고 무조건 새로 생성되며 피호출되는 Activity는 이 새로운 task의 최상위 Activity가 된다.

ㆍ FLAG_ACTIVITY_NO_HISTORY

→ Activity가 stack에 존재하지 않게 되도록 한다. (주로 로딩 화면에 사용)

ㆍ FLAG_ACTIVITY_REORDER_TO_FRONT

→ 이 flag를 이용하게 되면 호출하려는 Activity가 stack에 존재할 경우 최상위로 올려주는 효과를 가지게 된다.

예를 들어 ABCDE가 있을 경우, C를 호출하게 되면 ABDEC순서로 정렬이 변경된다.

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

→ Intent를 이용하여 새로운 task를 생성하거나 존재하고 있는 task를 포그라운드로 가져오는 경우가 아닌 경우에는 아무런 효과가 없는 flag.

적절한 경우에 task를 리셋하게 되는데, task의 affinity설정에 맞추어 리셋이 발생한다.



※ 다른 액티비티 종료

종료될 Activity에 선언.

 public static 액티비티명 activity = null;    //액티비티 변수 선언
 
   public void onCreate(Bundle savedInstanceState) { 
  activity = this; 
}

타 Activity에서 종료

 if(액티비티명.activity!=null){ //액티비티가 살아 있다면

   액티비티명 activity = (액티비티명)액티비티명.activity;
   activity.finish();
}


Reference

task 이미지 출처

Flag 사용법 출처
Flag 사용법 출처2

0개의 댓글