0. startActivityForResult() 에 대해 알아보자.( => registerForActivityResult() )
- startActivity() : Activity 간의 이동이 이루어지나, 이동전 Activity -> 이동후 Activity. 즉, 단방향으로 작업이 이루어진다.
- startActivityForResult(), onActivityResult() : Activity 간의 이동 되는 것은 같으나, 이동후 Activity 로 부터 결과를 받아 올 수 있는 양방향으로 작업이 이루어진다는 점이 다르다.
- 그러나 웬걸.. 이 API는 이미 deprecated 되었다는 사실!!!
AndroidX의 androidx.activity:activity:1.2.0 부터는(startActivityForResult() + onActivityResult())대신 registerForActivityResult() 로 사용하도록 안내되어 있다. 두둥! => 자세한 내용은 여기를 Click- 개선된 점 : 코드 가독성, REQUEST_CODE 사용 제외, 타입 안정성
- 사용법이 조금 다르긴 하지만 크게 어렵지 않아 이번 예제에서는 registerForActivityResult() 를 사용해보도록 하자.
1. 기능 구현
- MainActivity : SubActivity 로 이동할 Button 1개와 결과값을 받아 보여줄 TextView 를 만들자.
- SubActivity : SubActivity 를 종료할 Button 1개와 결과값으로 넘겨줄 텍스트를 입력할 EditText 를 만들자.
Flow = MainActivity -> SubActivity : 텍스트 입력 -> SubActivity 종료 -> 입력 텍스트 전달(결과값) -> MainActivity 텍스트 출력
2. Android Studio에서 기본 프로젝트(with empty activity) 생성하자!
생성시 'Empty Activity'로 기본 생성
3. ViewBinding 사용을 위한 build.gradle 설정
android {
// 뷰 바인딩 옵션 활성화
viewBinding {
enabled = true
}
}
4. SubActivty.kt, activity_sub.xml 생성하기.
패키지명 우클릭 -> New -> Activity -> Empty Activty : SubActivity 로 이름을 짖자.
5. activity_main.xml
'GO' Button 1개 + '결과값 출력' TextView 1개
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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/tv_comeback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="값을 가져와 주세요"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_go"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GO"/>
</LinearLayout>
6. activity_sub.xml
'종료' Button 1개 + '전달할 결과값 입력' EditText 1개
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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=".SubActivity">
<EditText
android:id="@+id/et_comback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="23sp"
android:hint="Main으로 보낼 값 입력해주세요"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="종료"/>
</LinearLayout>
7. MainActivity.kt
- openActivityResultLauncher() : registerForActivityResult() 를 사용하여 ActivityResultLauncher 타입을 반환하는 메소드를 만들어 보자.
registerForActivityResult() 에서는 CallBack 을 등록할뿐, 다른 Activity를 실행하거나 결과 요청을 하지 않는 대신,
생성,반환된 ActivityResultLauncher 인스턴스를 통해 할 수 있다.
인스턴스.launch() 를 통해 언제든 다시 결과를 생성하는 프로세스가 시작될 수 있다는 것!
- 주의할 점
registerForActivityResult() 를 통한 인스턴스 생성은 Activity 생명 주기 중, onCreate() 또는 onStart() 에서 호출해야한다.
(만약 onResume() 에서 호출 시, 에러가 발생하니 주의하도록 하자.)
class MainActivity : AppCompatActivity() {
private var mBinding : ActivityMainBinding? = null
private val binding get() = mBinding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val activityLauncher= openActivityResultLauncher()
binding.btnGo.setOnClickListener {
val intent = Intent(this, SubActivity::class.java)
activityLauncher.launch(intent)
}
}
private fun openActivityResultLauncher(): ActivityResultLauncher<Intent> {
val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result:ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
Toast.makeText(this, "수신 성공", Toast.LENGTH_SHORT).show()
binding.tvComeback.text = result.data?.getStringExtra("comeback")
}
else {
Toast.makeText(this, "수신 실패", Toast.LENGTH_SHORT).show()
}
}
return resultLauncher
}
}
8. SubActivity.kt
- intent.putExtra("comeback", binding.etComback.text.toString()) : EditText 값을 Key:comback 으로 하여 Intent 에 넣어보자.
- setResult(RESULT_OK, intent) : 결과 상태를 OK 로 설정
- finish() : SubActivity 를 종료하자.
class SubActivity : AppCompatActivity() {
private var mBinding : ActivitySubBinding? = null
private val binding get() = mBinding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivitySubBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnClose.setOnClickListener {
val intent = Intent()
intent.putExtra("comeback", binding.etComback.text.toString())
setResult(RESULT_OK, intent)
finish()
}
}
}
9. 실행결과
10. Reference
- 주의할 점
참고한 동영상 강의는 Java 로 진행된 강의입니다. Kotlin 을 공부하기 위한 목적으로 Java-Kotlin 간의 다른 부분에 대해서
직접 찾아가며 예제 작성을 하였고 영상이 올라온 시점이 3년 전이라 현재의 버전, API 들이 deprecated 된 경우도 있어
이 또한 현재 권장하는 API로 변경/적용 한 부분이 있어 Code가 다를 수 있으니 보시는 분들은 참고 바람.
'Android > Kotlin' 카테고리의 다른 글
[Android, Kotlin] BottomNavigation (0) | 2022.04.25 |
---|---|
[Android, Kotlin] AndroidX (Jetpack libraries) (0) | 2022.04.25 |
[Android, Kotlin] BackButton (0) | 2022.04.23 |
[Android, Kotlin] Spinner (0) | 2022.04.23 |
[Android, Kotlin] ServiceMusic (1) | 2022.04.22 |