Skip to content

4주차 - 너울/주연우 워크북 과제 제출#22

Merged
onebone merged 9 commits intoUMC-KWU:neouulfrom
Neouul:main
Apr 13, 2026
Merged

4주차 - 너울/주연우 워크북 과제 제출#22
onebone merged 9 commits intoUMC-KWU:neouulfrom
Neouul:main

Conversation

@Neouul
Copy link
Copy Markdown

@Neouul Neouul commented Apr 7, 2026

✅ 4주차 워크북 완료 🎉


🛠️ 트러블슈팅 (Troubleshooting)

문제 1️⃣

gson.fromJson(json, Product::class.java)로 역직렬화를 실패함

원인 분석

json 문자열을 List<Product> 형태로 역직렬화 해야하는 상황인데,
Product::class.java라고 쓰면 GSON은 이를 단일 객체 하나로 인식하려고 시도하기 때문

해결 방법

TypeToken을 사용하여 런타임에도 타입 정보를 유지하도록 함
val listType = object : TypeToken<List<Product>>() {}.type
val productList: List<Product> = Gson().fromJson(jsonString, listType)

문제 2️⃣

di 라이브러리를 도입하지 않아서 data source와 repository 사용을 어떻게 할지 고민함

원인 분석

di 라이브러리를 도입하지 않아서 구현체를 생성해줄 역할이 필요함

해결 방법

객체 생성을 담당할 컨테이너를 정의하고, 앱 전역에서 사용할 수 있게 등록함
class AppContainer(private val context: Context) {
    private val gson = Gson()
    private val productDataSource by lazy { ProductDataSourceImpl(context) }

    val productRepository: ProductRepository by lazy {
        ProductRepositoryImpl(productDataSource, gson)
    }
}
class MyApplication : Application() {
    lateinit var container: AppContainer

    override fun onCreate() {
        super.onCreate()
        container = AppContainer(this)
    }
}
<application
    android:name=".core.MyApplication"
    ... >

📌 커밋별 설명 (Commit Log)

Neouul added 9 commits April 7, 2026 15:38
- `savedStateInstance`가 null일 때만 `navController.setGraph`를 호출하도록 변경하여 액티비티 재생성 시 내비게이션 상태가 초기화되는 현상 방지
  - 화면 회전(Configuration Change)이 발생하면 액티비티가 파괴되었다가 다시 생성됨
  - 이때 savedInstanceState가 null이 아니게 됨
- Manifest에서 스플래쉬 화면 테마 수정
- 상품 데이터를 DataStore에 저장 및 불러오기를 하는 ProductDataSource를 구현
- DataStore를 Context의 확장 함수로 선언하여 싱글톤이면서 어디서든 접근 가능하도록 함
- `ProductRepositoryImpl`: DataStore의 JSON 데이터를 `Product` 모델 리스트로 변환하고 상품 정보를 업데이트하는 로직 추가
- `WishRepositoryImpl`: 위시리스트 상품 목록 조회, 추가 및 삭제 기능 구현
- `ProductDataSourceImpl` 수정: 데이터 부재 시 반환되는 기본값을 빈 JSON 배열 문자열("[]")로 변경
- Gson을 활용한 JSON 직렬화/역직렬화 로직 적용
- 수동 의존성 주입(Manual Dependency Injection)을 위한 `AppContainer` 클래스 추가
- `AppContainer`에서 `ProductRepository` 및 `WishRepository` 인스턴스를 lazy하게 생성하도록 구현
- `MyApplication` 클래스를 생성하여 `AppContainer`를 전역적으로 관리하도록 설정
- `AndroidManifest.xml`에 `MyApplication` 등록
- `ProductRepository`에 초기 데이터 설정(`initializeDataIfNeeded`) 및 데이터 업데이트 로직 구현
- `SplashActivity`에서 앱 실행 시 초기 mock 데이터 로드 로직 추가
- `HomeFragment`, `ShopFragment`, `WishFragment`를 UI 고정 데이터 방식에서 Repository의 Flow를 구독(Observe)하는 방식으로 전환
- `DetailFragment`에서 상품 상세 정보 로드 및 위시리스트 추가/삭제 기능 구현
- `ShopAdapter` 및 `ShopViewHolder`에 하트 아이콘 클릭 리스너 및 상태 변경 로직 추가
- RecyclerView 어댑터들에 `updateList` 메서드를 추가하여 실시간 데이터 갱신 처리
- `ShopFragment` 내 RecyclerView 로직을 `ShopTap0Fragment`로 이관하고 내부 `NavHostFragment` 도입
- `shop_nav_graph.xml`을 추가하여 '전체', 'Tops & T-Shirts', 'Shoes' 탭별 프래그먼트 정의
- `ShopFragment`에서 `TabLayout`의 선택 상태에 따라 `NavController`를 통한 화면 전환 로직 구현
- `ShopTap0Fragment`에서 상품 클릭 시 메인 `NavController`를 사용하여 상세 페이지로 이동하도록 수정
- `fragment_shop.xml`의 RecyclerView를 `FragmentContainerView`로 교체 및 UI 속성 정렬
- `FragmentExt.kt`에 Fragment에서 로딩 다이얼로그를 제어하기 위한 `showLoading`, `hideLoading` 확장 함수 추가
- `HomeFragment`의 상품 목록 조회 로직에 1초 가상 지연 및 로딩 다이얼로그 연동
- `DetailFragment`의 상품 상세 정보 로드 및 위시리스트 상태 변경 로직에 0.5초 가상 지연 및 로딩 다이얼로그 연동
Copy link
Copy Markdown
Contributor

@onebone onebone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너울 4주차 워크북 고생 많으셨습니다!! 워크북에서 요구한 비동기 처리와 DataStore 처리까지 잘 해주셨네요 👍 거기다 워크북에는 없었던 걸로 아는데 안드로이드 공식 문서에서 권장 아키텍처로 제시하는 패턴을 알맞게 잘 활용해주신 것 같아요!!

딱 한 가지 짚어보고 싶은 부분이 있는데요, ShopFragment에서 navigate()를 하면 백스택이 계속 쌓일 것 같아요. 탭 네비게이션은 보통 백스택이 쌓이는 걸 예상하지는 않을 것 같아서 launchSingleTop 같은 플래그를 설정해두는 것도 옵션일 것 같습니다~!

4주차 워크북 너무 잘해주셨고 다음 워크북도 기대하겠습니다!! 💪

@onebone onebone merged commit 345d28f into UMC-KWU:neouul Apr 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants