본문 바로가기
안드로이드 코틀린

[Kotlin][Android] StartActivityForResult 대신 RegisterActivityForResult 사용하기

by teamnova 2023. 1. 17.

StartActivityForResult는 안드로이드에서 주요 기능으로 액티비티를 시작하고 결과를 얻어오는데 사용되었지만 deprecated 되고 RegisterActivityForResult로 대체되었습니다.

StartActivityForResult가 더이상 사용되지 않는 이유

  • 특정 요청이 이루어지는 위치를 찾기 어려움 
  • 중복으로 사용된 경우 고유한 요청 코드를 보내야 했습니다. 이는 가끔 버그가 있는 결과를 불러오기도 합니다. 
  • 컴포넌트가 다시 생성되면 결과가 누락됩니다. 
  • onActivityResult 콜백이 프래그먼트와는 잘 작동하지 않습니다. 

RegisterActivityForResult가 더 나은 점 

  • Simple, easy & clean
  • 각 액티비티마다 별도의 callback

RegisterActivityForResult 사용법

 1. launcher를 정의 

lateinit var launcher : ActivityResultLauncher

 2. 정의한 launcher를 등록 

launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
	useTheResult(result)
}

registerForActivityResult()는 반드시 액티비티나 프래그먼트가 create 되기 전에 호출해야 합니다. 

프래그먼트나 액티비티의 생명주기가 created에 가기 전에는  ActivityResultLauncher를 실행할 수는 없습니다.

 

 3. 등록한 launcher를 사용

launcher.launch(Intent(context, ResultActivity::class.java)
	.putExtra(ResultActivity.PARAM_DATA,id))

 

따로 요청코드를 관리할 필요없이 ActivityResultContracts를 상속받아 사용할 수 있는 클래스들도 있는데 아래와 같은 종류들이 있다. 

  • StartActivityForResult
  • RequestPermission
  • TakePicture
  • CaptureVideo
  • OpenDocument

(https://developer.android.com/reference/androidx/activity/result/contract/package-summary 참조)

아래와 같이 커스텀해서 사용할 수도 있다. 

class CustomContract : ActivityResultContract<String, String?>() {
 const val DATA = "data"
 const val INPUT_DATA = "input_data"

    override fun createIntent(context: Context, input: String?): Intent {
        val intent = Intent(context, DummyResultActivity::class.java) 
        intent.putExtra(INPUT_DATA, input)
        return intent
    }

    override fun parseResult(resultCode: Int, intent: Intent?): String? {
        return when (resultCode) {
          //결과를 반환하기 전에 필요한 형식으로 전환
            Activity.RESULT_OK -> intent?.getStringExtra(DATA)
            else -> null
        }
    }
}