본문 바로가기

안드로이드/[Kotlin]

[Kotlin] registerForActivityResult() 사용법 (Feat. startActivityForResult 의 deprecated)

https://sukzoon1234.tistory.com/34

 

[Kotlin] Activity 전환 & 데이터 전달 (Intent, putExtra...)

우선 시작하기 전 안드로이드의 4대 구성요소에 대해 알아보자. - 1. Activity 사용자에게 보여주는 UI 화면을 구성하는 컴포넌트이다. (웹의 HTML 같은 느낌) Activity 클래스를 상속받아 사용한다. 하

sukzoon1234.tistory.com

이 글에서 Activity 끼리 데이터를 주고받는 intent의 간단한 예제를 만들어 봤었다.

지금 하고있는 FLO 클론코딩에서도 Activity 끼리 왔다갔다(?) 하면서 쌍방향으로 데이터를 주고 받아야 하는 경우가 생겼다. 그런데 단순하게 StartActivity(intent) 로 계속해서 Activity 호출을 반복하다가 보면 액티비티 스택에 계속해서 액티비티가 쌓이는 문제가 생긴다.

 

 

왼쪽은 MainActivity 이고, 오른쪽은 SongActivity 이다.

Main에서 Song을 실행하면 데이터 전달과 동시에 Main화면 위에 Song이  실행되고, 뒤로가기 버튼을 누르면 데이터 전달과 함게 Song이 종료되면서 다시 Main 화면이 나오는 그런 방식을 원했다. 

 

그런데 여기에다가 단순히 StartActivity(intent) 로 서로 데이터를 주고 받으면 어떻게 될까? Song에서 Main으로 돌아갈때마다 매번 MainActivity 가 생성이 되므로 액티비티 스택에 계속 축적되게 된다. 

 

 

그렇다면 SongActivity가 종료될 때 매번 MainActivity를 호출하는 것이 아닌, 그냥 보내고자 하는 데이터만 상위 Activity(MainActivity) 로 보낼 수는 없을까?

 

 

구글링을 해보니 startActivityForResult() 라는 메소드가 있었는데 이미 2020년 5월에 deprecated 되었다고 한다....ㅠㅜㅜ

 

 


 

그래서 요론 녀석을 찾았다. 내 프로젝트에 적용시킬 수 있을 거 같아서 공부를 해 보았다.

https://developer.android.com/training/basics/intents/result

 

활동에서 결과 가져오기  |  Android 개발자  |  Android Developers

활동에서 결과 가져오기 개발자 앱 내의 활동이든 다른 앱의 활동이든 다른 활동을 시작하는 것이 단방향 작업일 필요는 없습니다. 다른 활동을 시작하고 다시 결과를 받을 수도 있습니다. 예를

developer.android.com

 

우선 현재 Activity 에서 registerForActivityResult() 를 통해서 콜백을 등록해야 한다. 

그리고 람다 식에는 SongActivity로 받아온 result 라는 객체값을 어떻게 사용할 것인지 정의하면 된다. 

result 객체를 통해서 결과 코드(resultCode)와 데이터(intent) 에 접근할 수 있다.

++result.data 라는 코드로 intent에 접근 가능하다.

 

그리고 launch() 함수를 통해서 Sub 액티비티(SongActivity)를 실행시키면 된다.

//  MainActivity.kt

private lateinit var getResult : ActivityResultLauncher<Intent>

override fun onCreate(savedInstanceState : Bundle?) {
	super.onCreate(savedInstanceState)
        ...

	getResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if(result.resultCode == RESULT_OK) {
//          Log.d("check", "Hi: ${result.data?.getStringExtra("title")}")

            setPlayer(result.data!!) 
            //SongActivity 로 부터 받은 데이터(intent) 를 이용해서 결과값을 수행하는 함수 호출
        }
    }
    
    binding.mainPlayerLayout.setOnClickListener {
        val song = Song(binding.mainMiniplayerTitleTv.text.toString(), binding.mainMiniplayerSingerTv.text.toString(), checkIsPlaying(binding.mainBtnMiniplayerPlayIv))
        val intent = Intent(this, SongActivity::class.java)
        intent.putExtra("title", song.title)
        intent.putExtra("singer", song.singer)
        intent.putExtra("isPlaying", song.isPlaying)
        
        getResult.launch(intent)
        //SongActivity 실행과 동시에 데이터(intent 전달)
    }
}

 

SongActivity 에서는 우리가 흔히 아는 intent 방식으로 받아온 데이터를 처리할 수 있고, 

setResult() 함수를 통해서 MainActivity 로 데이터를 보내줄 수 있다.

// SongActivity.kt

override fun onCreate(savedInstanceState : Bundle?) {
	super.onCreate(savedInstanceState)
        ...
    initSongActivity() //MainActivity 로 부터 받아온 데이터를 처리해주는 함수 호출
}


private fun initSongActivity() {
        if(intent.hasExtra("title") && intent.hasExtra("singer") && intent.hasExtra("isPlaying")) {
//            Log.d("checking", ": ${intent.getStringExtra("title")}")
            val title = intent.getStringExtra("title")
            val singer = intent.getStringExtra("singer")
            val isPlaying = intent.getBooleanExtra("isPlaying", false)
            binding.playerTitleTv.text = title
            binding.playerSingerTv.text = singer
            setIsPlaying(isPlaying)

        }
    }


override fun onBackPressed() {
    val song = Song(binding.playerTitleTv.text.toString(), binding.playerSingerTv.text.toString(), checkIsPlaying(binding.playerBtnPlayIv))
    val intent = Intent(this, MainActivity::class.java)
    intent.putExtra("title", song.title)
    intent.putExtra("singer", song.singer)
    intent.putExtra("isPlaying", song.isPlaying)
    
    setResult(RESULT_OK, intent)
    //데이터(intent) 를 인자로 가지는 함수. MainActivity로 데이터를 보내준다.
    finish()
}

 

 

 

 

참고 :

https://junyoung-developer.tistory.com/151?category=960204 

https://velog.io/@galaxy/registerForActivityResult-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

https://developer88.tistory.com/351