CAFE

16. Activity에 대해서 - Task 편(4)

작성자슈퍼성근|작성시간11.05.30|조회수6,092 목록 댓글 19

슈퍼드로이드 카페의 안드로이드 강좌가 책으로 나왔습니다.

도서명 : 이것이 안드로이드다.

도서링크 : http://www.yes24.com//24/goods/13950202

================================================================================================


2.2 Task Activity 정리하기

 

지금까지 새로운 Task를 생성과 관련된 각 속성들에 대해서 살펴 보았다.

이제부터는 생성된 Task 내 각 Activity History 제거와 관련된 속성에 대해 살펴 본다.

 

● AndroidManifest.xml에서 <activity>의 속성들이다.

 

 <activity

    . . .

             android:allowTaskReparenting=["true" | "false"]
             android:alwaysRetainTaskState=["true" | "false"]
             android:clearTaskOnLaunch=["true" | "false"]
             android:finishOnTaskLaunch=["true" | "false"]

             android:finishOnCloseSystemDialogs=["true" | "false"]

             android:noHistory=["true" | "false"]  
             android:taskAffinity="string"
    . . .
 </activity> 

 

 

● Intent에 Flag 값에 존재하는 속성들이다.

    (노랑색 강조 부분만 해당한다.

 정의된 Intent Flag
 FLAG_ACTIVITY_NO_HISTORY
 FLAG_ACTIVITY_CLEAR_TOP

 FLAG_ACTIVITY_REORDER_TO_FRONT

 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

 FLAG_ACTIVITY_BROUGHT_TO_FRONT

 

 

2.2.1 FLAG_ACTIVITY_NO_HISTORY Flag에 대해서

       (== AndroidManifest.xml <activity andoird:noHistory>)

 

본 속성은 Activity Stack 내에 History를 남기지 않겠다는 속성이다.

우리는 특정 Activity의 경우 Backkey 등을 눌렀을때 다시

활성화 되는 것을 원치 않을 때가 있을 것이다.

 

예를 들어

Password 등을 묻는 Activity의 경우

최초 한번만 승인이 되고 그 다음 해당 application을 사용하기 원할 것이다.

하지만 해당 Application을 사용하다가 Back Key를 누르면

이전 Activity로 복원될 것이고 결국 계속 Back Key를 누르다 보면

다시 Password Activity가 보이게 되는 것이다.

이렇게 Password Activity를 다시 활성화 되는 것을 원치 않는다면

해당 속성을 Password Activity에 설정하면 된다.

설정된 Activity는 다시 해당 Activity를 startActivity()하지 않는 이상

나타나지 않는 것이다.

(물론 해당 속성 말고도 다른 방법으로 해당 기능을 수행할 수는 있다. ^^ 예일 뿐이다.)

 

테스트 패키지를 하나 작성해 보자.

아래와 같이 A -> B -> C 순으로 호출되는 패키지 이다.

A -> B -> C 순으로 호출하면 Activity Stack은 아래와 같을 것이다.

 

본 패키지에서 B Activity를 "noHistory" 속성을 줄 것이다.

 

패키지 구성은 아래와 같다.

 

AndroidManifest.xml에 아래와 같이 "noHistory" 속성을 True라고 주었다.

(Default는 "false"임을 기억하라)

 

각각의 A,B,C에 해당하는 Activity 소스 내용이다.

 

자 아래와 같이 실행해 보자.

 

과연 아래와 같이 Activity Stack이 변경되었을까?

 

Activity Stack을 확인해 보자.

이상하게도 B Activity가 그대로 남아 있다.

버그일까? ^^

좀더 자세히 보자.

1,2번을 보면 B Activity의 상태가 "FINISHING"인 것을 알 수 있다.

즉 B Activity는 이미 종료된 것이다. 즉 없는 것이나 마찬가지라는 것이다.

그러므로 C Activity에서 BackKey를 눌러보면 B Activity가 다시 활성화 되지 않고

바로 A Activity가 활성화 될 것이다.

(여기서 한가지 더 알수 있는 것이 있다. 우리는 B -> C 를 활성화 할때,

 분명 B Activity를 finish()함수를 사용해서 종료하지 않았지만 finish가 되었다.

 그 이유는 noHistory속성을 주게 되면 해당 B가 Foreground에서 벗어나 Background가

 되는 즉시 시스템에서 강제로 Finish를 시켜버리는 것이다.)

 

정말 B Activity가 빠진 결과를 보고 싶다면

아래와 같은 순으로 실행해 보자.

다른 점이 있다면 C Activity에서 Home Key를 누른 것이다.

 

Activity Stack를 보면 정말 B Activity가 사라진 것을 알 수 있다.

 

해당 옵션을 정리하자면

위와 같이 A -> B -> C를 활성화 하고 C에서 BackKey을 눌러도 B로 가지 않고

A로 가는 것을 알수 있다.

 

본 속성의 Sample 코드는 아래를 참조하라.

첨부파일 NoHistoryTest.zip

 

참고로 Intent flag "FLAG_ACTIVITY_NO_HISTORY"를 통해 테스트를 해 보 싶다면

아래와 같이 AndroidManifest.xml에서 해당 내용을 제거하고

 

A->B 를 호출할때 noHistory 속성을 주어야 하므로

A Activity에 아래의 Intent Flag를 추가하면 된다.

실행해 보면 결과는 같다.

 

하지만 AndroidManifest.xml을 이용하면 어디에서나 해당 Activity를 활성화할때

적용되지만 Intent Flag속성을 이용하면

매번 startActivity를 할때마다 속성을 넣어 주어야 한다.

서로 장단점이 있으므로 상황에 맞게 사용하길 바란다.

 

 

2.2.2 FLAG_ACTIVITY_CLEAR_TOP Flag에 대해서

 

해당 속성은 Task 내에 존재하는 특정 Activity부터 Top Activity까지 모두 제거한뒤

다시 그 특정 Activity를 활성화 시켜 Top이되도록 한다.

 

아래의 그림으로 이해해 보자.

위와 같이 Task내에 "B"가 존재할때,

"B" 를 "FLAG_ACTIVITY_CLEAR_TOP" Intent Flag 속성을 주어 하나더 추가하는 경우

1,2,3번과 같이 D,C,B Activity가 모두 제거되고,

다시 "B"가 추가되어 Top이 되도록 하는 속성이다.

 

테스트를 위해 아래와 같은 패키지를 하나 만들어 볼 것이다.

 

 본 패키지에서는 C->B를 호출할 경우

아래와 같이

본과정의 속성 "FLAG_ACTIVITY_CLEAR_TOP" 을 추가할 것이다. 

 

패키지 구성은 아래와 같다.

 

AndroidManifest.xml의 구성은 아래와 같다.

 

A Activity와 Layout 구성이다.

A Activity는 B Activity를 활성화 할 것이다.

 

B Activity와 Layout 구성이다.

B Activity는 C Activity를 활성화 할 것이다.

B Activity의 생명 주기를 확인하기 위해 로그를 추가하였다.

 

C Activity와 Layout 구성이다.

C Activity는 다시 B Activity를 활성화 할 것이다.

아래를 보면  "FLAG_ACTIVITY_CLEAR_TOP" 을 추가하였다.

그리고 C Activity의 생명 주기를 확인하기 위해 로그를 추가하였다.

 

일단 아래와 같이 실행해 보고 ,

생명 주기를 확인해 보라.

특히 제일 마지막 "B" Activity가   "FLAG_ACTIVITY_CLEAR_TOP" Intent 속성으로 활성화 될때,

"B"와 "C"가 onDestroy 되고 "B"는 다시 onCreate 되는 것을 알 수 있다.

(생명주기에서 onDestroy가 호출된다는 것은 Task에서 Pop 즉 제거된다는 의미이다.)

 

Activity Stack으로 확인해 보자.

"C"는 사라졌고 "A"와 "B"만 존재하는 것을 알 수 있다.

 

그렇다면 본 Flag는 어떤 경우에 사용될 수 있을까?

 

아래의 그림을 보자.

최초 회원 가입의 절차가 필요한 패키지의 예이다.

"A"에서 회원가입 버튼을 누르고 "B,C,D"의 등록 절차가 거쳐야 한다.

등록 절차를 마치게 되면 다시 로그인 Activity인 "A"로 복귀하고 "B,C,D"는 다시 필요하지 않게 되는 것이다.

 

즉 아래와 같이 "B,C,D"는 Activity Stack에서 사라져야 한다.

 

필요에 따라 아주 유용한 기능이 될 것이다.

 

!!! 하나 더 Tip을 알려 주도록 하겠다.

개인적으로 "FLAG_ACTIVITY_CLEAR_TOP" Intent Flag의 경우

예전에 배웠던 "FLAG_ACTIVITY_SINGLE_TOP" 과 같이 많이 사용되었다.

(해당 Flag는 특정 Top의 Activity를 재사용할 수 있었다.)

왜 그러한지 위의 패키지에서 해당 Flag를 추가해 보자.

아래는 "C" Activity이며, 해당 Activity에서 "B" Activity를 활성화 함으로

이곳에 Flag를 추가한다.

 

자 아래와 같이 실행하고 생명주기를 확인해 보자.

전에는 분명 "B" Activity가 Destory 되었지만,

이제 그렇치 않음을 알 수 있다.

(기존 "B" Activity는 재사용 되었다.)

 

위의 과정을 그림으로 다시 이해해 보자.

 

이렇게  "FLAG_ACTIVITY_SINGLE_TOP" 속성을 통해 재사용되면 무엇이 좋을까?

해당 Activity Instance를 다시 만들지 않으므로 성능의 이득은 당연한 얘기이다.

중요한 것은 재사용 되는 Activity의 Context가 계속 유지 될 것이다.

무슨 얘기일까?

예를 들어 재사용되는 Activity에 EditText View가 하나 있었고

재사용되기 전 EditText View에 "가나다라마..."라는 글을 입력해 두었다고 하자.

다시 해당 Activity로 복귀 재사용하게 되면 기존에 입력해 두었던 "가나다라마..."라는

Context 가 그대로 유지 되는 것이다.

만일 재사용되지 않고 Destory가 되었다면 모든 내용은 사라진다.

이해가 되었는가?

 

본 속성의 관련된 테스트 소스는 아래를 참조하자.

첨부파일 ClearTopTest.zip

 

 

2.2.3 FLAG_ACTIVITY_REORDER_TO_FRONT Flag에 대해서

 

이 Flag를 설명하기 전

개인적으로 굉장히 맘에 안드는 Flag임을 밝힌다.

왜 그러한지를 생각하면서 강좌를 지켜봐 주길 바란다.

 

이 Flag는 Task에 존재하는 특정 Activity를 Top으로 옮길 수 있다.

아래의 그림을 통해 이해해 보자.

이미 Task내 활성화된 "B" Activity를 다시 활성화 할때,

해당 속성을 주게 되면 아래에 실행되었던 "B" Activity가 Stack의 개념을 무시하고

최 상위 Top으로 이동하게 된다.

이동된 "B" Activity는 그대로 재사용 된다.

 

본 Flag의 테스트 패키지를 작성해 보자.

 

아래와 같이 A->B->C->B 순으로 활성화 되는 패키지 이다.

 

마지막 C->B를 호출할 때는 해당 Flag를 줄 것이다.

 

패키지 구성은 아래와 같다.

 

AndroidManifest.xml의 구성을 아래와 같다.

(하도 많이 보았기 때문에 많은 설명을 생략하도록 한다.)

 

A->B를 활성화하는 A Activity의 Layout과 소스 내용이다.

 

B->C를 활성화하는 B Activity의 Layout과 소스 내용이다.

정말 해당 Flag로 재사용되는지 확인하기 위해 생명 주기를 로그로 출력한다.

 

C->B를 활성화하는 C Activity의 Layout과 소스 내용이다.

아래의 설명하고자 하는 Flag를 셋팅하고 있다.

 

자 실행해 보고 생명 주기를 확인해 보자.

"B" Activity는 전혀 onDestroy가 호출되지 않았다.

"B" Activity는 onRestart () ->on Start () -> [안내]태그제한으로등록되지않습니다-onResume ()의 과정으로

재사용됨을 알 수 있다.

 

자 Activity Stack으로 정말 아래에 존재했던 "B" Activity가 Top으로 올라와 있는 지를 확인하자.

A->B->C->B 순으로 Stack에 쌓여야 함에도 불구하고

A->C->B 순으로 순서가 변경되었다.

 

어쨌든 이 Flag가 유용한 경우도 있을 것이다.

하지만 Stack의 구조를 깨 버린다.

이는 많은 혼돈을 줄 수 있다.

아마도 이 Flag로 얻는 이점 보다도 생각치 못한 side effect가 발생할 빈도가 클 것이다.

자리 변경으로 "B"가 top으로 올라왔지만 "B" 뒤에 "A"가 있어야 함에도 불구하고 "C"가 존재한다.

UI의 흐름이 뒤죽박죽이 되지 않을까?

여러분도 생각해 보라. (아마도 Stack이 깊을 수록 혼란스러운 Task 구조가 되어 버릴 것이다.)

 

아래의는 본 Flag의 테스트 코드이다. 참조하자.

첨부파일 ReorderToFrontTest.zip

 




!!! 위의 주제에 해당하는 적당한 예를 댓글로 남겨 주세요. ^^

    활용 방안의 예는 다른 개발자들에게 많은 도움이 됩니다. 


!!! 카페의 활성화를 위해 추천 버튼을 눌러 주세요. 


다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
  • 답댓글 작성자보헤미안 | 작성시간 13.10.21 와~ 감사합니다 ^^
  • 작성자춘춘 | 작성시간 14.01.13 FLAG_ACTIVITY_CLEAR_TOP [로그인]을 통한 설명 너무 좋아요! 감사합니다!
  • 작성자droy | 작성시간 15.06.08 감동적이에요
  • 작성자droy | 작성시간 15.06.08 1,2,3번과 같이 D,C,B Activity사 모두 제거되고, < -- 오타 있는데요
    사소한거지만 알려드려요 그대로 드래그해서 find해서 바꾸면 되겠네요!
  • 답댓글 작성자슈퍼성근 작성자 본인 여부 작성자 | 작성시간 15.06.09 감사합니다. 수정되었습니다.
댓글 전체보기
맨위로

카페 검색

카페 검색어 입력폼