공식문서를 읽고 정리한 글입니다!
한 Activity 또는 Process에서 다른 Activity를 시작하고 그 결과를 받아올 수 있다. 기존에는 Activity 클래스에서 제공하는 startActivityForResult()
, onActivityResult()
API가 있었다.
하지만!
이제는 AndroidX Activity와 Fragment에 도입된 Activity Result API 사용을 적극 권장한다.
Activity Result API는 이를 위해 Callback을 등록하고 실행, 처리하기 위한 구성요소를 제공한다.
결과를 받아 처리할 Callback을 등록해야한다. 다만, 다른 Activity가 실행되는 중 전 Activity가 메모리 문제로 kill될 수 있기 때문에 Callback과 다른 Activity를 launch하는 코드는 분리해야 한다.
Decouple
- result callback
- launching the other activity
분리한 Callback은 registerForActivityResult()
함수를 통해 등록할 수 있다.
ActivityResultContract
: input type과 output type을 정의하며, 필요에 따라 custom 가능하다ActivityResultCallback
: ActivityResultContract
에 정의된 output 객체를 가져오고 onActivityResult()
가 포함된 single method interfaceActivityResultLauncher
: the other activity launch에 사용된다registerForActivityResult()
함수는 Callback 등록만하고 다른 Activity를 launch 하진 않는다. launch 책임은 ActivityResultLauncher
에 있다. launch()
호출 시, result를 얻기위한 process가 시작된다. 그 subsequent activity가 끝나면 ActivityResultCallback
의 onActivityResult()
가 호출된다.
내부구현이 어떻게 되어있길래 이렇게 동작할까?
ComponentActivity 내부에는 ActivityResultRegistry 인스턴스를 갖고있다. 그리고 그 내부에 HashMap을 이용해 Contract와 Callback을 매핑한다. Activity로 돌아오게 되면 onActivityResult()
를 호출하고, 알맞는 callbackAndContract
를 찾아 해당 ActivityResultCallback의 onActivityResult()
를 호출한다.
이런식으로 구현되어있기 때문에, ComponentActivity나 Fragment에서 ActivityResultCaller를 implement해 registerForActivityResult()
하지 않아도! separate class에서 activity의 result를 받아올 수 있다. registerForActivityResult()
가 ActivityResultRegistry 인스턴스에 등록하는 것을 직접 하면 된다.
근데 이런 방식으로 한다면 LifecycleOwner를 가져오는 API를 같이 사용하는 게 좋다.(Lifecycle에 맞게 자동으로 launcher가 삭제되기 때문에) 만약 같이 사용하지 않는다면, 직접 launcher를 unregister()
하는 방법도 있다.
Activity Result API 사용 시 다음 장점이 있다.
크크 저도 얼마전에 공부한 내용이라 반갑네용 😇~