{"id":2202,"date":"2026-02-27T17:41:10","date_gmt":"2026-02-27T23:41:10","guid":{"rendered":"https:\/\/www.yoonhuh.com\/blog\/?p=2202"},"modified":"2026-03-02T01:00:58","modified_gmt":"2026-03-02T07:00:58","slug":"rpg-character-directory-android-project-showcasing-moshi-deserialization-stateflow-and-jetpack-compose","status":"publish","type":"post","link":"https:\/\/www.yoonhuh.com\/blog\/rpg-character-directory-android-project-showcasing-moshi-deserialization-stateflow-and-jetpack-compose\/","title":{"rendered":"RPG Character Directory: Android Project Showcasing Moshi Deserialization, StateFlow, and Jetpack Compose"},"content":{"rendered":"<p data-start=\"724\" data-end=\"1123\">I recently put together a new proof-of-concept Android project on GitHub called <a href=\"https:\/\/github.com\/huhx0015\/RPGCharacterDirectory\"><strong data-start=\"804\" data-end=\"831\">RPG Character Directory<\/strong><\/a>. The project was created to further explore using <a href=\"https:\/\/github.com\/square\/moshi\"><strong data-start=\"882\" data-end=\"891\">Moshi<\/strong><\/a> to deserialize JSON strings into data objects, along with <a href=\"https:\/\/developer.android.com\/kotlin\/flow\/stateflow-and-sharedflow\"><strong data-start=\"950\" data-end=\"963\">StateFlow<\/strong><\/a> for handling reactive updates from the data repository layer and surfacing them to the view layer. It also uses <a href=\"https:\/\/developer.android.com\/develop\/ui\"><strong data-start=\"1076\" data-end=\"1095\">Jetpack Compose<\/strong><\/a> to build and render the UI.<\/p>\n<p data-start=\"1125\" data-end=\"1220\">The project follows an <strong data-start=\"1148\" data-end=\"1169\">MVVM architecture<\/strong> and adopts a <a href=\"https:\/\/proandroiddev.com\/android-unidirectional-data-flow-local-unit-testing-487a6e6f5c9\"><strong data-start=\"1183\" data-end=\"1211\">unidirectional data flow<\/strong><\/a> pattern.<\/p>\n<p data-start=\"1222\" data-end=\"1353\">You can find the full source code on GitHub here:<br data-start=\"1301\" data-end=\"1304\"\/><a class=\"decorated-link\" href=\"https:\/\/github.com\/huhx0015\/RPGCharacterDirectory\" target=\"_new\" rel=\"noopener\" data-start=\"1304\" data-end=\"1353\">https:\/\/github.com\/huhx0015\/RPGCharacterDirectory<\/a><\/p>\n<div style=\"width: 800px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-2202-1\" width=\"800\" height=\"1792\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/www.yoonhuh.com\/blog\/wp-content\/uploads\/2026\/02\/RPGCharacterDirectory_Demo.mp4?_=1\" \/><a href=\"https:\/\/www.yoonhuh.com\/blog\/wp-content\/uploads\/2026\/02\/RPGCharacterDirectory_Demo.mp4\">https:\/\/www.yoonhuh.com\/blog\/wp-content\/uploads\/2026\/02\/RPGCharacterDirectory_Demo.mp4<\/a><\/video><\/div>\n","protected":false},"excerpt":{"rendered":"<p>I recently put together a new proof-of-concept Android project on GitHub called RPG Character Directory. The project was created to further explore using Moshi to deserialize JSON strings into data objects, along with StateFlow for handling reactive updates from the data repository layer and surfacing them to the view layer.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[534],"tags":[28,473,560,572,536,573],"class_list":["post-2202","post","type-post","status-publish","format-standard","hentry","category-coding","tag-android","tag-android-development","tag-kotlin","tag-moshi","tag-mvvm","tag-stateflow"],"_links":{"self":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts\/2202","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/comments?post=2202"}],"version-history":[{"count":5,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts\/2202\/revisions"}],"predecessor-version":[{"id":2210,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/posts\/2202\/revisions\/2210"}],"wp:attachment":[{"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/media?parent=2202"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/categories?post=2202"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yoonhuh.com\/blog\/wp-json\/wp\/v2\/tags?post=2202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}