Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Serializable / Parcelableとの上手な付き合い方
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
kobaken
April 24, 2025
Technology
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Serializable / Parcelableとの上手な付き合い方
2025年4月24日(木)開催のpixiv App Nightで発表した資料です。
kobaken
April 24, 2025
More Decks by kobaken
See All by kobaken
複数行のTextで中間省略(…)を実現する
kobaken0029
0
69
Jetpack Compose Preview実践ガイド
kobaken0029
0
140
Kotlinの好きなところ
kobaken0029
0
1.3k
Compose駆動開発のためのマルチモジュール化
kobaken0029
0
260
DataStoreを導入してみた
kobaken0029
1
390
Epoxyを用いたレイアウト構築術
kobaken0029
1
260
Androidエンジニアが1週間でiOSアプリ開発を学び、1ヶ月で大規模アプリ開発にJOINした話
kobaken0029
0
3.8k
Modern REST Communicate for Android
kobaken0029
0
1.6k
AndroidでモダンREST通信してみたった
kobaken0029
0
270
Other Decks in Technology
See All in Technology
AIネイティブな開発のサプライチェーンリスク対策 〜激動の開発現場でリスクに立ち向かう〜【ZennFes】
cscengineer
PRO
2
110
AGENTS.mdとSkillsで始めるAIエージェント活用
sonoda_mj
3
210
AIはどのように 組織のアジリティを変えるのか?
junki
2
650
Bucharest Tech Week 2026 - Reinventing testing practices in the AI era
edeandrea
PRO
1
150
小さくはじめるSLI/SLO ~育てながら組織に定着させる実践知~ / Starting Small with SLI/SLOs: Building Adoption Through Continuous Growth
nari_ex
7
1.9k
AmazonRoute 53ではじめてのドメイン取得!HTTPS化までの道のりを整理してみた
usanchuu
3
140
2026TECHFRESH畢業分享會 - Lightning Talk - 資料也要 CI/CD? 用 Airbyte 自動化資料同步
line_developers_tw
PRO
0
910
2026TECHFRESH畢業分享會 - Lightning Talk - E起 See See : 電商推薦讀心術? 數據說了算
line_developers_tw
PRO
0
920
AAIFに入ってみた ~内から見えるコミュニティ動向~
sato4
0
190
チームで進めるAI駆動アジャイル×ウォーターフォール
kumaiu
0
160
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
930
LLMにもCAP定理があるという話
harukasakihara
0
320
Featured
See All Featured
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
140
How to Talk to Developers About Accessibility
jct
2
230
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
Statistics for Hackers
jakevdp
799
230k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
Practical Orchestrator
shlominoach
191
11k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
Technical Leadership for Architectural Decision Making
baasie
3
400
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
270
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Into the Great Unknown - MozCon
thekraken
41
2.6k
Transcript
Serializable / Parcelableとの 上手な付き合い方 @kobaken
Index • Serializable / Parcelableとは • pixivコミックで問題になった事象 • なぜ発生してしまったのか •
今後の運用方針 • まとめ 2
Serializable / Parcelable 3
4 https://developer.android.com/develop/ui/views/touch-and-input/stylus-input/ink-api-state-preservation
5 https://developer.android.com/develop/ui/views/touch-and-input/stylus-input/ink-api-state-preservation
6 🤔💭
Serializable / Parcelableとは • オブジェクトを直列化するためのinterface ◦ オブジェクトをバイト列に変換(シリアライズ)、復元(デシリアライズ)する処理 • ActivityやFragment, Serviceなどのコンポーネント間のデータ受け渡し(画面遷移
など)や永続化などの際に利用されることが多い 7
Serializable 8 Java標準のシリアライズ機構 ※Kotlin Serializationの@Serializableではないです Pros • Serializableと追加するだけなので実装が容易 • Javaの実行環境であれば動作する
Cons • シリアライズ/デシリアライズの処理速度が 遅い • メモリ消費量が大きい import java.io.Serializable data class Hoge( val fuga: String, val piyo: Int, ) : Serializable
Parcelable 9 AndroidのParcel機構 メモリ上で効率的にデータをやり取りするために設 計されている Pros • シリアライズ/デシリアライズの処理速度が速い • メモリ効率が良い
Cons • 実装がやや複雑で面倒 • 永続化には向かない import android.os.Parcelable data class Hoge( val fuga: String, val piyo: Int, ) : Parcelable { constructor(parcel: Parcel): this( parcel.readString() ?: "", parcel.readInt(), ) override fun writeToParcel(dest: Parcel?, flags: Int) { if (dst != null) { dest.writeString(fuga) dest.writeInt(piyo) } } override fun describeContents() = 0 companion object CREATOR : Parcelable.Creator<Hoge> { override fun createFromParcel(parcel: Parcel) = Hoge(parcel) override fun newArray(size: Int): Array<Hoge?> = arrayOfNulls(size) } }
Parcelable 10 AndroidのParcel機構 メモリ上で効率的にデータをやり取りするために設 計されている Pros • シリアライズ/デシリアライズの処理速度が速い • メモリ効率が良い
Cons • 実装がやや複雑で面倒 • 永続化には向かない import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize data class Hoge( val fuga: String, val piyo: Int, ) : Parcelable kotlin-parcelize @Parcelizeで おk
問題になった事象 11
前提 • pixivコミック Androidアプリでは画面遷移をActivity.startActivityで行っている • マルチモジュール化を進行中 ◦ 大半の実装がappモジュール内にまとまったままになっている 12
問題になった事象 • 画面遷移時にBundleからデータを取得する箇所でクラッシュが発生💣💥 13
問題になった事象 • 画面遷移時にBundleからデータを取得する箇所でクラッシュが発生💣💥 解決策 • Serializableにロールバックした ◦ 早急な対応のため、手数が少なく、動作の実績がある元実装に戻した 14
なぜ発生したのか • 対応するclassをSerializable->Parcelableに置き換えていたが、Bundleから取り出 す処理をSerializable時代のままにしていた • pixivコミック Androidチームでは変更箇所の動作確認をリリース前に行なっている • 当時改修対象だった機能の動作も問題なかった ◦
影響範囲の調査不足(影響範囲が広い実装の変更だった) 15
今後の運用方針 16
今後の運用方針 • 新規実装ではParcelableを使用する ◦ @Parcelizeを活用する • 役割を明確にするため、画面遷移に利用するデータはドメインモデルとは別に定義 ◦ 便宜上、ナビゲーションモデルと呼ぶ ◦
ナビゲーションモデルはnavigationモジュールに配置する ◦ ナビゲーションモデル<-->ドメインモデルの変換ロジックもnavigationモジュールに配置する 17
Parcelableに変えていく理由 • IntentやBundleのListの扱いがSerializableよりParcelableが型安全 • Serializableよりパフォーマンス面に優れているParcelableを利用 18
Listの扱いが型安全 19 • Listの型を指定して型安全に取得可能 • Serializableの場合は自分でキャスト data class Hoge( val
fuga: String, val piyo: Int, ) : Parcelable // IntentからHogeのArrayListを取得 IntentCompat.getParcelableArrayListExtra( /* in = */ intent, /* key = */ “hoge”, /* clazz = */ Hoge::class.java ) // SerializableはList専用の口がないのでキャストする IntentCompat.getSerializableExtra( /* in = */ data, /* key = */ “hoge”, /* clazz = */ ArrayList::class.java ) as? ArrayList<Hoge>
Serializable vs Parcelable Serizliable • Java • 実装が楽 • 処理速度が遅め
• メモリ消費大 20 Parcelable • Android固有 • 実装が面倒(プラグインで自動生成が可能) • 処理速度が速め • メモリ消費小
Serializableと比較してParcelableがパフォーマンス優勢な理由 • リフレクションしていない ◦ writeToParcelで明示的に書き出す対象を指定するので解析の手間がなく、実行時の処理が速い • writeString, readString などの専用メソッドにより効率化 ◦
余計なGCのオーバーヘッドを削減 • Parcelの内部実装で最適化が行われている ◦ メモリマッピングなど • オブジェクトの循環参照を回避している ◦ 循環参照が発生する可能性がある場合、IDを利用して既にデシリアライズされたものを再利用したり、呼 び出された時に参照を解決したりして解決できる 21
モデルの相互変換 22 • それぞれのプロパティに1対1対応す るシンプルな変換 ◦ 遷移元->toNavigationModel ◦ 遷移先->toModel •
kotlin-fill-classというプラグインを 活用すると効率UP ◦ https://plugins.jetbrains.com/plugin/1094 2-kotlin-fill-class // core/data/model/~/Hoge.kt data class Hoge( val fuga: String, val piyo: Int, ) // core/navigation/~/model/Hoge.kt data class Hoge( val fuga: String, val piyo: Int, ) : Parcelable // core/navigation/~/model/converter/DoM2NaviM.kt fun Hoge.toNavigationModel() = hoge.sample.core.navigation.model.Hoge( fuga = fuga, piyo = piyo, ) // core/navigation/~/model/converter/NaviM2DoM.kt fun Hoge.toModel() = hoge.sample.core.data.model.Hoge( fuga = fuga, piyo = piyo, )
まとめ 23
まとめ • ActivityやFragment間のデータ受け渡しはSerializableよりParcelableが優秀 ◦ シリアライズの速度やメモリ効率もParcelableに軍配があがる ◦ ただし、永続化に使うのは避けること • @Parcelizeを活用すべし ◦
kotlin-parcelizeを導入しよう ◦ ボイラープレートを自動生成してくれて便利 • 役割ごとに型を分けて影響範囲を明確にする ◦ 今回は画面遷移時に引き渡されるパラメータとしてナビゲーションモデルを定義した ◦ ナビゲーションモデルはBundleに格納・取出することに集中する ◦ 遷移先でドメインモデルとして振る舞えるように相互変換を実装する 24
参考文献 • https://developer.android.com/kotlin/parcelize?hl=ja#skip_properties_from _serialization • https://developer.android.com/privacy-and-security/risks/unsafe-deserializ ation • https://outcomeschool.com/blog/parcelable-vs-serializable •
https://mixi-inc.github.io/AndroidTraining/fundamentals/2.07.serialize-and- collection-and-perpetuation.html#直列化 • Gemini Advanced 2.0 Flash 25