그냥

액티비티를 호출하고 결과를 받아오기 위해

Deprecated 된 startActivityForResult 대신 ActivityResultLauncher 를 사용할 수 있다.

 


 

startActivityForResult 는 Deprecated 됐는가?

 

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

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

developer.android.com

위 공식문서에서 자세히 살펴볼 수 있는데,

 

결과를 얻기 위해 액티비티를 시작할 때, 메모리 부족으로 인해 프로세스와 액티비티가 소멸될 수 있기 때문이다. (특히, 카메라 사용과 같이 메모리를 많이 사용하는 작업의 경우 소멸 확률이 매우 높음)

 

그렇게 되면, startActivityForResult 를 사용한 경우 onActivityResult CallBack에서 결과를 받아오지 못할 수 있다.

하지만 CallBack 을 사용하는 ActivityResultLauncher 를 반환하는 registerForActivityResult 를 사용할 경우 콜백 메소드 등록을 통해 결과값을 받아올 수 있다.

 

간단하게 요약하면 콜백을 분리하여 항상 콜백을 받을 수 있도록 하는 것이다.

 

 

 

1️⃣ 사용하기

위와 같이 2개의 다른 액티비티로 이동하는 버튼을 만들고

이동한 액티비티에서 보낸 결과를 받아와 출력하는 코드를 작성해보려고 한다.

 

private val activityResultLauncher : ActivityResultLauncher<Intent> = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ){

        // SubOne에서 결과를 받아옴
        if(it.resultCode == ONE){
            val intent = it.data
            val returnValue = intent!!.getStringExtra("one")
            Toast.makeText(this, returnValue.toString(), Toast.LENGTH_SHORT).show()
        }

        // SubTwo에서 결과를 받아옴
        else if(it.resultCode == TWO){
            val intent = it.data
            val returnValue = intent!!.getStringExtra("two")
            Toast.makeText(this, returnValue.toString(), Toast.LENGTH_SHORT).show()
        }
    }

 

registerForActivityResult 를 이용하여 콜백 메소드를 등록해준다.

ActivityResultContracts 를 통해 결과를 생성하는 데 필요한 입력 유형과 결과의 출력 유형을 정의할 수 있다.

 

일반적인 startActivityForResult 와 유사하게 사용하려면 StartActivityForResult 로 지정하면 된다.

콜백메소드만 분리했으므로 결과를 받을 때 사용할 resultCode 만 정의해주면 되고 요청할 때 필요한 requestCode 는 작성하지 않는다.

 

registerForActivityResult는 프래그먼트나 액티비티를 만들기 전에 호출하는 것이 안전하므로 반환되는 ActivityResultLauncher 인스턴스의 멤버 변수를 선언할 때 직접 사용하는 것이 좋다.

 

resultCode 는 임의로 작성하였다.

 

인텐트로 resultCode를 정의하는 형식으로 하거나,

런처를 여러개 만드는 방식으로도 처리를 할 수 있다.

 

이제 두개의 액티비티로 이동하는 버튼 기능을 각각 정의해주고,

 

이동한 액티비티에서는 돌아가는 버튼을 누르면

정해진 resultCode 를 통해 값을 전달하도록 한다. 위 방식은 기존 방식과 차이가 없다.

그러면 위와 같이 액티비티에서 보낸 값을 resultCode 를 통해 받을 수 있다.

 

 

2️⃣ Permission

private val permissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ){  isGranted: Boolean ->
        if(isGranted){
            Toast.makeText(this, "허가", Toast.LENGTH_SHORT).show()
        }
        else{
            Toast.makeText(this, "실패", Toast.LENGTH_SHORT).show()
        }
    }

아까 살펴본 ActivityResultContracts 에서 RequestPermission을 통해 권한을 요청하는 코드를 작성해주고

 

// 카메라 권한 요청 - 1
perButton.setOnClickListener {
    if(ContextCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){
        Toast.makeText(this@MainActivity, "이미 권한이 있습니다.", Toast.LENGTH_SHORT).show()
    }
    else{
        permissionLauncher.launch(Manifest.permission.CAMERA)
    }
}

 

권한 검사를 해 launch를 해주면 쉽게 권한을 요청할 수 있다.

 

그런데, RequestPermission 의 내부구조를 살펴보면

내부에서 이미 권한 검사를 하는 것을 알 수 있다.

 

// 카메라 권한 요청 - 2
perButton.setOnClickListener {
    permissionLauncher.launch(Manifest.permission.CAMERA)
}

따라서 권한 검사 없이 그냥 바로 호출해도 이상없이 작동한다.

 

 

 

 

 

 

https://github.com/HanYeop/AndroidStudio-Practice2/tree/master/ActivityResultLauncher

 

GitHub - HanYeop/AndroidStudio-Practice2: (2021.05.20~) 안드로이드 학습 내용 저장소

(2021.05.20~) 안드로이드 학습 내용 저장소. Contribute to HanYeop/AndroidStudio-Practice2 development by creating an account on GitHub.

github.com

 

 

 

참고

https://developer.android.com/training/basics/intents/result?hl=ko 

https://developer.android.com/training/permissions/requesting

 

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading