Parcelable 및 번들

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

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

활동 간 데이터 전송

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

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

Kotlin

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

자바

    Intent intent = new Intent(this, MyActivity.class);
    intent.putExtra("media_id", "a1b2c3");
    // ...
    startActivity(intent);
    

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

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

활동 간에 합성 또는 복합 객체를 전송하는 메커니즘이 필요한 상황도 있습니다. 이럴 때 맞춤 클래스는 Parcelable을 구현하고 적절한 writeToParcel(android.os.Parcel, int) 메서드를 제공해야 합니다. 또한 CREATOR라는 null이 아닌 필드도 제공해야 합니다. CREATOR는 Parcel을 현재 객체로 다시 변환하는 데 createFromParcel() 메서드를 사용하는 Parcelable.Creator 인터페이스를 구현합니다. 자세한 내용은 Parcelable 객체의 참조 문서에서 확인하세요.

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

프로세스 간 데이터 전송

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

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

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

구체적으로 savedInstanceState에서는 사용자가 활동으로 다시 이동할 수 있는 한(활동의 프로세스가 종료되었더라도) 시스템 프로세스가 제공된 데이터를 계속 보유해야 하므로 데이터 양을 적게 유지해야 합니다. 저장된 상태를 50k 미만의 데이터로 유지하는 것이 좋습니다.

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