개요
코틀린을 사용하여 안드로이드 앱을 개발할 때, 액티비티(Activity)는 화면을 구성하는 기본 단위입니다.
이 포스트에서는 액티비티 간의 화면 전환 방법, 데이터 전달, 그리고 여러 액티비티를 거쳐 최종 액티비티로 돌아오는 방법을 설명합니다.
서브 액티비티 만들기
먼저 새로운 서브 액티비티를 만들어야 합니다.
프로젝트에 새로운 액티비티 추가하기
- Android Studio에서
패키지 이름
을 우클릭한 후,New > Activity > Empty Views Activity
를 선택합니다. Activity Name
을 적당한 이름으로 설정합니다 (예:SubActivity
).Finish
를 눌러 생성합니다.
기본 액티비티 구성
먼저, 메인 액티비티와 서브 액티비티를 설정해보겠습니다.
메인 액티비티에서는 서브 액티비티를 시작하고, 서브 액티비티에서는 사용자가 입력한 데이터를 다시 메인 액티비티로 반환하는 구조를 갖습니다.
Main Activity
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
// ActivityResultLauncher 선언
private val activityResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.getStringExtra("returnValue")?.let { message ->
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.btnStart.setOnClickListener {
val intent = Intent(this, SubActivity::class.java)
intent.putExtra("from1", "hello Bundle")
intent.putExtra("from2", 12345)
activityResultLauncher.launch(intent) // startActivityForResult 대신 사용
}
}
}
Sub Activity
class SubActivity : AppCompatActivity() {
private val binding by lazy { ActivitySubBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
with(binding) {
to1.text = intent.getStringExtra("from1")
to2.text = "${intent.getIntExtra("from2", 0)}"
btnClose.setOnClickListener {
val returnIntent = Intent()
val message = editMessage.text.toString() // 사용자 입력
returnIntent.putExtra("returnValue", message) // 결과 데이터 설정
setResult(Activity.RESULT_OK, returnIntent) // 결과 코드 및 데이터 설정
finish() // 서브 액티비티 종료
}
}
}
}
화면 전환 및 데이터 전달 방법
서브 액티비티 호출하기
- MainActivity에서 버튼 클릭 시
Intent
를 사용하여SubActivity
를 호출합니다. 이때,putExtra
메서드를 사용하여 서브 액티비티로 전달할 데이터를 설정합니다.
binding.btnStart.setOnClickListener {
val intent = Intent(this, SubActivity::class.java)
intent.putExtra("from1", "hello Bundle") // 문자열 데이터
intent.putExtra("from2", 12345) // 정수 데이터
activityResultLauncher.launch(intent) // 서브 액티비티 호출
}
서브 액티비티에서 데이터 수신하기
- SubActivity에서는
intent
객체를 통해 메인 액티비티에서 전달받은 데이터를 수신합니다.
to1은 문자열을, to2는 정수 데이터를 보냈기에getStringExtra
와getIntExtra
메서드를 사용하여 데이터를 가져옵니다.
to1.text = intent.getStringExtra("from1") // 문자열 데이터 표시
to2.text = "${intent.getIntExtra("from2", 0)}" // 정수 데이터 표시
서브 액티비티에서 메인 액티비티로 데이터 반환하기
- 사용자가 입력한 데이터를
Intent
에 담아 메인 액티비티로 반환합니다.setResult
메서드를 사용하여 결과 코드를 설정하고,finish()
를 호출하여 서브 액티비티를 종료합니다.
btnClose.setOnClickListener {
val returnIntent = Intent()
val message = editMessage.text.toString() // 사용자 입력
returnIntent.putExtra("returnValue", message) // 결과 데이터 설정
setResult(Activity.RESULT_OK, returnIntent) // 결과 코드 및 데이터 설정
finish() // 서브 액티비티 종료
}
메인 액티비티에서 서브 액티비티의 결과 처리하기
MainActivity
에서는ActivityResultLauncher
를 사용하여 서브 액티비티의 결과를 처리합니다.
서브 액티비티에서 반환된 데이터는onActivityResult
메서드에서 확인할 수 있습니다.
private val activityResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.getStringExtra("returnValue")?.let { message ->
Toast.makeText(this, message, Toast.LENGTH_SHORT).show() // 반환된 데이터 표시
}
}
}
이러한 방법으로 메인 액티비티와 서브 액티비티 간에 데이터를 전달하고, 사용자 입력에 따라 메인 액티비티로 데이터를 반환하는 기능을 구현할 수 있습니다.
각 단계에서 Intent를 활용하여 간편하게 데이터를 주고받을 수 있으므로, 여러 화면 간의 원활한 데이터 처리가 가능합니다.
Q&A
startActivity(intent)
와 activityResultLauncher.launch(intent)
의 차이점
startActivity(intent)
- 용도: 새로운 액티비티를 시작할 때 사용합니다.
- 장점
- 간단하게 새로운 액티비티를 시작할 수 있습니다.
- 결과를 받지 않고 단순히 화면 전환만 필요할 때 적합합니다.
- 단점
- 이전 액티비티로부터의 결과를 받을 수 없습니다.
activityResultLauncher.launch(intent)
- 용도: 새로운 액티비티를 시작하고, 그 액티비티에서 결과를 반환받기 위해 사용합니다.
- 장점
- 시작한 액티비티에서 반환된 결과를 쉽게 처리할 수 있습니다.
- 결과 코드와 데이터를 직접 받아올 수 있어, 보다 유연한 처리가 가능합니다.
- 단점
- 모든 액티비티에 대해 결과가 필요하지 않을 때 사용하기엔 다소 복잡할 수 있습니다.
정리
- 만약 서브 액티비티에서 결과를 메인 액티비티로 보내야 한다면
activityResultLauncher.launch(intent)
를 사용하는 것이 좋습니다. - 반면에 단순히 화면을 전환하고, 결과가 필요하지 않을 경우에는
startActivity(intent)
를 사용하는 것이 더 간단하고 효율적입니다.
finish()는…
메인 액티비티에서 서브 액티비티로 이동할 때는 val intent = Intent(this, SubActivity::class.java) 라고 확실히 지정을 해줬는데, 돌아올때는 메인 액티비티로 간다는 명령이 없는 이유가 무엇때문인지 궁금할 수 있습니다.
이 부분은 안드로이드 액티비티의 생명주기와 인텐트의 흐름을 이해하는 데 중요한 개념입니다.
간단히 설명하자면, 서브 액티비티에서 finish()
메서드를 호출할 때, 이전 액티비티(즉, 메인 액티비티)로 돌아가는 것입니다.
finish() 메서드는 현재 액티비티를 종료하는 역할을 합니다.
이 메서드를 호출하면 현재 액티비티의 생명주기가 종료되고, 다시 이전 액티비티로 돌아가게 됩니다.