nueijeel

[Android] 직렬화 Serializable과 Parcelable 본문

Android/공부

[Android] 직렬화 Serializable과 Parcelable

nueijeel 2024. 12. 27. 21:24

 

그동안 단일 액티비티 기반의 프로젝트에서 프래그먼트 간 데이터 공유를 위해 Bundle 객체를 주로 사용해왔다.

다양한 타입의 값들을 bundle에 담아 전달할 수 있는데 그 중 사용자 정의 클래스 객체를 전달하기 위해서는 직렬화하는 과정이 필요했다.

 

지금까지는 java의 serializable 인터페이스를 구현해 직렬화했었는데,

안드로이드 환경에서 serializable은 성능적 측면에서 문제가 있을 수 있다는 점을 알게되어 더 나은 방안을 찾아보고 포스팅하게 되었다.

 

 

 

직렬화

직렬화(Serializable)는 메모리에 있는 데이터를 디스크에 저장하거나 네트워크 통신을 통해 전달하기 위해 byte stream 형태로 변환하는 것이다. (역직렬화는 반대 개념)

 

 

 

 

그렇다면 직렬화가 필요한 경우는 언제일까?

 

데이터 형식에 따른 메모리 저장 영역과 관련이 있다.

 

 

데이터가 원시 타입일 경우 Stack Memory에 저장된 데이터 그대로를 전달하면 되므로 별도로 직렬화를 하지 않아도 된다.

하지만 Class 타입이나 String, Array 등의 복잡한 데이터들은 Heap Memory에 저장되고, Stack Memory는 Heap Memory에 실제 데이터가 할당된 주소를 참조하게 된다. 이런 형식의 데이터를 디스크에 저장하거나 네트워크 통신으로 전달하기 위해서는 참조된 주소값이 아닌 실제 데이터 값을 이용해야하기 때문에 데이터를 직렬화하는 과정이 필요한 것이다.

 

 

 

Serializable

자바 직렬화 메커니즘인 Serializable을 통해 객체 직렬화/역직렬화가 가능하다.

 

 

Serializable 인터페이스는 자체로 메서드가 없는 마커 인터페이스이기 때문에 추가적인 구현 코드를 작성할 필요 없이 
필요한 클래스에 Serializable 인터페이스를 구현함으로써 직렬화 할 수 있다.

 

 

하지만 자바 직렬화는 내부적으로 객체 직렬화를 위해 reflection을 수행한다.

 

 

Reflection은 런타임 중에 수행되며 처리를 위해 추가적인 객체를 다량으로 생성하고

이 과정에서 생성된 객체들은 직렬화가 끝난 뒤 GC 대상이 되기 때문에 CPU의 부하로 인한 성능 저하로 이어진다.

 

 

 

 

Parcelable

안드로이드 SDK에서 제공하는 직렬화 인터페이스이다.

 

 

Parcelable 인터페이스는 구현을 위해 직렬화 및 역직렬화 처리에 대한 코드를 명시적으로 작성해야 하기 때문에

Serializable과 달리 Reflection 과정을 거치지 않아 성능상의 이점이 있다.

 

하지만 Parcelable을 통한 직렬화 구현 시 작성한 메서드를

클래스 변경에 따라 수정해야하기 때문에 유지보수 측면에서 단점이 있다.

 

 

 

이 두 직렬화 메커니즘에 대한 대안으로 Parcelize가 있다.

 

 

 

 

Parcelize

코틀린에서 제공하는 컴파일러 플러그인으로 Parcelable 구현을 자동으로 생성하여 보일러 플레이트 코드를 줄이고 코드를 보다 간결하게 만들어 준다. 또한 런타임 오류 발생 가능성이 낮다.

 

 

plugins {
    id("kotlin-parcelize")
}

 

Parcelize 플러그인을 적용하기 위해 우선 build.gradle에 kotlin-parcelize 플러그인을 추가해준다.

 

 

그 다음 직렬화를 구현하고자 하는 클래스에 @Parcelize 어노테이션을 추가하고 Serializable 인터페이스 대신 Parcelable 인터페이스를 구현한다. Parcelable 객체지만 별다른 메서드를 작성하지 않아도 된다.

 

다른 프래그먼트로 값을 전달할 때 Bundle 객체에 Serializable 객체가 아닌 Parcelable 객체를 담아 전달한다.

 

 

전달받은 객체도 Parcelable 형태로 받아 사용한다.

 

 

Parcelize 플러그인 적용 시 주의할 점

- kotlin 컴파일러 지원을 필요로해서 kotlin 플러그인을 사용하는 환경에서만 작동
- 특정 타입 사용 시의 제한
- 직렬화하려는 모든 속성이 기본 생성자에 포함되어 있어야 함

 

 

 

 

 

 

참고

https://medium.com/shdev/bundle%EA%B3%BC-serialization-bd4b29d59c

 

Bundle과 Serialization

ACP week 3-bundle & serialization

medium.com

 

 

 

 

 

 

 

728x90