본문 바로가기
오늘은 뭘 배울까?/Android

addToBackStack에 대한 고찰

by Kim Juhwan 2021. 10. 6.

1. Fragment
   1-1. 개념
   1-2. remove

   1-3. replace
   1-4. 문제 발생
2. addToBackStack
   2-1. 개념
   2-2. 사용법

3. 고민
   3-1. addToBackStack은 꼭 필요한 함수일까?
   3-2. fragment를 매번 새로 생성하는 게 옳은가?

4. 결론

 

 

 


 

 

이 글을 검색해서 찾아온 사람이 있다면 아마...

뒤로 가기를 눌렀을 때 이전에 실행했던 프래그먼트로 이동하고 싶거나

뒤로 가기를 눌렀을 때 이전에 실행했던 프래그먼트를 거치지 않고 바로 액티비티로 돌아가고 싶어서 일 것이다.

이 글을 정독하고 나면 개념과 해결 방법을 얻어갈 수 있을 것이다.

 

1. Fragment

1-1. 개념

addToBackStack에 대한 이야기를 하기 전에 먼저 Fragment에 대해서 간략하게 설명을 해야 할 것 같다.

Fragment는 Activity에 내가 원하는 화면을 쌓아 올린다라고 생각하면 된다.

 

 

액티비티간의 화면 전환

 

Activity위에 Activity를 쌓아 올리는 것은 불가능하기 때문에 이렇게 서로를 대체하는 것(화면 전환)만 가능했지만

 

 

액티비티위에 Fragment를 겹치게 놓기

 

Activity위에 Fragment를 쌓아 올리는 것이 가능하다. 포토샵의 레이어와 같다고 생각하면 된다.

 

Fragment에 대해서 자세히 설명하자면 끝도 없기 때문에
설명에 필요한 개념만 짧게 설명하였다.

 

1-2. remove

Fragment를 하나 빼는 과정

 

Transaction의 remove 함수를 사용하면 가장 최상위에 있는 Fragment를 제거할 수 있다.

addToBackStack은 설명 안하고 왜 이상한 걸 설명하고 있나 싶겠지만 일단 계속 들어보십셔

 

1-3. replace

Fragment를 replace하는 과정

 

Transaction의 replace 함수를 사용하면 기존에 쌓여있던 Fragment들을 다 제거하고 해당 Fragment를 추가한다.

 

1-4. 문제 발생

자, 이제 문제

만약 내가 겹쳐둔 Fragment에서 맨 위에꺼 하나만 지워버리고 싶다면 어떻게 해야 할까?

맞다. [목차 1-2]에서 설명한 remove 함수를 사용하면 된다.

 

자, 다시 문제

만약 뒤로 가기를 눌렀을 때 맨 위에꺼 하나만 지워버리고 싶다면 어떻게 해야 할까?

뒤로 가기를 감지하는 onBackPressed에서 remove를 사용하면 정말 정말 좋겠으나...

 

Activity에서 검색(좌), Fragment에서 검색(우)

 

문제는 onBackPressed가 액티비티에는 있지만 Fragment에는 없다는 것이다.

그렇다면 이를 어떻게 해결할 수 있을까?

콜백을 사용하든 어떻게 하든 무슨 방법을 동원하면 해결할 수 있을 것 같긴 하다.

하지만 이런 경우에 사용하라고 구글이 만들어놓은 함수가 있다.

그것이 바로 addToBackStack이다.

 

2. addToBackStack

2-1. 개념

백스택에 들어가있는 Fragment들

 

[목차 1-3]에서 replace를 하면 기존의 Fragment들은 버려진다고 했었다.

하지만 addToBackStack를 사용하면 Fragment를 버리지 않고 BackStack에 차곡차곡 모아둔다.

이때 BackStack안에 들어가 있는 Fragment들은 Pause 상태로 유지된다.

즉, 기존에 replace만 사용했을 때는 Fragment가 Destory 되었지만 BackStack에 들어가면 Pause 상태에서 멈춘다.

 

그리고 뒤로 가기 버튼을 누르면 담아두었던 Fragment를 다시 꺼내와 화면에 보여준다.

이것이 바로 addToBackStack이 하는 역할이다.

 

2-2. 사용법

        supportFragmentManager.beginTransaction()
            .replace(R.id.frame_layout_main, MainFragment())
            .addBackStack(null) // replace 다음에 적어준다.
            .commit()

사용법이라고 할 것도 없는 게, 그냥 replace 다음에 addBackStack 함수를 사용해주면 된다.

인터넷에 검색하면 인자 값으로 전부 null을 주던데 이게 무슨 뜻일까 싶어 공식문서를 찾아봤다.

 

타입은 String형이며 BackStack 상태를 나타내는 이름을 주던가 아니면 null을 넣으라고 한다.

그니까 이게, 이 포스팅에서는 설명 안 할 거지만 stack에 들어가는 fragment에 각자 이름을 지정해줄 수 있고

