π App Introduction: News reader app with personalized content delivery and offline storage capability
π Duration: March 15, 2021 ~ June 30, 2021 (3.5 months)
π± Platform: Native Android app
π’ Company: Desoft (Cubaβs national software development company)
π₯ Team Size: 1 developer
πΌ Role: UI/UX design and complete Android app development
π οΈ Key Technologies: Android
Kotlin
Coroutines
MVVM
Room
Retrofit
Moshi
Navigation
Material Design
Glide
Lottie
ViewBinding
π GitHub: daehan-lim/cubadebate-app
βββ database/ # Local database related classes
β βββ CubadebateDatabase.kt # Room database main class
β βββ converters/ # Data type converters
β βββ dao/ # Data access objects
β β βββ PostDao.kt # Post-related data access
β β βββ RecentCategoryDao.kt # Recent category data access
β β βββ TagDao.kt # Tag-related data access
β βββ model/ # Database entity models
β βββ post/ # Post-related entities
β β βββ DatabasePost.kt # Post main entity
β β βββ DatabaseCategory.kt # Category entity
β β βββ ...(other post entities)
β βββ savedpost/ # Saved post entities
β β βββ SavedPost.kt # Saved post main entity
β β βββ SavedCategory.kt # Saved post category
β β βββ ...(other saved post entities)
β βββ ...(other entities)
β
βββ model/ # Data model classes
β βββ api/ # API response models
β β βββ comment/ # Comment API models
β β β βββ Content.kt # Comment content
β β β βββ ResponseComment.kt # Comment response model
β β βββ post/ # Post API models
β β β βββ NetworkPost.kt # Network post model
β β β βββ ...(other API models)
β βββ categories/ # Category-related models
β β βββ MyCategoriesGridViewItem.kt
β βββ comment/ # Comment domain models
β β βββ Comment.kt # Comment information
β βββ post/ # Post domain models
β βββ Post.kt # Post main model
β βββ Category.kt # Category model
β βββ ...(other post models)
β
βββ network/ # Network communication classes
β βββ CubadebateApiService.kt # Retrofit API service interface
β
βββ repository/ # Data repository (Repository pattern)
β βββ PostRepository.kt # Post data management
β βββ RecentCategoryRepository.kt # Recent category data management
β βββ TagRepository.kt # Tag data management
β
βββ ui/ # User interface classes
β βββ CoroutineBaseViewModel.kt # Coroutine-based base view model
β βββ PostsViewModel.kt # Common post view model
β βββ HeadingsAdapter.kt # Post list adapter
β βββ EndlessRecyclerViewScrollListener.kt # Infinite scroll listener
β βββ main/ # Main screen classes
β β βββ MainActivity.kt # Main activity
β β βββ MainActivityViewModel.kt # Main activity view model
β βββ categories/ # Category screens
β β βββ BaseCategoryFragment.kt # Category base fragment
β β βββ HomeFragment.kt # Home fragment
β βββ details/ # Post detail screen
β βββ comments/ # Comment-related screens
β β βββ CommentsActivity.kt # Comments activity
β β βββ CommentsFragment.kt # Comments fragment
β β βββ RepliesFragment.kt # Comment replies fragment
β β βββ ...(ViewModels and other classes)
β βββ search/ # Search screens
β βββ saved/ # Saved posts screen
β βββ forme/ # Personalized recommendation screen
β β βββ ForMeFragment.kt # Recommendation main fragment
β β βββ MyCategoriesFragment.kt # My categories fragment
β β βββ MyTopicsFragment.kt # My topics fragment
β β βββ ...(ViewModels and other classes)
β β
β βββ headingspertag/ # Posts by tag screen
β βββ subscription/ # Subscription screens
β βββ settings/ # Settings screens
β βββ categories/ # Category management
β βββ topics/ # Topic management
β
βββ util/ # Utility classes and helper functions
βββ ActivityUtils.kt # Activity utilities
βββ BindingUtils.kt # Data binding utilities
βββ MappingUtils.kt # Data mapping utilities
βββ PostUtils.kt # Post utilities
βββ PreferenceManager.kt # Settings management utilities
βββ Util.kt # General utility functions
1. Offline Storage Architecture Selection
Requirements
Users needed reliable offline access to news articles even in unstable network environments
Decision
Implemented robust offline storage using Room Database
@Entity(tableName = "posts")
data class DatabasePost(
@PrimaryKey val id: Long,
val title: String,
val content: String,
val imageUrl: String?,
val publishedDate: String,
val isSaved: Boolean = false
)
2. MVVM Architecture Implementation
Requirements
Needed systematic management of complex news data flows and UI states while efficiently integrating network and local data sources
Decision
Built layered architecture combining MVVM
with Repository
pattern
class PostRepository(private val database: CubadebateDatabase) {
suspend fun getPosts(categoryId: Long?): MutableList<Post> {
return withContext(Dispatchers.IO) {
try {
// Attempt to fetch latest data from network
val networkPosts = when(categoryId) {
null -> CubadebateApi.retrofitService.getPostsAsync()
else -> CubadebateApi.retrofitService.getPostsByCategoryAsync(categoryId)
}.await()
// Save to local DB and return
networkPosts.map { it.mapToPost() }
} catch (e: Exception) {
// Return local data on network failure
getPostsFromDb(categoryId)
}
}
}
}
1. User-Centric Content Discovery Enhancement
Problem
Users found it difficult to freely explore or subscribe to news on topics of interest through the existing website, with no way to customize content based on user preferences
RecyclerView
and Room Database
to aggregate news from user-selected topics