이번 포스팅은 액티비티끼리 데이터를 주고받을 때 사용하는 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
'안드로이드 공부 노트' 카테고리의 다른 글
[Android] 안드로이드 Parcelable(@Parcelize) 사용해 액티비티간 데이터(Object) 전달하기 - Kotlin (0) | 2022.10.28 |
---|---|
[Android - Glide] 안드로이드 이미지 로드 라이브러리 Glide 사용법 - Kotlin (0) | 2022.10.09 |
[Android]안드로이드 SharedPreferences란? (예제를 이용한 사용법) (0) | 2022.03.23 |
[Android] 안드로이드 뷰 페이저2(ViewPager2)+탭 레이아웃(TabLayout) 예제를 통한 사용법 (0) | 2022.03.13 |
[Android]안드로이드 매니페스트(Manifest)란? - 개념,역할 (0) | 2022.03.10 |