티스토리 뷰

지식쌓기

Android - Tasks and Back Stack (2)

바나나쥬스 2012. 9. 25. 20:44

Android - Tasks and Back Stack (1) 에 이어 그다음 내용부터 

http://developer.android.com/guide/components/tasks-and-back-stack.html#ManagingTasks


역시나 내맘대로 정리 보는사람 음스므로 음슴체 


<Managing Tasks>


- 이전에 설명했던 android의 task, back stack관리는 대부분의 app에 잘 동작함

- 개발자가 activity들이 back stack에 어떻게 존재하는지 task랑 어떤 연관을 가지고 동작하는지 같은 것에 대해 고민하지 않아도 됨

- 그래도 개발자는 이런 기본적인 동작을 하고 싶지 않을수도 있음 

- 한 activity를 현재 task에 속하게 하지 않고 새로운 task로 시작하게 하고 싶거나

- 이미 생성되어 있는 activity의 instance를 그대로 사용하면서 맨 위로 올리고 싶거나

- task를 떠날때 back stack에서 clear시키고 싶을수 있음

- 이러한 것을 manifest 파일의 <activity> 에서 정의해 줄수 있음


* <activity>에 정의해주는 속성 

- taskAffinity

- launchMode

- allowTaskReparenting

- clearTaskOnLaunch

- alwaysRetainTaskState

- finishOnTaskLaunch


* intent의 flag로 설정해 주는거 (startActivity() 할때)

- FLAG_ACTIVITY_NEW_TASK

- FLAG_ACTIVITY_CLEAR_TOP

- FLAG_ACTIVITY_SINGLE_TOP


<Using the manifest file>

- <activity> 의 속성으로 넣어주는거 하나씩 보겠음

* launchMode

- standard 

   - default임, 앞에서 계속 설명한거와 같은 동작, 새 instance생성해서 task의 top으로 올림

- singleTop 

   - activity가 이미 task의 top에 있으면 새 instance를 생성하지 않고 그 activity의 onNewIntent()를 호출함 

   - top에 없으면 새 instance 생성하여 task의 top으로 올림

   - 예를들면

   - A-B-C-D (D가 top에 있음) 인 task가 있음

   - activity D를 실행하라는 intent가 들어옴

   - activity D의 launchMode가 standard인 경우 activity D의 새 instance를 생성함 따라서 A-B-C-D-D가됨

   - activity D의 launchMode가 singleTop인 경우 activity D는 stack의 top에 있으므로 top에 있는 activity D의 onNewIntent()를 호출함

   - 그래서 stack은 그대로 A-B-C-D 가됨

   - 그런데 activity B를 실행하는 intent가 들어오는 경우

   - activity B의 launchMode가 singleTop 으로 설정되어 있어도 activity B의 새 instance가 생성되고 stack에 추가됨

   - 그래서 stack은 A-B-C-D-B 가됨

- singleTask

   - 시스템은 새 task를 만들고 새로 생성된 activity를 root로 둠 (근데 밑에 그림 보면 root가 아님.. 설명을 위해서인가?)

   - 그런데 다른 task에 activity의 instance가 있으면 새로 instance를 만들지 않고 그 activity의 onNewIntent()를 호출함

   - 그리고 그 activity가 있는 task를 foreground로 가져옴

   - 결국 activity는 instance 1개만 있음

- singleInstance

   - task에 오직 하나의 activity만 가짐

   - 다른 activity들을 task에 두지 않음

   - 그외 singleTask랑 같음


- 밑에 그림으로 singleTask 더 살펴봄

   Figure 4 설명 .

   - Activity Y 가 singleTask로 설정되어있음 

   - Activity 2 가 activity Y를 실행시킴 

   - Activity Y 가 singleTask이므로 이미 있는 activity Y가 속해 있는 task가 foreground로 올라오고 activity Y의 onNewIntent()가 호출됨

     (Activity Y 가 다른 task에없었으면 새로 다른 task에 생성되서 들어가게됨) 


  * (번외) 근데 여기서 activity 2가 activity X를 실행시키면 어떻게 될까??? 

   - activity X는 top이 아닌데 말이쥐

   - 사실 singleTask로 되어있는 activity는 task의 root가 되니까 위 그림과 같이 될수 없는데...어?

   - 직접해볼라니 좀 귀찮아서 일단 구글링 

   - http://stackoverflow.com/questions/6268646/android-question-about-singletask-mode?answertab=active#tab-top 

   - 위 링크에 답변한 사람 dbalaouras 아저씨의 이론대로 설명하면

   - activity X 가 불리면 activity Y는 destroy되고 activity X 가 top으로 옴

   - 위 그림으로 보면 세번째 상태로 바로 간다는 거임 - 그럴거 같음

   - 언젠가 테스트해보겠음.. 귀찮지만...


- 다시 본론으로 

- launchMode 속성은 intent flag값에 의해 overrided 될수 있음 (무시될수 있음)

 * 이부분 테스트해서 정리좀 해야할듯.. 

launchMode설정상태에서 flags넣어 실행하는거 case별로.. 언젠가 -ㅅ-


<Using Intent Flags>

- activity 실행할때 넘겨주는 Intent에 flags를 줄수있음

- FLAG_ACTIVITY_NEW_TASK

   - singleTask와 같음

   - 귀찮지만 다시 설명하면

   - 새로운 task로 activity를 실행시킴

   - 어딘가 activity가 있으면 그 task가 foreground로 나오고 기존의 activity의 onNewIntent()가 호출됨

- FLAG_ACTIVITY_SINGLE_TOP

   - singleTop과 같음

   - activity가 top에 있을 경우만 그 activity의 onNewIntent()가 호출됨, top에 없으면 새로 만듬

