안드로이드 개발자의 창고
[34일차 Android] OnActivityResult 본문
출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT
📖 startActivityForResult
- Activity에서 다른 Activity를 실행하고 다시 돌아왔을 때 어떤 처리가 필요하다면 Activity를 실행할 때 startActivity가 아닌startActivityForResult 메서드를 사용한다.
onActivityResult
-
startActivityForResult 메서드를 이용해 Activity를 실행하고 돌아오면 자동으로 onActivityResult 메서드가 호출된다.
-
여기에서 필요한 작업을 처리한다.
예제 코드
MainActivity.kt - startActivityForResult()
button.run {
setOnClickListener {
// SecondActivity 실행
val secondIntent = Intent(this@MainActivity, SecondActivity::class.java)
// startActivity(secondIntent)
// 값들을 설정한다.
secondIntent.putExtra("data1", 100)
secondIntent.putExtra("data2", 11.11)
secondIntent.putExtra("data3", true)
secondIntent.putExtra("data4", "안녕하세요")
val t1 = TestClass()
t1.name = "홍길동"
t1.age = 100
secondIntent.putExtra("data5", t1)
// requestCode - 개발자를 위한 코드
startActivityForResult(secondIntent,SECOND_ACTIVITY)
}
}
- startActivityForResult로 Activity를 전환하는 코드이다.
- secondIntent를 선언하여 MainActivity에서 SecondActivity로 전환하도록 한다.
- secondIntent에 data1~4와 TestClass()의 객체를 전달한다.
- SECOND_ACTIVITY는 requsetCode로 개발자가 Activity를 구분하기 위해 사용한다.
MainActivity.kt - onActivityResult()
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
SECOND_ACTIVITY -> {
activityMainBinding.textView.text = "SecondActivity에서 돌아왔습니다\n"
// resultCode로 작업의 결과를 구분한다.
when(resultCode){
RESULT_OK -> {
activityMainBinding.textView.append("작업 성공\n")
// 3번째 매개변수로 전달되는 Intent 객체로부터 데이터를 추출해 사용한다.
if (data != null){
val value1 = data.getIntExtra("value1", 0)
val value2 = data.getDoubleExtra("value2", 0.0)
val value3 = data.getBooleanExtra("value3", false)
val value4 = data.getStringExtra("value4")
activityMainBinding.textView.append("value1 : ${value1}\n")
activityMainBinding.textView.append("value2 : ${value2}\n")
activityMainBinding.textView.append("value3 : ${value3}\n")
activityMainBinding.textView.append("value4 : ${value4}\n")
}
}
RESULT_CANCELED -> {
activityMainBinding.textView.append("작업 취소\n")
}
}
}
THIRD_ACTIVITY -> {
activityMainBinding.textView.text = "ThirdActivity에서 돌아왔습니다\n"
}
}
}
- startActivityForResult()에 전달한 requsetCode로 각각의 Activity를 구분한다.
- setResult()로 전달된 작업 결과로 한 번 더 분기 처리를 한다.
MainActivity.kt - TestClass()
class TestClass() : Parcelable{
lateinit var name : String
var age:Int = 0
// 객체를 Intent에 저장하면 parcel에 저장됨
constructor(parcel: Parcel) : this() {
// 멤버 변수에 값을 담는다.
// Parcel에 저장한 순서대로 추출한다.
name = parcel.readString()!!
age = parcel.readInt()
}
// 객체를 Intent에 넣으려고 할 때 호출된다.
// 매개 변수로 전달되는 parcel 객체에 객체 복원에 필요한 값들을 넣어준다.
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeInt(age)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<TestClass> {
// Intent로 부터 객체를 추출할 때 호출되는 메서드
// 새로운 객체를 생성하고 parcel에 저장되어 있는 값을 객체 맴버 변수에 담아준다.
override fun createFromParcel(parcel: Parcel): TestClass {
return TestClass(parcel)
}
override fun newArray(size: Int): Array<TestClass?> {
return arrayOfNulls(size)
}
}
}
- 안드로이드에서 4대 구성요소 간에 객체를 전달하기 위한 직렬화를 수행하기 위해 Parcelable 인터페이스를 구현한다.
- Java의 Serialize와 같은 역할을 한다.
SecondActivity.kt
secondBinding.run {
// Activity를 실행하기 위해 사용한 Intent로부터 데이터를 추출한다.
textViewSecond.text = "SecondActivity\n"
// 기본 자료형에 관련된 메서드들을 데이터의 이름과 저장된 것이 없을 경우 사용할 기본 값을 설정한다.
val data1 = intent.getIntExtra("data1", 0)
val data2 = intent.getDoubleExtra("data2",0.0)
val data3 = intent.getBooleanExtra("data3", false)
// 객체는 기본값을 설정하지 않으며 값이 없을 경우에는 null이 반한된다.
val data4 = intent.getStringExtra("data4")
textViewSecond.append("data1 : ${data1}\n")
textViewSecond.append("data1 : ${data2}\n")
textViewSecond.append("data1 : ${data3}\n")
textViewSecond.append("data1 : ${data4}\n")
// 객체를 복원한다.
// SDK 버전별 처리
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
val data5 = intent.getParcelableExtra("data5", TestClass::class.java)
textViewSecond.append("data5.name : ${data5?.name}")
textViewSecond.append("data5.age : ${data5?.age}")
} else {
val data5 = intent.getParcelableExtra<TestClass>("data5")
textViewSecond.append("data5.name : ${data5?.name}")
textViewSecond.append("data5.age : ${data5?.age}")
}
buttonSecond.run {
setOnClickListener {
// 작업의 결과를 설정해준다.
// RESULT_OK : 작업이 정상적으로 끝났다는 것을 의미한다.
// RESULT_CANCELED : 작업이 취소되었다는 것을 의미한다.
// RESULT_FIRST_USER : 작업의 상황을 더 추가적으로 정의하고 싶을 때(+1, +2, +3...)
// setResult(RESULT_OK)
// setResult(RESULT_CANCELED)
// 이전 Activity로 전달할 데이터를 설정할 Intent 객체를 생성한다.
val resultIntent = Intent()
// 값을 설정한다.
resultIntent.putExtra("value1", 200)
resultIntent.putExtra("value2", 22.22)
resultIntent.putExtra("value3", false)
resultIntent.putExtra("value4" , "반갑습니다")
// 돌아갈 때 전달할 값이 있다면
// setResult 메서드의 두번째 매개 변수에 Intent 객체를 넣어준다.
setResult(RESULT_OK, resultIntent)
// Activity 종료
finish()
}
}
}
- SecondActivity에서 button을 클릭했을 때 실행되는 코드
- SDK 버전별로 객체를 복원하는 메서드가 다르다.
- setResult()로 작업의 결과와 Intent를 전달한다.
📖 registerForActivityResult
- startActivityForResult 와 onActivityResult 메서드 조합 대신 사용한다.
- 다수의 액티비티 실행을 분리해 관리할 수 있다는 장점을 가지고 있다.
예제 코드
MainActivity.kt - onCreate() 내부
val c1 = ActivityResultContracts.StartActivityForResult()
val fourthActivityLauncher = registerForActivityResult(c1){
// FourthActivity를 갔다 돌아왔을 때의 코드를 구현한다.
textView.text = "FourthActivity를 갔다 돌아왔습니다\n"
// Result Code로 분기한다.
if (it.resultCode == RESULT_OK){
// Intent를 통해 값들을 추출한다.
val value1 = it.data?.getIntExtra("value1", 0)
val value2 = it.data?.getDoubleExtra("value2", 0.0)
textView.append("value1 : ${value1}\n")
textView.append("value2 : $value2")
}
}
- registerForActivityResult()를 사용한 코드
- ActivityResultContracts를 사용하여 계약 객체(c1)을 생성한다.
- 계약 객체는 '이 객체를 가지고 ~~를 할거다'라는 의미이다.
- 이 코드는 다른 Activity를 갔다 돌아왔을 경우라는 것을 의미하는 StartActivityForResult()를 사용한다.
button3.run {
setOnClickListener {
// FourthActivity 실행
val fourthIntent = Intent(this@MainActivity, FourthActivity::class.java)
fourthIntent.putExtra("data1", 100)
fourthIntent.putExtra("data2", 11.11)
fourthActivityLauncher.launch(fourthIntent)
}
}
- 위에서 선언한 fourthActivityLauncher를 사용하여 Intent를 전달한다.
'Computer > Android' 카테고리의 다른 글
[37일차 Android] Toast (0) | 2023.06.23 |
---|---|
[37일차 Android] 다른 앱의 Activity 실행하기 (0) | 2023.06.23 |
[34일차 Android] Activity 실행하기 (0) | 2023.06.17 |
[34일차 Android] Activity (0) | 2023.06.17 |
[34일차 Android] Popup Menu (0) | 2023.06.17 |