정상에서 IT를 외치다

[AndroidManifest] singleTask, noHistroy, parentActivityName 에 대해서 본문

안드로이드

[AndroidManifest] singleTask, noHistroy, parentActivityName 에 대해서

Black-Jin 2018. 6. 1. 14:11
반응형

안녕하세요! 블랙진입니다.


안드로이드 매니페스트 에서 launchMode 를 설정에 따른 화면 Task 관리 대해 공부한 걸 적어보고자 합니다.




1. SingleTask 를 사용해서 중간에 띄어져 있는 화면을 모두 지우고 해당 화면을 재사용 하자



  




 화면은 왼쪽과 같이 A ~ D Activity 로 구성되어 있고 모든 화면의 XML은 아래과 동일합니다.









Main, A~D Activity 의 모습





실험 1


A_Activity 만 launchMode 에 singleTask 를 설정했습니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tistory.blackjin0427.mytaskaffinity">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".MainActivity">

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

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

</activity>

<activity android:name=".A_Activity"
android:launchMode="singleTask"/>

<activity android:name=".B_Activity"/>

<activity android:name=".C_Activity"/>

<activity android:name=".D_Activity"/>

</application>

</manifest>


Main -> A -> A -> A


처음 A 화면만 onCreate 가 되고 그 뒤부터는 onNewIntent 로 시작합니다.


이렇게 SingleTask 일 때는 한개의 화면만 생성되게 됩니다.


Main -> A  이렇게 2개만 스택에 존재하게 됩니다.






Main -> A -> B -> C -> D -> A


B, C, D Activity는 onDestroy 가 되고 A Activity 는 onNewIntent 로 받아옵니다.


Main -> A  이렇게 2개만 스택에 존재하게 됩니다.






실험 2


A_Activity 와 B_Activity launchMode 에 singleTask 를 설정했습니다.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tistory.blackjin0427.mytaskaffinity">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".MainActivity">

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

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

</activity>

<activity android:name=".A_Activity"
android:launchMode="singleTask"/>

<activity android:name=".B_Activity"
android:launchMode="singleTask"/>

<activity android:name=".C_Activity"/>

<activity android:name=".D_Activity"/>

</application>

</manifest>



Main -> A -> B -> C -> D -> A


B, C, D Activity는 onDestroy 가 되고 A Activity 는 onNewIntent 로 재사용됩니다.


Main -> A  이렇게 2개만 스택에 존재하게 됩니다.







Main -> A -> C -> D -> B -> C -> D -> B


B 사이에 있는 파랑색 C, D 는 onDestroy 가 되고 B 화면은 onNewIntent 로 재사용 됩니다..


Main -> A  -> C -> D -> B 이렇게 4개만 스택에 존재하게 되고 중간에 파랑 C, D 는 없어집니다.







Main -> A -> C -> D -> B -> C -> -> B -> A


A 중간에 있는 C, D, B, C, D, B Activity는 onDestroy 가 되고 마지막 A Activity 는 onNewIntent 로 재사용됩니다.


Main -> A  이렇게 2개만 스택에 존재하게 됩니다.






결론!!


SingleTask 화면이 스택에 있고 그 위에 다른 화면들이 있어도 SingleTask 로 설정된 화면을 재호출하면 그 중간에 있던 모든 화면들은 onDestroy 가 되고


해당 SingleTask 화면은 onNewIntent 로 재사용 됩니다.


여기서 singleTask 는 startActivityForResult 사용할 수 없습니다. 사용시 모두 RESULT_CANCELED 가 반환되니 참고 하시기 바랍니다.







2. noHistory 를 사용해서 스택에 화면이 저장되지 않게 하자


<activity android:name=".A_Activity" 
android:noHistory="true"/>

AndroidManifest 에서 위와 같이 사용 하시거나



val intent = Intent(this, A_Activity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NO_HISTORY
startActivity(intent)

위와 같이 FLAG 를 사용하여 스택에 저장되지 않는 화면을 호출 할 수 있습니다.


A activity 에 noHistory 를 설정해두면


Main -> C -> A -> B


로 이동하면 스택에는


Main -> C -> B 이렇게 남게 됩니다. 


즉 A 위에 다른 화면이 덮이거나 백그라운드로 이동하게 되면 A 화면은 onDestroy 가 되는 겁니다.







3. parentActivityName 를 사용해서 뒤로가기 시 parantActivity 가 나오게 하자


이번에는 Manifest 를 아래와 같이 구성하였습니다.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tistory.blackjin0427.mytaskaffinity">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".MainActivity">

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

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

</activity>

<activity android:name=".A_Activity"/>

<activity android:name=".B_Activity"
android:label="child_activity"
android:parentActivityName=".C_Activity">

<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".C_Activity" />

</activity>

<activity android:name=".C_Activity"/>

<activity android:name=".D_Activity"/>

</application>

</manifest>


B 는 C 의 child 가 되고 


C 는 B 의 Parent 가 되도록 설정했습니다.


이렇게 설정 하면 B 화면을 띄우고 뒤로가기에


override fun onBackPressed() {
NavUtils.navigateUpFromSameTask(this)
}

를 설정하면 Parent Activity 인 C 가 나오게 됩니다.


( 참고로 C_Activity 를 한 번 실행 되 있어야 합니다.)




Main -> A -> B 


이렇게 C 화면이 없을 경우 뒤로가기 시 A 화면으로 넘어가게 됩니다.


Main -> A  이렇게 2개만 스택에 존재하게 됩니다.





Main -> A -> C -> D -> B 


이렇게 C 화면을 한번 실행 했으면 B 화면에서 뒤로가기 C 가 위치한 화면 기준으로 

해당 C 화면과, D 가 onDestroy 되고 C 화면을 새로 호출하게 됩니다.


Main -> A -> C  이렇게 3개만 스택에 존재하게 됩니다.




Main -> A -> C -> D -> D -> B 


이렇게 C 화면을 한번 실행 했으면 B 화면에서 뒤로가기 C 가 위치한 화면 기준으로 

해당 C 화면과, D, D 가 onDestroy 되고 C 화면을 새로 호출하게 됩니다.


Main -> A -> C  이렇게 3개만 스택에 존재하게 됩니다.




Main -> A -> C -> D -> D -> C -> D -> D -> B


이런식으로 화면을 구성하게 되면 B 화면에서 뒤로 가기 시


파랑 C, D, D 화면에 onDestroy 되고 C 화면이 새로 호출됩니다.


Main -> A -> C  -> D -> D -> C 이렇게 5개만 스택에 존재하게 됩니다.


여기서 맨 앞에 C 를 지우고 다시 B 를 호출시키면 아래와 같고 


Main -> A -> -> D -> D -> B


B 에서 뒤로가기 시


초록 C, D, D 가 지워지고 새로운 C 가 호출되면서


Main -> A -> C  이렇게 3개만 스택에 존재하게 됩니다.




이렇게 부모 Activity 인 C 를 호출 시키고 자식 Activity 인 B 가 나중에 호출 되었을 경우


C 와 B 중간에 있던 Activity 는 모두 제거되고 새로운 부모 Activity 인 C 가 호출 되는 모습을 확인해 보았습니다.


이것 또한 singleTask 와 매우 비슷한 모습이지만 singleTask 는 재사용 된다는 점에서 큰 차이가 있는것 같습니다.





참고자료


- 블로그


엑티비티 스택에 관하여

테스크란?


- 공식 안드로이드 문서


작업 및 백 스택

앱 매니페스트

반응형
Comments