- FLAG_ACTIVITY_CLEAR_TOP

   - 실행하려는 activity가 현재 task(current task)에 있으면 새 instance를 생성하지 않고 그 activity위에 있는 activity들을 다 destroy 시키고 실행하려는 activity를 top으로 가져오고 onNewIntent()를 호출함


  *(번외) 그럼 다른 task에 있으면 다르나???? 왜 current task라고 적혀있는거지????? 

   - 이건잠시 보류


   - FLAG_ACTIVITY_CLEAR_TOP flag는 주로 FLAG_ACTIVITY_NEW_TASK랑 같이 쓰임

   - 그러면 기존의 다른 task에 있는 activity를 새 task에 가져올수 있게됨 (이거 해석 다시 해봐야겠다능)

   - 이 플래그로 실행하려는 activity의 launchMode가 standard이면 그 activity도 stack에서 지워지고 새 instance가 생성되어 stack에 들어감

   - 왜냐면 standard는 항상 새로 만들어야 옵션이니까


<Handling affinities>

- affinity는 activity가 어느 task에 속하게 할지 정해줌

- 기본적으로 같은 app의 모든 activity들은 각각의 affinity를 가질수 있음

- 기본적으로 같은 app의 모든 activity들은 같은 task에 속하게됨

- 근데 이 정보를 고칠수 있음

- 다른 app에 있는 activity들이 affinity 를 공유할수 있음

- 그리고 같은 app에 있는 activity들이라도 서로 다른 task에 속할 수 있음

- <activity> 의 taskAffinity 속성값에 정의해줌 
- affinity 동작의 두가지 경우

   * FLAG_ACTIVITY_NEW_TASK flag가 있는 intent로 activity가 실행되는 경우 

      - 기본적으로 새로 생성되는 activity는 startActivity()를 호출한 activity가 속한 task에 속하게 됨

      - 근데 FLAG_ACTIVITY_NEW_TASK flag가 있는 intent로 실행되면 시스템은 새 task에 activity를 포함시킴 (앞에 FLAG_ACTIVITY_NEW_TASK 설명한 그대로임) 

      - 근데 affinity가 정의되어 있으면 같은 affinity를 가진 task를 찾아서 그 task로 들어가게됨 

   * activity가 allowTaskReparenting=true 로 설정되어 있는경우 

      - activity는 시작된 task에서 같은 affinity를 가진 task로 옮겨감

      - 예를들어

      - 여행 app에서 지정된 지역의 날씨를 보여주는 activity가 있는경우 (이 activity에 allowTaskReparenting=true설정)

      - 기본적으로 날씨 activity는 여행 app에 있는 다른 activity들과 같은 affinity를 가짐

      - 여행 app이 아닌 다른 app의 activity에서 날씨 activity를 실행한경우 날씨 activity는 실행시킨 activity의 task에 가게됨

      - 그런데 여행 app이 foreground로 나오면 날씨 activity는 다시 affinty가 같은 여행 app의 task로 돌아감


<Clearing the back stack>

- 사용자가 장시간 task를 떠나 있으면 시스템은 root activity를 제외하고 task의 activity들을 clear시킴

- 사용자가 다시 task로 돌아오면 root activity만 남아있음

- 이러는 이유는 사용자가 오랜 시간이 지난후 돌아왔다는것은 전에 뭘하고 있었는지는 관계없이 다시 새로운 것을 시작하기 위해 온것이기때문

- alwaysRetainTaskState

   - root activity에 true로 설정되어 있으면 task의 오랜 시간지나도 모든 activity를 유지함 

- clearTaskOnLaunch

   - root activity에 true로 설정되어 있으면 사용자가 task를 떠나고 돌아올때마다 task를 clear시킴

   - alwaysRetainTaskState의 반대가됨

   - 사용자가 task에 돌아올때는 항상 초기 상태가 됨

- finishOnTaskLaunch

   - clearTaskOnLaunch 이랑 비슷한데 이건 task 전체에 해당하는게 아니라 하나의 activity에만 해당됨

   - root activity뿐만아니라 어떤 activity이든 사라질수 있게 되는거임

   - true로 설정되어 있으면 activity는 현재 session만을 위해 task에 있게 되는거임 

   - 사용자가 task를 떠났다가 돌아오면 없다능 

 

<Starting a task>

- activity의 intent-filter에 아래와 같이 적어주면 task의 entry point로 설정할수 있음

<activity ... >
    <intent-filter ... >
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    ...
</activity>

- 위와 같은 intent-filter는 activity 런처에 아이콘과 label로 표현됨

- 사용자는  activity 런처를 통해서 task를 떠나고 task로 돌아오고 할수 있어야 함

- 앞에서 배운 activity launchMode중에 singleTask, singleInstance는 처음 새 task에서 시작됨

- 그래서 이 두 launchMode는 activity가 ACTION_MAIN, CATEGORY_LAUNCHER filter를 가졌을때만 사용해야 함

- 이 filter가 없는 activity A 를 singleTask로 실행시키면 일단 singleTask이므로 새 task로 실행됨

- 그리고 사용자가 홈 버튼을 누름

- activity A가 있는 task는 background로 감 

- 근데 더이상 activity A가 있는 task를 가져올 방법이 없음, 런처가 없으니까

(번외) 근데 이건 activity가 어떻게 런치되는가에 따르니까.. 런처 말고는 실행할 방법이 없는 activity에만 해당된다고 생각

- 사용자가 다시는 activity A 에 돌아오지 못하고 하고 싶은경우에는 finishOnTaskLaunch를 true로 설정하면됨


------------------------------------------------------------------

음 근데 최근엔 recent menu도 있고 한데..

거기에 대한 언급은 하나도 없네 어?

너무 이 기술문서만 믿어도 안될듯 하는 주관적인 내생각 ㅋ