|
슈퍼드로이드 카페의 안드로이드 강좌가 책으로 나왔습니다.
도서명 : 이것이 안드로이드다.
도서링크 : http://www.yes24.com//24/goods/13950202
================================================================================================
Activity를 활성화하는 함수는 아래와 같이 존재한다.
ⓐ public void startActivity (Intent intent)
ⓑ public void startActivityForResult (Intent intent, int requestCode)
Activity를 활성화 할때 우리는 활성화 되는 Activity에게 Intent를 이용해서
원하는 데이터를 전달할 수 있었다.
아래와 같이 전달되는 데이터는 Intent를 이용하는 것이다.
테스트 코드로 이해해 보자.
패키지 구성은 아래와 같다.
AndroidManifest.xml은 아래와 같다.
즉 2가지 Activity를 등록하고
A Activity가 B Activity를 호출할 것이다.
아래는 A acitivty에 대한 소스이다.
1번에서 활성화할 B Class정보를 Intent에 넣는다.
2번에서는 B Activity로 전달할 데이터를 Extra에 넣는다.
전달한 데이터는 String형으로 "superdroid"라는 것을 기억하자.
Intent에 들어가는 항목들은 Intent 강좌에서 아주 아주 아주 상세히 설명하였다.
생각이 안나면 꼭 돌아가서 다시 복습하자. (Intent에 대해서 모르면 Android 공부를 할 수 없다.)
아래는 B acitivty에 대한 소스이다.
1번에서 A가 전달할 Intent를 getIntent()라는 함수로 참조하게 된다.
2번에서 A가 Intent Extra로 전달한 String을 저장한다.
3번에서 전달 받은 String을 화면으로 출력하기 위해
TextView에 받은 String을 출력한다.
아래와 같이 실행하면
A에서 전달한 String이 Intent에 담겨져 2번과 같이 TextView로 출력되었다.
이전에 Task에 대해서 공부하였다.
Task에 대해서 공부하던중 Activity Stack의 정보를 볼 수 있었을 것이다.
Activity Stack에 정보를 보면 아래와 같이
B Activity가 Intent를 전달 받은 내용이 간략히 보여 준다.
(has extras) 라고 쓰여 있는 것은 위에서 Intent에 Extra 정보를 넣었기 때문에
Extra가 포함되어 있다는 의미이다.
차후 디버깅할때 필요한 경우가 있으므로 그때 그때 기억해 두자.
본 테스트 패키지는 아래를 참조하자.
위에서 startActivity() 함수를 이용하였다.
startActivityForResult() 함수로 바꿔 테스트를 해 보아도 같은 결과를 얻을 것이다.
그렇다면 startActivityForResult() 는 특별히 startActivity()와 같은데 왜 존재할까?
물론 중요한 기능이 한가지 더 있다.
위에서 특정 Activity를 활성화 하면서 전달하고자 하는 데이터도 전달이 가능하였다.
그렇다면 그 반대인 경우도 가능할까?
그 반대의 경우가 바로 startActivityForResult() 함수의 역활이다.
그 반대? 그것이 무엇인지 아래의 그림을 잠시 보자.
1번은 위에서 처럼 A에서 B로 Intent를 통해 Data를 전달하였다.
반대란 2번과 같이 B가 종료될때 A로 복귀되는데 이때 B에서 A로 특정 데이터를 전달하는 것을 말한다.
위와 같이 결과를 받는 것이 필요한 경우가 많다.
예를 들어 메시지를 전송하는 패키지라고 하자.
A는 메시지 목록을 보여 주고, B는 메시지를 전송한다고 하자.
A에서 B를 호출하여 메시지를 전송한다.
B에서 메시지를 성공적으로 전송한다면 A에서 전송된 메시지를 리스트로 표현해야 한다.
이 경우 B에서 메시지를 성공적으로 발송했다는 데이터를 A로 리턴하고
A는 성공적으로 메시지를 받았다는 데이터를 받고 메시지 리스트를 갱신하는 것이다.
자 이를 위해서는 아래와 같은 구현이 필요하다.
1과 같이 startActivity() 함수가 아니라 startActivityForResult() 함수를 사용해야 결과를 리턴 받을 수 있다.
2번 과 같이 A에 대한 데이터를 받기 위해서는 getIntent() 함수를 이용한다.
3번에서는 B에 대한 처리를 완료하고 그 결과를 리턴하기 위해서는
setResult() 함수를 이용해서 전달할 데이터를 저장하고 꼭 finish()함수로 Activity를 종료하여야 한다.
( finish()함수에서 전달할 데이터를 설정하는 코드가 존재함으로 꼭 finish()함수를 사용해야 한다.
단 이전키를 누르는 등의 동작으로 액티비티를 종료하는 경우 내부적으로 finish 함수를 호출하기 때문에
굳이 finish 함수를 호출할 필요는 없다. 여기서 말하고자 하는 것은 finish 함수가 호출되기전에
setResult 함수를 먼저 호출해라는 것이다.)
4번에서 B로 부터 전달 받은 데이터는 A에서 받기 위해 onActivityResult()함수를 overriding해야 한다.
시스템에서는 B로부터 전달받은 데이터를 A에서 구현된 onActivityResult() overriding 콜백함수를
호출함으로써 데이타가 인자로 전달한다.
자 그렇다면 위의 과정을 테스트 패키지를 통해 이해해 보자.
AndroidManifest.xml 에 패키지에서 사용될
Activity 두가지를 등록하였다.
A Activity의 구현내용이다.
해당 Activity에서는 아래의
1번과 같이 활성화할 B Activity의 class명과 전달할
데이터 myName이라는 Key 값으로 "superdroid"라는 문자열을 Intent에 담았다.
2번에서 Intent를 전달하였다.
차후 B Activity에서는 전달한 "superdroid"값이 정상적으로 전달되었는지 확인할 것이다.
3번은 B Acitivty의 결과를 전달받기위해 onActivityResult() 함수를 overriding하였다.
B Activity의 구현 부이다.
1번에서 A로 부터 전달받은 Intent를 얻어 왔고
2번에서 Intent Extra로 전달한 myName Key에 해당하는 값이 전달되었는지
TextView 출력할 것이다.
3번에서는 A Activity로 전달한 데이터 resultText Key 값의 "superdroid result" 문자열을
Extra로 Intent에 담았다.
4번에서 결과로 전달할 Intent를 설정하고 finish()함수를 통해
B Activity를 종료시킴과 동시에 결과로 Intent를 전달하였다.
아래와 같은 과정으로 실행해 보자.
1번에서 B를 활성화 하면서 전달한 문자열이 2번에서 정상적으로 출력이 되었다.
다시 3번과 같이 B에서 결과값을 전달할 문자열이 4번 A Activity로 전달되면서 화면에
출력된 것을 알 수 있다.
함수를 정리하자면 아래와 같다.
자세히 살펴 보면 이해가 금방 될 것이다.
일단 1번에서 전달할 Data를 설정하였고, B Activity에 전달할 요청 코드를 설정하였다.
2번에서 전달한 Data를 수신하였고 그에 대한 처리를 할 것이다.
3번에서 A Activity에 전달할 결과를 결과 코드와 함께 Data(intent)를 전달한다.
그 결과는 4번 A Activity에 onActivityResult() 가 호출되면서 인자로 전달 된다.
여기서 결과 코드를 보면 RESULT_OK 이다.
만일 성공적인 결과를 전달하는 경우 우리는 RESULT_OK 코드로 전달한다.
framework에서는 3가지 코드가 존재한다.
- RESULT_OK = 0
- RESULT_CANCELED = -1
- RESULT_FIRST_USER = 1
대충보아도 알 수 있을 것이다.
하지만 해당 코드는 중요하지 않다.
두 Activity 사이의 전달 코드는 서로 아는 정수로 재 정의하여 사용해도 무관하기 때문이다.
여기서 요청 코드가 왜 필요한지 궁금하지 않는가?
만일 궁금해 했다면 훌륭하다.
분명 A Activity에서 전달한 코드를
A Activity에서 결과를 받는 onActivityResult()의 인자로 다시 받는 것 밖에 없다.
같은 코드를 다시 받는데 왜 필요할까?
그 이유는
A Acitivity는 꼭 B Activity의 결과만 받지 않기 때문이다.
예를 들어 A Activity는 어떤 패키지의 C Activity의 결과도 받을 수 있고,
D,E...등등 다른 Activity의 결과도 받을 수 있다.
그러나 A Activity의 결과를 받은 함수는 onActivityResult() 함수 하나 밖에 없다.
각기 다른 Activity에서 결과를 받은 것을 구분하기 위해서는
당연히 요청 코드가 꼭 필요한 것이다.
본 테스트 패키지 소스는 아래에서 제공한다. 참조하자.
startActivityForResultTest.zip
다음은 Intent의 Flag 중 Activity간에 데이터를 전달하는
추가 기능이 존재한다.
Flag 명은 FLAG_ACTIVITY_FORWARD_RESULT 이다.
무엇인지 아래의 그림을 보고 이해해 보자.
일반적으로 Activty의 결과를 받을때는 Activity를 활성화 하는 측과
활성화되는 측 간의 결과를 전달했었다.
즉 그림에서 A-2가 A-1에게 결과를 전달했었다.
그렇다면 A-2가 결과 Intent를 작성하고 setResult()와 finish()를 통해
A-1 Activity로 전달한다.
모든 결과 데이터의 작성은 A-2가 있는 것이다.
하지만 A-2의 책임을 다른 Activity로 넘기는 방법이 있다.
위와 같이 A-2의 책임을 다른 Activity로 넘기기 위해서
A-3를 활성화 하고 Intent Flag로 FLAG_ACTIVITY_FORWARD_RESULT 를 설정하면 된다.
A-2는 해당 Flag를 셋팅하고 자신의 할일이 끝났으므로 finish()를 호출하여 종료해 버리면
책임은 끝난다.
그러므로 A-3가 전달할 Intent를 작성하고 setResult()와 finish()를 호출해 주면 된다.
아래의 테스트 패키지로 정확히 확인해 보자.
아래 패키지는 A -> B -> C 순으로 Activity를 활성하고
C가 종료되면서 A로 결과가 전달되는지 확인하는 패키지이다.
A Activity는 우리가 이전에 배운 방법으로
startActivityForResult() 함수로 B Activity를 활성화 하고
그 결과를 전달 받기 위해 아래의 2번과 같이 onActivityResult() 함수를 overriding해 주었다.
그 결과는 3번과 같이 Toast로 출력하였다.
(Toast는 배우지 않았다. 하지만 아래와 같이 작성해 주면 팝업으로 결과를 출력해 주는 것만
잠시 외우자... 다음에 배울 것이므로 따라 써 주기만 해 주시길)
B Activity느 아래와 같이
1번에서 C Activity를 활성화하고 책임을 넘기기 위한
FLAG_ACTIVITY_FORWARD_RESULT Flag만 셋팅해 준다.
2번에서 B Activity의 할일은 끝났으므로 바로 종료한다.
C Activity는 B의 책임을 넘겨 받았다.
그러므로 1번과 같이 전달할 Intent를 작성하고
setResult()함수를 통해 Intent를 설정하였다.
그후 2번과 같이 종료를 통해 A 로 결과 Intent를 전달한다.
!!! 전달할 데이터는 returnText라는 Key 값으로 "superdroid" 문자열임을 기억하자.
자 아래와 같이 테스트를 해 보자.
3번에서 C가 결과를 전달한 것이 A에서 Toast로
"superdroid" 문자열이 출력된 것을 알 수 있다.
본 테스트 코드는 아래를 참조하자.
startActivityForResultTest.zip
자 여기까지가 아주 일반적인 이야기만 한 것이다.
여기서 예외상황/제약사항들은 없을까?
있다. 꼭 알고 있어야 하는 사항들이다.
첫번째 : Activity의 결과를 설정하는 setResult()와 finish()는
아래와 같이 Activity의 종료되는 과정의 생명주기에 사용될 수 있을까?
위와 같이 종료되는 생명주기에 해당 소스를 넣으면
Activity가 종료될때 무조건 호출되니 편할 것도 같다.
하지만 절대 허용하지 않는다.
아래와 같이 위의 패키지를 약간 수정해서 알아보자.
B Activity에서 생명주기 종료의 한 부분인 onPause()에 넣어 보았다.
아래와 결과를 보자.
4번과 같이 전혀 전달 받지 못했다. 왜일까?
아래의 Framework소스를 보면 쉽게 이해가 된다.
위의 Framework 소스에 setResult() 함수의 구현부를 보면,
setResult()함수를 통해서만 전달될 데이터가 설정이 되고,
설정된 전달 결과는
3번과 같이 finish()함수를 통해서만 4번과 같이 저장된뒤,
5번에서 finishActivity()함수를 통해 인자로 전달이 되는 것이다.
즉, 꼭 finish() 함수를 사용해야 결과가 전달되며,
종료 생명주기에서는 이미 finish()를 사용해도 무시한다.
그러므로 생명주기에서 해당 코드를 사용해서는 안되고,
특정 이벤트(종료 버튼 click)등에서 사용하도록 하자.
두번째 : Intent로 전달하는 데이터 크기는 제한이 없을까?
전에 한번 설명한 적이 있다.
Intent는 내부적으로 Binder통신을 한다고 하였다.
(차후 Service Component에서 설명하니 그냥 IPC 통신을 하고 Binder라는 것을 이용한다는 것만 알아두자.)
이렇게 Binder통신은 메모리가 제한적이다.
Binder 통신이 가능한 사이즈는 아래의 Framework 소스에 정의 되어 있다.
즉 1M 가까이 밖에 쓸 수없다.
하지만 안드로이드에서는 100KB 이상을 사용하지 않도록 공고한다.
꼭 100KB이내에서 사용해야하는 것은 아니지만
어쨌는 1M 보다 전달할 수 있는 공간이 작으므로,
신경을 써야된다.
쉽게 생각하여, 일반적인 자료형은 전달하되...
절대 Raw 데이터를 전달하지 않도록 한다.
Raw 데이터라고 함은 Image데이터, 동영상 데이터, 아주 긴 Text 데이터 등을 들 수 있겠다.
이런 데이터는 직접 전달하지 않고
보통 저장된 경로를 전달하는 간접 전달 방식으로 처리해야 한다.
(차후 이런 경우 4대 Component 중 Content Provider의 URI를 전달한다.
Intent에서 Data 항목이 URI Class라고 배웠고 그 것이 바로 간접 데이터 전달 방식이다.)
세번째 : 모든 경우 Activity의 결과를 전달 받을 수 있을까?
이를 이해하기 위해서는 이전에 배웠던 Task에 대해서의 지식이 필요하다.
위와 같이 하나의 Task 내에서 결과 전달은 모두 가능하다.
하지만 아래와 같이 다른 Task에서 결과 전달은 불가능 하다.
A-1 Activity에서 A-2 Activity를 활성화 하였지만 결과 A-2의 결과를 A-1에서는 받지 못한다.
즉 결과 전달은 하나의 Task 내에서만 가능하기 때문이다.
다시 기술적으로 말하자면 Root Acitivty는 결과를 전달할 수 없다.
그렇다면 위와 같이 하게 되면 어떻게 될까?
아래는 Task에서 배웠던 launchMode="singleInstance" 속성을 통해 Task를 분리해서 테스트를 하였다.
(Task를 분리하는 방법은 이전에 많이 배웠다. singleTask... FLAG_ACTIVITY_NEW_TASK... 등)
이해를 위해 B Activity의 결과를 1번과 같이
전달받은 A Activity onActivityResult() 함수에서
로그를 출력하도록 해 보자. (그 이유는 아래를 보면 알 수 있다.)
위의 수정사항을 아래와 같이 실행해 보자.
위를 보면 알 수 있듯이
A에서 B를 호출함과 동시에
2번 로그에 벌써 onActivityResult()함수가 호출되어 버렸다.
즉 Task가 분리되는 B는 그 결과를 받을 수 없으므로
바로 결과를 리턴해 버리는 것이다.
이 사항을 모르면 많이 당황하게 된다.
이런 실수를 범하는 사람들은 아주 많이 보았다.
우리는 그러지 말자. ^^
정리하자면 아래와 같다.
마지막으로 네번째 : 최초 전달 받은 Intent가 변경되는 경우는 없는가?
조금 어려운 말일수 있다.
이 말을 이해하려면 Task에서 배웠던 Activity 재사용에 대해서 이해하여야 한다.
- launchMode = "singleInstance"
- launchMode = "singleTask"
- launchMode = "singleTop" or FALG_ACTIVITY_SINGLE_TOP
위와 같이 설정된 경우 Activity를 재사용하게 될 수 있다고 했었다.
기억하는가? 기억이 나지 않는다면 launchMode = "singleInstance" 항목이라도
다시한번 보고 오길 바란다.
테스트 패키지로 이해해 보자.
일단 바로 위에 테스트 패키지를 이용할 것이다.
바로 위의 패키지는 launchMode = "singleInstance"로 설정하여 B Activity를 실행하였다.
아래의 그림을 보자.
launchMode가 singleInstance인 경우 위의 그림처럼 B는 새로운 Task에
올라가게 된다.(모두 아는 사실이길...)
그렇다면 아래의 그림을 보자.
5번과 같이 B Activity를 다른 패키지에서 다시 활성화하는 경우이다.
B가 launchMode가 singleInstance인 경우 다시 활성화 하는 경우 B가 종료되지 않는한
재 사용 된다고 했던 사실을 기억하는가?
이 경우 5번과 같이 새로운 Intent를 전달 받게 될 것이다.
B가 1번을 통해 받았던 Intent가 있을 것이고,
B가 5번을 통해 다시 새로운 Intent를 받게 된다.
이 것이 지금 설명하고자 하는 부분이다.
기존에 1번에서 B는 Intent에 포함된 extra에 String 형으로 "superdroid" 문자열을 받고
화면에 출력하였다.
그런데 5번에서 새로운 Intent를 받고 "superdroid2"라는 문자열을 받게 된다.
이 경우 B는 변경된 Intent 안에 "superdroid2"라는 문자열을 화면에 출력할 수 있을까?
일단 Activity가 재사용되는 경우는 아래와 같은 생명주기를 가진다.
위의 사항을 기억하고 간단히 위의 패키지를 수정하고 그 결과를 확인해 보자.
자 AndroidManifest.xml을 아래와 같이 수정하자.
1번은 차후 B Activity가 다른 패키지에서 활성화 되어야 함으로
외부에 B Activity를 공개하였다.
2번은 aunchMode = "singleInstance"로 설정하였다.
아래는 B Activity를 수정한 내용이다.
해당 B Activity의 상세한 생명주기를 보기 위해 로그를 추가 하였다.
아래와 같이 실행해 보자.
1번과 2번과정까지 B의 생명주기를 확인할 수 있었다.
어쨌든 B가 Foreground 상태가 아니므로 B Activity 상태는 onStop() 상태이다.
자 다른 패키지에서 B를 활성화 하기 위해 아래의 패키지를 작성해 보자.
AndroidManifest.xml 내용은 수정사항이 없다.
CallB Activity에서 B Acitivty를 활성화하기 위해 코드를 추가한다.
1번 과정은 새로운 Intent에 Extra 값으로 "superdroid2"라는 문자열을 넣었다는 것을 기억하자.
자 아래의 과정을 진행해 보자.
3,4과정을 통해 다시 B를 활성화 하였다.
로그를 보면 B가 새롭게 시작하는 것이 아니라 onRestart() 부터 재사용되는 것을 알 수 있다.
하지만 5번을 보면 새로 전달한 Intent Extra 문자열인 "superdroid2"가 B에 출력되지 않고
이전에 Intent 내용인 "superdroid"가 출력되었다.
물론 당연한 결과이다.
아래 B Activity 소스를 기억해 보라.
onCreate()함수에서 화면에 Intent로 받은 문자열을 TextView에 출력하지 않았는가!
당연히 Activity가 재사용되면 아래의 함수만 호출이 된다.
2번(onRestart) -> 3번(on Start) -> 4번(onResume)
그렇다면 아래와 같이 소스를 수정하여
- on Start()에 해당 코드를 넣어 두면 출력이 될까? B Activity에 소스를 추가해 보자.
아래에서 결과를 확인해 보자.
하지만 결과는 출력되지 않았다.
분명 on Start()는 호출되었다.
왜 그럴까?
그것은 우리가 모르는 것이 하나 있기 때문이다.
Activity가 최초 활성화 될때 받은 Intent는
다시 재사용되어도 없어지지 않는다는 것이다.
다시 말하자면 새로운 Intent 와서 아무리 getIntent()를 해도 최초에 받은 Intent 만 유지 된다는 것이다.
엥 그렇다면 재사용시 전달되는 새로운 Intent는 참조할 방법이 없을까?
아니다 방법이 존재한다.
아래는 B Activity의 수정내용이다.
onNewIntent()라는 함수를 Overriding하면 가능하다.
onNewIntent() 함수는 이와 같이 새로운 Intent가 전달되면 호출된다.
다시 말하면 해당 Activity가 재사용되어 활성화 되면 호출된다는 것이다.
새로운 Intent정보는 onNewIntent()함수의 인자로 전달됨을 기억하자.
정말 그러한지 아래를 보자.
정상적으로 변경되었다.
2번의 로그를 보면 해당 B Activity가 재사용 될때
onRestart() -> on Start() -> onResume() 함수가 순서대로 생명주기에서 호출된다.
onNewIntent() 함수는 생명주기 함수가 호출되기전 제일먼저 호출 됨으로써
여러가지 예외처리를 할 수 있도록 한다.
보통 onNewIntent()의 구현은 아래와 같이 많이 사용된다.
getIntent()를 하면 최초 받은 Intent 정보를 리턴 받는다고 하였다.
하지만 새로운 Intent를 setIntent()함수의 인자로 전달하면,
다음에 getIntent() 함수로 Intent를 참조하면 새로운 Intent 정보를 얻을 수 있다.
추가로 전에 singleTask 설명하면서 아래의 Flag를 기억하는가?
시스템에서 FLAG_ACTIVITY_BROUGHT_TO_FRONT를 셋팅하는 경우가 있다고 했다.
즉 뒤에 있던 Activity가 시스템에 의해 강제로 앞으로(Front) 올때 시스템에서
바로 이 Intent Flag를 셋팅한다. 기억 나는가?
모르면 다시 singleTask를 보라.
어쨌든 FLAG_ACTIVITY_BROUGHT_TO_FRONT는 바로 onNewIntent() 함수 내에서 활용된다.
생각해 보라!
"뒤에 있던 Activity가 시스템에 의해 앞으로 온다."
뒤에 있었다는 말은 존재했던 Activity이라는 것이고
앞으로 온다는 말은 재 사용되었다는 말이 아닌가?
재 사용되었다는 것은 꼭 onNewIntent()가 호출 된다는 것이기 때문이다.
이 Flag는 많이 사용되지는 않겠지만 기억해 두면 나쁠것이 없을 것이다.
그렇지만 오히려 어렵고 복잡하게 느껴지면 차라리 잊어라... ^^
자 이정도면 Activity 활성화와 Activity 간에 데이터 전달에 대해서는
충분한 수준이라고 생각한다.
수고하셨습니다. 그럼 다음 강좌도 열심히 ^^/ 고고
!!! 위의 주제에 해당하는 적당한 예를 댓글로 남겨 주세요. ^^
활용 방안의 예는 다른 개발자들에게 많은 도움이 됩니다.
!!! 카페의 활성화를 위해 추천 버튼을 눌러 주세요.
|
첫댓글 정말.. 나중에 책으로 내셔도 좋을 것 같습니다 ^^
열심히 봐 주시는 분이 있다는게 힘이 됩니다. ^^
정말 최강(최고의 강의)입니다.. ( -_-)=b
과찬이십니다. ^^ 대단히 감사합니다.
정말 많이 배우고있습니다.
감사합니다. 보다 좋은 강좌로 답하겠습니다. ^^
좋은 내용 감사합니다.
감사드립니다. ^^
꼭 책으로 내셔야 할 듯 감동 받고 있습니다.
T-T 감사합니다. 보다 좋은 정보로 답해드리겠습니다.
여러번 읽어 봅니다.
강좌 보다 더 쉽게 책을 쓰기 위해 노력하고 있습니다. T-T
집필중인 책이 어느정도 완성이 되면 강좌도
갱신하도록 하겠습니다.
감사합니다. ^^
앞으로 계속해서 안드로이드를 사용할 것 같은데 책 집필 완성되고 출간되면 꼭 구입해서 보겠습니다!
감사합니다. ^^ 최선을 다해 좋은 책 만들어 보겠습니다.
예외사항 3번째에서 Task가 분리되는 B는 그 결과를 받을 수 없으므로 바로 결과를 리턴해 버린다고 하셨는데 그럼 onActivityResult 함수의 호출은 누가 하는 것인가요? 문맥으로 보면 B Activity인것 같은데 어느 부분에서 어떤 식으로 onActivityResult를 호출하는지 애매합니다...
안녕하세요.
앗 약간의 오해를 하신것 같습니다.
onActivityResult는 B 액티비티가 호출해주는 것이 아니라
시스템이 호출해줍니다. (ActivityManagerService)
생명주기 함수들과 같이요.
수고하세요.
강의 보는 중간에 댓글답니다. 이미지 제작에 정말 많은 정성을 들이셨네요!
startActivityForResultTest.zip 에 addFlags하는 부분이 없네요~
setResult, onActivityResult에 대해서 이보다 더 잘 설명할 수 있을까 감탄하면서 강좌를 닫습니다!
적절한 예가 있으면 올려드릴게요!
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance">
이렇게 설정하면
MainActivity에서 인텐트로 활성화할 대상액티비티가 onCreate되기전에
D/MainActivity? onActivityResult() called 이 호출되네요
그래서 대상액티비티에서 보낼 결과값을 받을 수 없군요
사례 1: 특정 앱을 실행하는 NDEF 레코드를 작성하는 페이지가 있고
그페이지에 앱선택 버튼이 있어서 그 버튼을 누르면 리스트뷰에 앱목록을 뿌려주고 리스트뷰의 한 아이템을 클릭하면 해당 패키지명을 setResult로 설정해서 "앱선택 버튼이 있는 페이지"로 받아오려고 했는데
NFC에 기록하려면 태그를한 번 휴대폰에 대야하잖아요 그렇게 되면 새로운 인텐트를 받는 상황이 되기때문에
onNewIntent에서 처리를 해줘야해요 그래서 액티비티의 launchmode를 singleinstance로 줬거든요 그랬더니 패키지명을 못받아왔었죠.