[Android] startActivityForResult() 가 Deprecated 되었다고??

김병수·2021년 6월 3일
0
post-thumbnail

startActivityForResult() 함수가 Deprecated 되었다는 것은 꽤나 오래전에 알게 되었지만, 이번에 팀 프로젝트를 진행하면서 까먹었던 부분도 다시 상기시킬 겸 방법을 공유하고자 한다.

startActivityForResult() ?

안드로이드에서 새로운 액티비티를 띄우고, 그 액티비티가 종료될 때 결과 값을 받아서 어떤 작업을 수행하고자 할 때 사용하던 함수이다. 그런데 androidx에서 부터는 deprecated 되었다.

그렇다면 왜 deprecated 되었나??

확실하지는 않지만... intent로 카메라 앱을 실행하고 그 결과로 촬영한 사진을 받고자 하는 경우, 카메라 앱에서 작업을 수행하는 도중에 메모리 부족으로 프로세스가 종료될 가능성이 있다. 따라서 result callback을 다른 액티비티를 실행하는 코드 상에서 분리하는 방식으로 이러한 문제를 해결한다고 한다.

정확한 이유는 안드로이드 공식 문서를 참고하길 바란다.
https://developer.android.com/training/basics/intents/result

startActivityForResult() 를 대체하는 방법은 크게 2가지 작업으로 나뉜다.

1. Activity Result에 Callback 등록하기

val getContent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
	// Callback 작업 구현
}

새로 실행할 Activity가 종료되었을 때, 수행될 callback 작업을 구현한다.

2. 결과를 위한 Activity 실행하기

val intent: Intent = Intent(context, PopupBuySellActivity::class.java)
getContent.launch(intent)

Intent를 만들어주고, 위에서 만든 getContent로 launch(intent) 해주면 끝!

인줄 알았지만...
예상치 못했던 오류가 발생했다.
Activity를 실행하는 Fragment가 처음 생성되었을 때는 callback 작업이 정상적으로 수행되었지만, Fragment가 Destroy 되었다가 다시 Create 되는 경우에는 callback 작업이 정상적으로 수행되지 않는 현상이 발생한 것인데...
이는 Fragment의 멤버 변수로 선언과 동시에 초기화했기 때문에 발생하는 문제인 것 같다.
그래서 이를 해결하기 위해서 다음과 같은 방법을 사용했다.

해결방법

class FragmentBuy : Fragment() {
    lateinit var getContent: ActivityResultLauncher<Intent>
}

Fragment의 멤버변수로 선언만 해두고,

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        getContent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        
        }
}

onCreateView() 에서 getContent 변수를 초기화해준다.

이렇게 하면 Fragment가 Destroy 된 후에 다시 Create 되어도, getContent는 Fragment가 생성될 때마다 초기화되기 때문에 정상적으로 callback 작업이 수행된다.

참고로 Activity에서 사용하는 경우에는 onCreate() 함수에서 getContent를 초기화해주면 될 것 같다. 물론 getContent를 선언하는 Activity가 Destroy 될 일이 없다면 그럴 필요가 없지만 말이다.

profile
주니어 안드 개발자

0개의 댓글