이번 포스팅에서는 UI/UX 의 주요 Component 인 Activity 와 Fragment 에 대해 작성하고자 한다. (여기서 UI 는 사용자가 상호작용할 수 있는 화면 그 자체(시각적 디자인)를 의미하며, UX 는 화면과 상호작용하는 사용자 입장에서 더 만족스러운 (편리한, 원활한) 상호작용을 제공해주는 것을 의미한다.)
Fragment 가 출시된 정확한 날짜는 잘 모르겠지만, Android 의 UI/UX 를 구현하기 위해 기본적으로 사용된 Component 는 Activity 이다. Activity 는 Android 의 4가지 주요 Component 중 하나인 만큼 UI/UX 측면에서 매우 큰 역할을 차지하고 있다. 하지만 Activity 만으로 UI/UX 를 구현하기에는 몇 가지 한계점이 존재한다.
첫 번째로 Activity 와 View 의 종속성이다. Fragment 없이 UI/UX 를 구현하게 되면 하나의 Activity 는 여러 View 들을 소유하게 되고, 이 View 들은 해당 Activity 에 의존하게 되기 때문에 동일한 재사용이 불가능하다.
두 번째로 Activity 간의 데이터 공유이다. Application 을 실행하면 화면과 화면 사이의 데이터를 공유하게 되는 경우는 불가피하다. 그렇기 때문에 Activity 와 Activity 사이의 데이터 공유가 이루어져야 하는데, Activity 는 각각 자신의 메모리 영역을 가지고 있고 서로 공유를 하지 않기 때문에 같은 메모리 안에서 데이터를 공유하는 것보다 좋지 않은 성능을 제공한다. (이는 화면 전환에서도 마찬가지로 각 Activity 는 자신의 메모리 영역을 차지하고 있어 화면 전환 시 일명 Context Switching 과 같은 overhead 가 발생한다.)
이처럼 Activity 만을 사용해 UI/UX 를 구현하기에는 한계가 있어 Fragment 의 개념이 출시되었다. 그렇다면 Fragment 란 무엇일까?
Fragment 는 화면 일부의 UI 를 정의할 수 있는 Component 로 독립적으로 존재할 수 없고 반드시 host (Activity) 를 필요로 한다. 그렇기 때문에 하나의 Activity (host) 는 여러 개의 Fragment 를 가질 수 있으며, 우리는 Fragment 를 통해 Activity 와 View 의 종속성을 분리할 수 있다. 즉, 비슷한 기능(카테고리) 을 하는 View 들을 하나의 Fragment 로 관리하여 하나의 Component 로 구성할 수 있기 때문에 재사용은 물론이고 관심사 분리를 통해 효율적으로 UI/UX 구현을 할 수 있다. (Tablet 과 같은 큰 화면의 UI/UX 를 효율적으로 (관심사 분리를 통해) 구현하기 위해 Fragment 개념이 생겨났다고 한다.)
사실 필자는 Fragment 를 재사용 할 정도로 큰 project 를 진행해보진 않았지만, 관심사를 분리해 하나의 Activty 를 구성하는 것보다 더 체계적으로 UI/UX 를 구현할 수 있다는 점에 큰 merit 가 있다고 생각했다.
의존성을 분리할 수 있다는 장점 외에도 하나의 host 안에 여러 Fragment 가 존재한다는 것은 Fragment 들은 host 메모리를 공유한다는 뜻이기 때문에 Fragment 간 데이터를 공유할 때에도 좋은 성능을 보이게 된다. (앞서 말했듯이 화면 전환 측면에서도 같은 메모리 내에 전환이 이루어지기 때문에 overhead 가 발생하지 않는다.)
Fragment 도 물론 단점이 존재한다. (해당 내용은 필자가 아직 경험한 바가 없어 확 와닿은 내용은 아니지만, "이런 단점도 있구나~" 라는 정도로만 이해하고 작성한 내용이다.)
host 내에 여러 Fragment 를 관리하기 위해서는 FragmentManager 라는 것이 Transaction 을 통해 관리를 하는데, 이는 비동기로 실행되어 예기치 않은 동작이 발생할 수 있다. 또한 Fragment 도 Activity 처럼 LifeCycle 이 존재하는데, Fragment 의 LifeCycle 까지 고려하게 된다면 Activity 만을 사용했을 때 보다 당연히 더 고민해야할 부분이 많아지게 된다.
지금까지 Fragment 가 출시된 이유를 살펴보면서 Activity 의 역할과 Fragment 의 장/단점에 대해 알아보았고, Activity 와 Fragment 의 LifeCycle 에 대해 알아보기 앞서 Activity 의 Back Stack 에 대해 먼저 알아보자.
Android 는 단일 Activity 로도 존재할 수 있지만, 복잡한 project 의 경우, 여러 개의 Activity 로 구성되고 이는 Back Stack 을 통해 관리되어 진다.
개발자라면 다 알고 있는 Stack 의 개념과 매우 동일하지만 몇 가지 option 에 따라 조금 다르게 동작하기 때문에 해당 option 에 대해 중점적으로 다룰 것이다.
우선 option 은 AndroidManifest 의 LaunchMode 로 관리할 수 있고, Intent Flag 로도 관리할 수 있다.
standard
항상 Activity 를 Stack 에 쌓는다.
singleTop
Activity 실행 시, Stack 최상단의 Activity 가 해당 Activity 와 동일하다면 재사용한다.
singleTask
Activity 가 재사용된다는 점에서 singleTop 과 유사하지만, 최상단 Activity 를 비교하는 것이 아닌 재사용되는 Activity 위에 존재하는 Activitiy 들을 전부 destory 시킨다. (단, taskAffinity 가 다른 경우 새로운 Stack 에 Activity 를 push 한다.)
singleInstance
taskAffinity 와 상관없이 항상 새로운 Stack 에 Activity 를 push 한다.