2021. 11. 17. 14:46ㆍAndroid
안드로이드에서 Activity 간의 이동은 startActivity()와 startActivityForResult()로 이루어진다.
startActivity는 startActivity(new Intent(현재액티비티, 이동할액티비티))로 사용하는데 이렇게 이동할 때마다 스택에 액티비티가 계속 쌓인다. 예를 들어 A -> B -> C -> D 이런 과정으로 액티비티 이동했을 경우엔 D 액티비티가 가장 후입 되었기 때문에 스택의 가장 위에 위치하며 나머지 A,B,C 액티비티들이 차곡차곡 스택에 쌓이게 된다. 이런식으로 액티비티 이동을 지속하게 되면 스택에 액티비티가 계속해서 쌓이게 된다것이다. 이렇게 쌓인 액티비티는 finish()라는 메소드를 통해서 스택에서 제거할 수 있는데 액티비티를 이동할 때마다 제거할지 아니면 나중에 제거할지 등 목적에 따라 활용방법이 다양하다. 해당 게시글은 안드로이드 미니 프로젝트를 개발하면서 활용했던 기술들의 기록이다.
finish()
서문에서 설명했듯이 A라는 액티비티에서 B라는 액티비티로 이동하게 될 경우 A가 사라지는 것이 아닌 B 아래에 깔리게 된다. 안드로이드 폰의 경우 뒤로가기 버튼이 필수로 내장되어 있기 때문에 B에서 뒤로가기를 하게 되면 B액티비티는 스택에서 제거되고 A액티비티로 이동된다. 그럼 A -> B로 이동할 때 A를 제거하기 위해서는 어떻게 해야 할까. 그 방법은 A -> B로 넘어가면서 finish() 해주면 된다.
// A액티비티
startActivity(new Intent(A.this, B.class));
finish();
이런식으로 A에서 B로 넘어갈 때 finish()를 호출해주면 B로 넘어가면서 A는 스택에서 제거된다.
FLAG_ACTIVITY_CLEAR_TOP
안드로이드에서 Activity를 호출하다보면 발생하는 Activity의 중복문제나 흐름을 제어해주고 싶을 때 Flag를 사용한다.
그 중에서 FLAG_ACTIVITY_CLEAR_TOP은 이동할 액티비티가 스택에 존재할 경우 해당 액티비티를 최상위로 올리면서 그 위에 존재하는 모든 액티비티를 제거하는 플래그이다. 예를 들어 A-B-C-D 이렇게 네개의 액티비티가 스택에 쌓여있을 경우 B를 호출하게 되면 B위에 쌓여있던 C, D는 제거 되고 A와 B만 남게된다.
Intent intent = new Intent(D.this, B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
스택에 쌓인 모든 액티비티 제거
B -> C -> D 후 E로 이동했을 때 뒤에 진행된 B-C-D 액티비티를 제거하고 싶을 경우가 있을 수 있다. 하지만 E로 이동하기 전까진 B-C-D를 제거하면 안된다면 어떻게 해야할까? 이동할 때마다 finish()를 호출해주게 된다면 E로 이동하기전에 뒤에 쌓인 스택들이 모두 제거되기 때문에 다른 방법을 사용해야한다.
회원가입 하는 기능을 개발한다고 생각해보자 B-C-D는 회원가입을 위한 사용자정보, 동의정보를 수집하기 위한 액티비티이고 이를 마치면 E라는 화면으로 이동한다. 이때 B에서 회원의 배송지를 입력하고 C로 넘어왔는데 배송지를 잘못 입력해서 뒤로 넘어가야 하는 상황인데 만약 액티비티를 이동할 때마다 finish()를 호출해줬다면 C로 넘어왔을 때 이미 B는 스택에서 제거됐기 때문에 정보 수정을 할 수가 없게 된다. 하지만 회원가입을 마치고 E로 넘어왔을 때는 B-C-D는 스택에서 제거되야 한다. 그렇지 않을 경우 회원가입 완료 화면으로 넘어왔는데 뒤로가기를 눌렀더니 다시 회원가입을 진행했던 화면으로 넘어가기 때문이다.
여기서 목적은 E로 넘어왔을 때 스택에 쌓여있는 B-C-D를 제거하고 뒤로가기를 눌렀을 때 회원가입 페이지(B-C-D)가 아닌 처음 시작했던 메인페이지(A)로 넘어가게 하는 것이다. 즉, A와 E 사이에 있는 B-C-D를 제거하는것이 목적이다.
방법은 간단하다. 제거할 액티비티를 리스트에 담아서 한번에 제거하면 된다.
일단 BaseActivity인 A에 B-C-D 액티비티들을 담을 ArrayList를 static으로 생성한다. 그리고 여기에 다른 액티비티를 담을 수 있게 해당 인스턴스를 반환하는 메소드를 만들어준다.
//회원가입 완료 후 도중에 스택에 쌓인 액티비티들 중 제거할 액티비티 리스트
public static ArrayList<Activity> actList = new ArrayList<Activity>();
//제거할 액티비티에서 리스트에 저장하기 위한 인스턴스 반환 메소드
public ArrayList<Activity> actList(){
return actList;
}
그리고 B-C-D 액티비티 onCreate() 안에서 리스트 인스턴스를 호출해서 각 액티비티를 저장해준다.(B-C-D 모두 동일하게 저장한다.)
//B액티비티
@Override
protected void onCreate(Bundle savedInstanceState) {
A a = new A();
a.actList().add(this); //스택에서 제거할 액티비티를 리스트에 저장
}
그렇게 리스트에 제거할 액티비티를 다 담아줬으면 이제 E에서 For문을 돌려서 제거하면 된다.
//E액티비티
A a = new A();
//지금까지 ArrayList에 저장한 액티비티 전부를 for문을 돌려서 finish한다.
for(int i=0; i<a.actList().size(); i++;){
a.actList().get(i).finish();
}
참고
안드로이드 Intent Flag 정리
안드로이드 Intent Flag 정리
velog.io
안드로이드 finish() 함수의 용도
A라는 화면에서 B라는 화면으로 이동을 하면 안드로이드는 내부적으로 하기와 같은 작업을 합니다. 즉, 위와 같이 화면이 스택이라는 곳에 쌓이게 됩니다. A 화면이 없어지는 게 아니라, B 화면
soo0100.tistory.com
[Android] 스택에 쌓인 액티비티 모두 종료하기
예를들어 A, B, C Activity가 있다고 칩시다. A에서 B로 갈 때 finish()를 하지 않고 갑니다. 즉, Intent intent = new Intent(A.this, B.class); startActivity(intent); startActivity(intent); 만 이용해서..
neoroid.tistory.com
'Android' 카테고리의 다른 글
[안드로이드] 안드로이드 파이어베이스 연동시 토큰 검증 에러 (0) | 2021.11.04 |
---|