Parcelable 및 번들

ParcelableBundle 객체는 IPC/바인더 트랜잭션과 같은 프로세스 경계 전반에서 인텐트가 있는 활동 간에 사용하고 구성 변경 시 일시적인 상태를 저장하기 위한 것입니다. 이 페이지에서는 ParcelableBundle 객체 사용을 위한 추천 및 권장사항을 제공합니다.

참고: Parcel은 범용 직렬화 메커니즘이 아니므로 Parcel 데이터를 디스크에 저장하거나 네트워크를 통해 전송해서는 안 됩니다.

활동 간 데이터 전송

앱이 새 활동을 시작하면서 startActivity()에 사용할 Intent 객체를 생성할 때 putExtra() 메서드를 사용하여 매개변수를 전달할 수 있습니다.

다음 코드 스니펫은 이 작업을 실행하는 방법의 예를 보여줍니다.

val intent = Intent(this, MyActivity::class.java).apply {
    putExtra("media_id", "a1b2c3")
    // ...
}
startActivity(intent)

OS는 인텐트의 기본 Bundle을 묶습니다. 그런 다음 OS는 새 활동을 생성하고 데이터 번들을 풀며 인텐트를 새 활동에 전달합니다.

Bundle 클래스를 사용하여 Intent 객체에서 OS에 알려진 프리미티브를 설정하는 것이 좋습니다. Bundle 클래스는 Parcel을 사용하는 마샬링 및 언마샬링에 고도로 최적화되어 있습니다.

활동 간에 복잡한 객체를 전달하거나 UI 상태에 보존해야 하는 경우도 있습니다. 이러한 경우 맞춤 클래스는 Parcelable을 구현해야 합니다. 최신 Kotlin 및 Jetpack Compose 앱의 경우 @Parcelize 주석을 사용하는 것이 좋습니다. 이렇게 하면 번들을 사용할 때 데이터를 안전하게 처리하는 데 필요한 직렬화 로직이 자동으로 생성됩니다. 이는 rememberSaveable을 사용할 때 데이터를 처리하는 데 사용되는 접근 방식과 동일합니다. @Parcelize 사용에 관한 자세한 내용은 Parcelable 구현 생성기를 참고하세요.

인텐트를 통해 데이터를 전송할 때 데이터 크기를 몇 KB로 제한해야 합니다. 너무 많은 데이터를 전송하면 시스템에서 TransactionTooLargeException 예외가 발생할 수 있습니다.

프로세스 간 데이터 전송

프로세스 간 데이터 전송은 활동 간 데이터 전송과 비슷합니다. 그러나 프로세스 간 전송 시 맞춤 Parcelable을 사용하지 않는 것이 좋습니다. 한 앱에서 다른 앱으로 맞춤 Parcelable 객체를 전송할 때에는 전송 앱과 수신 앱 모두에 정확히 동일한 버전의 맞춤 클래스가 확실히 있어야 합니다. 일반적으로 맞춤 클래스는 두 앱 모두에서 사용되는 공통 라이브러리일 수 있습니다. 시스템은 인식하지 못하는 클래스를 언마샬링할 수 없기 때문에 앱이 맞춤 Parcelable을 시스템에 전송하려고 하면 오류가 발생할 수 있습니다.

예를 들어 앱은 AlarmManager 클래스를 사용하여 알람을 설정하고 알람 인텐트에서 맞춤 Parcelable을 사용할 수 있습니다. 알람이 울릴 때 시스템은 인텐트의 Extras Bundle을 수정하여 반복 횟수를 추가합니다. 이 수정으로 시스템은 Extras에서 맞춤 Parcelable을 제거할 수 있습니다. 이 제거로 인해 결과적으로 앱이 수정된 알람 인텐트를 수신할 때 다운될 수 있습니다. 앱이 더 이상 존재하지 않는 추가 데이터를 수신하기 위해 기다리기 때문입니다.

바인더 트랜잭션 버퍼는 현재 1MB의 고정 크기로 제한되어 있으며 이 버퍼는 프로세스를 대상으로 진행 중인 모든 트랜잭션에 의해 공유됩니다. 활동별 수준이 아니라 프로세스 수준에 이 제한이 적용되기 때문에 이러한 트랜잭션에는 startActivity, rememberSaveable (내부에서 onSaveInstanceState 사용) 등 앱의 모든 바인더 트랜잭션과 시스템과의 상호작용이 포함됩니다. 크기 제한을 초과하면 TransactionTooLargeException이 발생합니다.

rememberSaveable로 상태를 저장하는 구체적인 경우, 사용자가 Activity로 다시 탐색할 수 있는 한 (Activity의 프로세스가 종료되었더라도) 시스템 프로세스가 제공된 데이터를 계속 보유해야 하므로 데이터 양을 적게 유지해야 합니다. 저장된 상태를 50KB 미만의 데이터로 유지하는 것이 좋습니다.

참고: Android 7.0 (API 수준 24) 이상에서는 시스템에서 TransactionTooLargeException를 런타임 예외로 발생시킵니다. 하위 버전의 Android에서는 시스템이 logcat에 경고만 표시합니다.