그 이름을 통해 무언가 또 다른 작업을 할 수 있는 듯하다. 그 작업들에 대해서는 여기를 참고하자.

 

아무튼 그래서 이름을 지정해주고 싶으면 지정하고 그게 아니면 null값을 줘라 이 뜻이다.

 

3. 고민

3-1. addToBackStack은 꼭 필요한 함수일까?

구글 플레이 앱에서 탭을 이동하고 뒤로가기를 눌러보았다.

 

구글에서 만든 앱은 어떤 방식을 적용하고 있는지 궁금해서 찾아보았다.

구글 플레이에 들어가서 탭을 여러 번 바꿔보고 뒤로 가기를 누르니 바로 홈 화면으로 나가지는 것을 확인할 수 있었다.

 

구글은 자기들이 생각하는 앱의 표준 디자인이나 구성 같은 것들이 있다.

그리고 그걸 구글 관련 앱을 만들 때 엄격하게 적용한다고 나는 개인적으로 그렇게 느꼈다.

그렇다면 구글은 addToBackStack을 사용하지 않는 쪽으로 권장을 하는 걸까?

 

공식문서 내용 中 ...

 

"사용자가 뒤로 이동하여 변경을 '실행 취소'하도록 허용하는 것이 적절한 경우가 많습니다."

...

...

나는 왜 이렇게 한글이 어려울까?

어떻게 하는 게 맞다는 거야..?

번역기를 돌린 말투라 애매해서 영어로 된 공식문서를 읽어보려 했지만

이유는 모르겠으나 현재 저 페이지는 한글로만 남아있고 언어 설정을 영어로 바꾸면 내용이 다른 페이지로 연결된다.

죄송하지만 판단은 글을 읽으시는 여러분들께...

 

addToBackStack에 대해 언급되어 있는 한글 공식문서 링크

 

3-2. fragment를 매번 생성하는 게 옳은가?

버려진 fragment들 :(

 

[목차 1-3]에서 말했듯이 replace를 하면 기존에 액티비티에 쌓여있던 fragment들은 지워진다.

Destory 된다는 것이다.

그리고 다시 그 fragment를 띄우기 위해서는 create를 해야 한다.

 

이런 생각이 문득 들었다.

fragment를 띄울 때마다(= 화면 전환을 할 때마다) 내용의 갱신이 필요한 경우

예를 들어 실시간으로 정보가 슉슉 바뀌는 게시물은 매번 fragment를 죽였다가 살렸다가 하는 작업이 유의미하다고 생각했다.

 

근데 만약 실시간으로 내용이 바뀌지도 않고, 어딘가로부터 통신받아 데이터를 보여주는 것도 아니라면

매번 굳이 fragment를 죽였다 살렸다 해야 할 필요가 있을까??

항상 똑같은 화면만을 보여주는 fragment가 있다면 addToBackStack처럼 fragment를 중지시켜놨다가 재활용 하는 게 바람직 하지 않을까?

 

이런저런 고민을 하다가 발견한 방법이 있다.

이 블로그 글을 읽고 알게 됐는데 FragmentTransaction에 show, hide 함수가 있다는 걸 알게 됐다.

사용할 fragment를 전부 add 해두었다가 보여주고 싶은 fragment만 show를 하고 나머지는 hide 하는 것이다.

그렇다면 이 hide & show를 사용하는 게 가장 최선인 걸까?

글쎄.. 그건 모르겠다. 속 시원하게 답변을 듣고 싶은데 공식문서에도 외국 문서에도 답을 찾을 수 없었다.

 

4. 결론

어쩌면 내가 쓸데없는 고민을 한 걸지도 모른다.

요즘 스마트폰이 얼마나 빠르고 인터넷이 얼마나 빠른데 fragment 다시 만든다고 리소스를 많이 잡아먹는 것도 아니고...

뒤로 가기 눌렀을 때 이동하는 화면이야 앱마다 특성이 다르니 상황에 맞게 써주면 될 것이고...

 

글을 읽어주신 여러분들은 그냥 이런 쓸데없는 고민을 하는 애도 있구나 하고

add, replace, addToBackStack에 대한 정보만 얻어가 주시면 될 것 같습니다.

 

 


💡 느낀 점

  • 난 그래도 아직까지 뒤로 가기로 프래그먼트를 이동하는 건 반대하는 입장이다. 탭으로도 이동할 수 있고 스와이프로도 이동할 수 있는데 뒤로 가기까지...? 지원을 해야 하나...?
  • 구글 애널리틱스를 통해서 뒤로 가기를 통해 이전 프래그먼트로 돌아가려는 사용자의 비율을 조사하면 해답을 얻을 수 있지 않을까...
  • 아냥이 앱 만들 때 addToBackStack 때문에 엄청 고생했었는데 드디어 제대로 조사 좀 해봤다.
  • 함수 하나를 파고들어 조사하는 것도 재밌는 것 같다. 
  • 나는 그림을 매우 못 그리는 구나를 느낌. 😂

📘 참고한 자료


 

반응형

댓글