이번엔 큰맘먹고 글하나 써볼라합니다. 주제는 제목에 있구요...
완전히 실행되는 수준으로 코드를 달지는 않겠지만 핵심은 모두 설명하겠습니다.
1. Notification 쓰면 Activity가 맨날 새로 떠요...
저도 이거땜시 죽는줄 알았습니다. 스레드 하나가 MainActivity 생명주기에 종속되서 새로 떴을때 다 꼬였거든요...
정말 검색해서 (실제로 주제와 딱 맞는것을 검색하는데는 실패...) 나오는 파라미터들을 이리저리 조합해도
원하는 결과는 얻지 못했습니다.
2. 그러다 문득 생각난 SMS...
Notification을 잴 많이 쓰는 기본어플은 누가 뭐래도 SMS겠죠....
그래서 냅다 풀소스에서 죽어라 찾았습니다.
거기서 특이한넘 발견....
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
써봤더니... 결과는
3. 오... 지정한 액티비티가 찾아서 뜬다...
말그대로 찾아서 뜹니다... 근데 여기서 암초가 하나 있었으니...
4. 근데 root activity는 새로 뜬다.
task 설명한곳들을 찾아보면 activity의 stack이고.... 거기에 가장 아래에 있는 넘을 root activity라고 하더군요
근데 문제는 Notification으로 root activity를 띄우면 제가 원하는 동작을 제대로 수행하지 못하고 여러개 띄운다는겁니다.
액티비티 속성에 singleTask 달면 하나만 띄우긴 하는데 다른데서 또 사고가 납니다....
Noti 로 실행하고 다시 홈가서 런처를 이용한 실행이라던가... 등등등....
여기서 꼼수가 등장합니다.
5. root activity를 더미로 하나 두자....
애초에 root activity가 두개 뜨는게 문제라믄... 그 activity를 root로 안하믄 되지... 라는 생각으로
root를 더미로 하나 만들고 그 위에 쭉 올렸습니다.
그랬더니 두둥.....
정말 원하는 대로 하나씩 뜹니다.... 어떤상황이라도 말이죠...
저두 이것때메 고민 많이 했는데 대책이 없는걸루 알았댔는데 이건 정말 사막에서 만난 샘과 같군요.
그냥가자님.. 앞으루 복많이 받으실거에요.
왜냐면 태스크 관리 정책때문에... SingleInstance로 하면 다른것에 붙는걸 허용하지 않으니까요...
테스트를 얼마나 해보셧는지 모르겠군요...
액티비티야 그냥 뜨니까... 아 되나보네 하지만...
테스트케이스 적어가면서 세밀하게 해보면 새로운 task가 실행되는 부분이 생깁니다.
그냥 가자 님이 디자인을 어떻게 하고 어떤 문제를 겪었는지 저는 자세히 모를 수 있습니다.
하지만 일반적인 경우라면 singleTask로 중복실행을 대부분 해결할 수 있을거라 봅니다.
singleTask에대한 안드로이드 Reference를 첨부합니다.
(원문) http://developer.android.com/guide/topics/fundamentals.html 에서 발췌
In contrast, the "
singleTask
" and "singleInstance
" modes mark activities that are always at the root of a task. They define a task; they're never launched into another task. In contrast, "singleTask" and "singleInstance" activities are limited to just one instance. Since these activities are at the root of a task, this limitation means that there is never more than a single instance of the task on the device at one time.
(번역문) http://nuninaya.tistory.com/569?srchid=BR1http%3A%2F%2Fnuninaya.tistory.com%2F569 에서 발췌
singleTask및 singleInstance는 task를 정의하여 root activity로 적재되고 다른 task에 적재되지 않는다.
singleTask, singleInstance는 task내에서 오로지 한개의 instance만 적재된다. root activity만 가능하기 때문에 device내에서 한번에 하나의 Instance만 존재할 수 있다.
this limitation means that there is never more than a single instance of the task on the device at one time.
번역이 살짝 틀렸네요...
"이 제한은 한 디바이스에서 동시에 그 태스크에서 하나 보다 많은 인스턴스가 존재할수 없음을 의미한다." 라고 하는데요...
문제는 the task입니다. 당연히 그 태스크에서야 싱글 인스턴스인데...
태스크가 2개 뜨는것에 대한 보장은 어디에도 명시되어있지 않습니다.
즉 task가 여러개 뜨면서 멀티 activity가 실행되는 케이스에 대한 명시가 없는것이고 이는 알아서 회피해야 합니다.
실제 테스트를 해보면 singleTask로 실행해도 멀티플로 뜨는 경우가 생기기도 하구요.
기존 메인 엑티비티를 startActivity로 띄우는 코드만 작성된 것을 루트로 둔다는 것인가요?
그르탐 매니페스트에서 루트 엑티비티(더미)가 띄우는 엑티비티에서 싱글타스크 싱글인스턴스를 속성에 넣어주면
더미는 여러개라도 그노마가 startActivity로 띄우는 애는 하나가 된다는 말씀? 아리송 하네요.
조금 자세히 알고싶습니당 ^^
좋은정보 너무 감사합니다!
더미는 하는일이 크게 2가지입니다.
1. 원하는 엑티비티(A라고 칭하겠습니다.)를 실행한다.
2. A가 종료할때 보내는 브로드캐스트를 받아서 같이 종료한다.
더미나 A엑티비티 모두 SingleInstance나 SingleTask는 쓰지 않았습니다.
일단 그걸 쓰면, 다시 해당 Activity를 부를때 새로운 Task가 뜨는 테스트 케이스가 너무 많았습니다.
SingleInstance는 테스트 안했고.. (일단 컨셉에 안맞아서...)
SingleTask의 경우 기존것이 종료되고 새로뜨던가 아니면 두개가 뜨던가... 이런식이었습니다.
물론 기존것이 종료되고 새로운 것이 실행되서 Instance가 1개일지는 모르겠으나...
태스크에서 꺼내오는것은 아니니까요...
대부분 이 문제로 골치아픈분들은 단순히 액티비티가 2개뜨는 문제보다는
기존것이 종료되면서 나오는 사이드이펙트가 더 클겁니다.
그냥가자님 정말 감사합니다..
저 역시 음악 서비스 중 무한으로 액티비티 뜨는 문제가 있었는데..
pendingintent에 intent를 세팅 하기전,
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
를 넣어주니, 원하는 대로 동작하네요 ^-^
추천하고 갑니다!
노티파이케이션에서 앱을 실행할 시에는 위의 3가지 플래그를 줄 수 있는데 프로그램 목록에서 앱을 실행할
때는 저런 플래그를 줄 수가 없지 않습니까..? 그래서 지금 문제가 되는 케이스는 푸시 메시지를 받아서 노티파이케이션에
뜨고 그 노티를 클릭해서 앱을 실행한 후에 home 키로 나오고 프로그램 목록에서 앱을 선택해서 실행하면
MainActivity가 두개가 생성되네요....어떻게 하면 좋을까요...? ㅠ
안녕하세요.
더미를 만들어서 중복실행을 막을려고하는데 더미에서 Main을 띠울떄 무슨FLAG를 사용하시나요?
더미를 만들어서 햇는데 중복실행이 되고 잇습니다.
음 저도 현재 리시버딴에서 푸시 메세지를 받으면 푸시Activity에 Alert을 띄우고
버튼을 누르면 어플의 특정 Activity를 실행하게 해 두었는데
어플이 중복 실행이 되는군요.
더미에대한 개념을 잘 모르겠는데 혹 힌트좀 부탁드리겠습니다.
여기 많은 분들이 보실꺼 같아서 여기에 글을 추가로 달아보겠습니다.
저 같은 경우 A->B 화면으로 구성되는 어플에서
노티피케이션을 클릭하면 A는 생략하고 B로 명령을 전달하는 기능을 개발중이였습니다.
예를 들면 A는 스플래쉬 화면이고 B는 메인화면 이였습니다.
그런데.. 어떻게 해도 되지 않다가...
정말 위에 써주신 방법 다 안되더라구요..
그러다가 찾아낸게..
혹시 메인이면 신호가 갈까? 라는 생각이 2일만에 떠올랐고 ㅠㅠ
B Activity에
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
이러한 인텐트 필터를 주니까 !! 해결됬씁니다.
우와 ㅠㅠㅠ
정말 감격..스러어ㅜ요 ㅠㅠ
인텐트 필터를 처음엔 DEFAULT로 넣었는데 안되고
Main으로 넣으니 되네요~ 다들 참고하세염 '-'ㅎ