본문 바로가기
안드로이드 공부 노트

[Android] 안드로이드 registerForActivityResult()란?(startActivityForResult derpecated 해결 방법)

by 지게요 2022. 5. 29.
728x90
반응형

이번 포스팅은 액티비티끼리 데이터를 주고받을 때 사용하는 startActivityForResult derpecated 됨에 따라 해결 방법을 포스팅해 보겠다.

 

# registerForActivityResult란?

공식 문서에 나와있는 내용을 정리해 보면,

Activity 또는 Fragment에 있을 때, Activity Result API에서 제공하는 registerForActivityResult() API를 통해서 결과 콜백을 등록할 수 있다.

여기서 registerForActivityResult()는 ActivityResultContract와 ActivityResultCallback을 가져와서 다른 activity를 실행하는 데 사용할 ActivityResultLauncher를 반환한다.

  • ActivityResultContract는 우리가 결과를 생성하는 데 필요한 입력의 형태와 결과를 출력하는 형태를 정의하고 우리가 intent를 사용하는 작업의 기본적인 계약을 제공한다.

이러한 내용이 있다.

사실 글만 읽어서는 이해가 잘 되지 않는다.

아래 예제를 통해 코드로 알아보자

 

# 예제를 통한 사용법

 

예제를 설명하자면

1. A액티비티(MainActivity)에서 넘어가기 버튼을 눌러 B액티비티(secondActivity)로 넘어간다.

2. B액티비티에서 이름과 나이 입력

3. 돌아가기 버튼 클릭

4. 돌아온 A액티비티에 B액티비티에서 넘어온 값 확인

이런 식으로 진행된다.

# 사용법

## ActivityResult를 받고자 하는 액티비티에 Callback등록

먼저 예제 기준으로 설명하면 ActivityResult를 받고자 하는 액티비티는 A액티비티이다(MainActivity)

 

1. ActivityResultLauncher자료형인 resultLauncher 변수를 전역 변수로 선언 후 setReultNext라는 함수를 만들어줬다.

class MainActivity : AppCompatActivity() {
    private lateinit var resultLauncher: ActivityResultLauncher<Intent>
    }

2. 만들어준 변수 resultLauncher에 registerForActivityResult메소드를 활용해서 ActivityLauncher를 만든다.

 

registerForActivityResult메소드의 파라미터는 ActivityResultContract, ActivityResultCallback가 필요하다.

ActivityResultContract는 startActivityForResult를 비롯하여 다양한 객체들이 있다.

ActivityResultCallback은 람다로 사용하고 ActivityResult 객체가 파라미터로 떨어지고 여기서 원하는 데이터를 가져오면 된다.

 

그 후 result.resultCode가 올바르게 넘어오면 B액티비티(secondActivity)에서 넘겨준 이름과 나이를 getStringExtra로 받는다.

private fun setResultNext(){
        resultLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()){ result ->
            // 서브 액티비티로부터 돌아올 때의 결과 값을 받아 올 수 있는 구문
            if (result.resultCode == RESULT_OK){

                val name = result.data?.getStringExtra("name") ?: ""
                val age = result.data?.getStringExtra("age") ?: ""

                textName.text = "이름 : $name"
                textAge.text = "나이 : $age 살"
            }
        }
    }

3.  만들어준 변수 resultLauncher.launch()를 통해 데이터를 받아올 Activity를 실행한다.

  nextBtn.setOnClickListener {
            val intent = Intent(this,SecondActivity::class.java)
            resultLauncher.launch(intent) // startActivityForResult 랑 동일한 기능 이다.
        }

 

A액티비티(MainActivity) 전체 코드

