ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 액티비티간 데이터 전달 - startActivityForResult
    Android 2024. 10. 10. 16:05

    이전 화면으로 되돌아올 때 사후처리가 필요한 경우가 있다.

    그때 필요한 방법은 아래 두가지가 있다.

    • startActivityForResult (전통적인 방법) → deprecated 됨
    • ActivityResultLauncher (최근 권장하는 방법)

    오늘은 startActivityForResult 의 사용법을 알아보려한다.

     

    해당 방식은 안드로이드 버전1~버전12 까지는 잘 사용됐지만, 안드로이드 11 버전이 나올쯤부터 androidx의 ActivityResultLauncher 가 권장되기 시작했다. 권장되는 방식인 ActivityResultLauncher 을 바로 사용하는 것도 괜찮지만, 기존 startActivityForResult 를 먼저 공부해보고 어떤 점이 불편해서 ActivityResultLauncher 가 나오게 되었는 지 알아가는 과정도 좋다고 생각한다.

    일단 그림으로 상황을 간단하게 정리해보면 아래와 같다.

     

    액티비티 A  - 데이터 받아올 준비하기

    액티비티 A는 2가지 준비를 해야한다. 첫번째는, 액티비티 B를 실행시켜야 하고, 액티비티 B로부터 데이터를 받아올 준비를 해야한다. 데이터를 받아올 준비를 하는 과정부터 보자.

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    	super.onActivityResult(requestCode, resultCode, data)
         	if(requestCode == 지정한 정수값 && resultCode == Activity.RESULT_OK) {
        	val result = data?.getStringExtra("key")
            // 이후 해당 result 변수 사용하기
        }
    }

     

    해당 onActivityResult 함수는 액티비티 B 에서 액티비티 A 로 전환될 때 자동으로 호출된다.

    각각의 매개변수의 의미는 다음과 같다.

    requestCode A 액티비티에서 B 액티비티를 실행할 때 필요한 요청 코드
    → 인텐트 구분
    resultCode B 액티비티에서 돌려받은 결과 코드
    data B 액티비티가 전달한 데이터를 가진 인텐트 객체


    지금 단계에서는 data 만 이해해도 충분하다. 사실 requestCode 랑 resultCode 는 아직 잘 이해가 되지 않을 것이다. 두개는 넘어가도 좋다. 해당 오버라이딩 함수 내에서 B 액티비티로부터 data 파라미터로 데이터를 받아올 수 있고, 인텐트 객체이기 때문에 getExtra 를 통해 꺼내온 데이터를 사용할 수 있다는 점이 중요하다.


    액티비티 A - 액티비티 B 실행하기

    이제 액티비티 A 는 데이터를 받아올 준비를 완료했다. 이제 액티비티 B 를 실행하면 된다.

    val intent = Intent(this@AActivity, BActivity::class.java)
    startActivityForResult(intent, 10)


    여기서 기존의 startActivity 가 아니라 startActivityForResult 함수를 사용해야 한다.

    이때는, intent 객체 외에 한개의 파라미터가 더 필요하다. 바로, 요청 코드(requestCode)이다.

    요청 코드는 인텐트를 식별하는 값으로, 정수값을 임의로 지정해주면 된다.

    만약에, 10으로 지정하면 해당 인텐트 변수에 이름표 10을 붙여주는 것과 같다.

    이렇게 하면 B 액티비티가 실행된다. (네이밍을 잘못했다.)

     

    근데, 여기서 한가지 더 이해해야할게 있다. requestCode 는 아까 A 액티비티가 데이터를 받아올 준비를 할 때 등장했었다.
    스크롤하기 힘드니 아래에 다시 작성했다.

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    	super.onActivityResult(requestCode, resultCode, data)
         	if(requestCode == 지정한 정수값 && resultCode == Activity.RESULT_OK) {
        	val result = data?.getStringExtra("key")
            // 이후 해당 result 변수 사용하기
        }
    }

     

    여기서 첫번째 파라미터가 해당 개념이다. 만약에, 10을 지정했다면, 저기에 써있는 "지정한 정수값" 에도 10을 넣어주면 된다. 이제 requestCode 와 data 는 이해했고, 남은 resultCode 만 이해하면 된다.

     

    액티비티 B - 액티비티 A 에 데이터 전달하기

    intent.putExtra("key", "value")
    setResult(RESULT_OK, intent)
    finish()

     

    여기서 intent 는 자신을 실행한 A 액티비티에서 전달한 인텐트 객체를 의미하기 때문에, 인텐트를 다시 생성하는게 아니다. 액티비티로부터 전달된 인텐트에 원하는 정보를 담고, setResult 함수에다가 resultCode 값과 인텐트를 넣으면 된다.

    resultCode 는 대표적으로 다음 종류가 있다.

    RESULT_OK 요청을 제대로 처리한 경우
    RESULT_CANCELED 요청을 제대로 처리하지 않은 경우

     

    finish 함수 같은 경우, 현재 화면에 보이는 액티비티(B 액티비티)를 종료해 달라고 시스템에 요청하는 것을 의미한다. 이렇게 하면 시스템은 이전 액티비티(A 액티비티)로 화면을 되돌린다. 이렇게 하면 사용자가 뒤로가기 버튼을 누르지 않아도 자동으로 화면을 전환할 수 있다.

    아까 A 액티비티에서 데이터를 받기 위해 필요한 준비물 코드를 다시 살펴보자.

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    	super.onActivityResult(requestCode, resultCode, data)
         	if(requestCode == 지정한 정수값 && resultCode == Activity.RESULT_OK) {
        	val result = data?.getStringExtra("key")
            // 이후 해당 result 변수 사용하기
        }
    }


    파라미터를 다시 정리하자면, requestCode 는 액티비티 A 에서 인텐트를 식별하기위해 정하는 값이다. resultCode 는 실행된 액티비티 B 에서 결정하는 상수값이다. data 는 액티비티 B 로부터 넘어온 데이터를 품은 인텐트 객체이다.

    이걸 내가 왜 써야하고, 해당 기능을 쓰면 어떤 화면을 구현할 수 있는 것일까?

    사용 예시(시연 영상)

     


    회원가입을 하고 나서 로그인 창으로 넘어올 때 아이디와 비밀번호 데이터가 넘어온 것을 볼 수 있다.
    이렇게 하면, 사용자는 번거롭게 다시 아이디와 비밀번호를 칠 필요가 없다. 해당 기능을 사용하지 않으면 유저는 회원가입을 한 이후에도 로그인을 하기 위해 아이디와 비밀번호를 한번 더 쳐야한다.
    즉, 다른 조건이 동일하다는 전제 하에, 해당 앱을 구현한 앱이 구현하지 않은 앱보다 UX(User Experience)가 더 우수하고 경쟁력이 있다.

    다음에는 권장되는 방식인 ActivityResultLauncher 사용 방식도 정리해보고, 왜 전자 방식이 deprecated가 되었고, 후자 방식을 사용해야 하는가에 대한 생각도 적어볼 예정이다!

Designed by Tistory.