package com.example.registerforactivityresultex

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var resultLauncher: ActivityResultLauncher<Intent>
    private lateinit var textName : TextView
    private lateinit var textAge : TextView
    private lateinit var nextBtn : Button
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        textName = findViewById(R.id.textName)
        textAge = findViewById(R.id.textAge)
        nextBtn = findViewById(R.id.nextBtn)

        setResultNext()

        nextBtn.setOnClickListener {
            val intent = Intent(this,SecondActivity::class.java)
            resultLauncher.launch(intent) // startActivityForResult 랑 동일한 기능 이다.

        }
    }

    private fun setResultNext(){
        resultLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()){ result ->
            // 서브 액티비티로부터 돌아올 때의 결과 값을 받아 올 수 있는 구문
            if (result.resultCode == RESULT_OK){

                val name = result.data?.getStringExtra("name") ?: ""
                val age = result.data?.getStringExtra("age") ?: ""

                textName.text = "이름 : $name"
                textAge.text = "나이 : $age 살"
            }
        }
    }
}

 

A액티비티.xml(activity_main.xml) 전체 코드

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="이름"
        android:textSize="45sp"
        android:layout_marginBottom="40dp"
        app:layout_constraintBottom_toTopOf="@+id/textAge"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/textAge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="250dp"
        android:text="나이"
        android:textSize="45sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/nextBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="넘어가기"
        android:layout_marginTop="50dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textAge" />
</androidx.constraintlayout.widget.ConstraintLayout>

## 데이터를 보내 줄 액티비티에서 setResult 등록

1. B액티비티(secondActivity)에서 데이터를 실어서 A액티비티(MainActivity)로 넘겨준다.

intent.putExtra("name",inputName.text.toString())
intent.putExtra("age",inputAge.text.toString())
setResult(RESULT_OK,intent)
finish()

setResult에서 그냥 RESULT_OK만 넘겨줘도 되고 intent를 통해 값을 넘겨줘도 된다.

 

B액티비티(SecondActivity) 전체 코드

package com.example.registerforactivityresultex

import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class SecondActivity : AppCompatActivity() {
    private lateinit var backBtn : Button
    private lateinit var inputName : EditText
    private lateinit var inputAge : EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        backBtn = findViewById(R.id.backBtn)
        inputName = findViewById(R.id.inputName)
        inputAge = findViewById(R.id.inputAge)

        backBtn.setOnClickListener {
            if (inputName.text.isNullOrBlank() || inputAge.text.isNullOrBlank()){
                Toast.makeText(this, "이름과 나이를 입력해주세요", Toast.LENGTH_SHORT).show()
            }
            else{
                intent.putExtra("name",inputName.text.toString())
                intent.putExtra("age",inputAge.text.toString())
                setResult(RESULT_OK,intent)
                finish()
            }

        }

    }

}

B액티비티.xml(activity_second.xml) 전체 코드

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="15dp"
        android:layout_marginStart="15dp"
        app:layout_constraintBottom_toTopOf="@+id/ageLayout">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="5dp"
            android:text="이름 :"
            android:textSize="35sp" />

        <EditText
            android:id="@+id/inputName"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:hint="이름 입력"
            android:textSize="35sp" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/ageLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginStart="15dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="5dp"
            android:text="나이 :"
            android:textSize="35sp" />

        <EditText
            android:id="@+id/inputAge"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:hint="나이 입력"
            android:textSize="35sp" />
    </LinearLayout>

    <Button
        android:id="@+id/backBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="돌아가기"
        android:textSize="25dp"
        android:layout_marginTop="150dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/ageLayout" />

</androidx.constraintlayout.widget.ConstraintLayout>

깃허브 

https://github.com/JiSeokYeom/RegisterForActivityResultEX.git

 

GitHub - JiSeokYeom/RegisterForActivityResultEX

Contribute to JiSeokYeom/RegisterForActivityResultEX development by creating an account on GitHub.

github.com

 

참조 문서
https://developer.android.com/training/basics/intents/result?hl=ko
https://velog.io/@soyoung-dev/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%BD%94%ED%8B%80%EB%A6%B0-registerForActivityResult-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
https://velog.io/@ho-taek/Android-registerForActivityResult%EB%9E%80

 

반응형