The document discusses an archetype architecture for modern Android app development. It introduces key concepts like view models, use cases, repositories, actions, and middleware to solve common architectural problems like navigation, dialogs, network requests, state management, and more. The architecture aims to provide better code organization, testability, and flexibility through abstraction layers and dependency injection. It is presented as an alternative to Google's Architecture Components that uses smaller abstractions to break problems into solvable pieces.
6. Problems every architecture need to solve
• Navigation
• Dialogs
• Network requests
• Restore state
• Services
• Lifecycle
• Activity result
• and more
11. Google endorses
• Kotlin - supported in Android Studio
• Dagger 2 - recommended DI tool for Android apps
• rxJava 2 - supported by Room ORM
• Arch components announced
• MVVM recommended
12. Archetype vs Architecture components
UI controller
(Activity/Fragment)
ViewModel
Repository
Data Source
XML Layout
View
14. Archetype vs Architecture components
UI Container
(Activity/Fragment)
View Model
Repository
Middleware
(Context)
Binding
Use case
(Interactor)
Action
XML Layout
View
17. Binding
• Generated from XML
//SomeFragment.kt
override fun onCreateView(
inflater: LayoutInflater?,
container: ViewGroup?,
state: Bundle?): View {
super.onCreateView(inflater, container, savedInstanceState)
binding = DataBindingUtil.inflate(inflater, layoutId, container, false)
…
}
18. ViewModel
• Transform data for View
• Fragment* set ViewModel in Binding
class LoginViewModel @Inject constructor(
viewModel: ViewModel,
loginState: LoginState,
resourceProvider: ResourceProvider,
loginUseCase: LoginUseCase
) :
ViewModel by viewModel,
LoginState by loginState,
ResourcesProvider by resourceProvider,
LoginComponent by loginUseCase {
…
}
19. UseCase
• Encapsulate Business logic
interface EnvironmentUseCase {
fun observeEnvironment(): Observable<EnvironmentModel>
}
class EnvironmentUseCaseImpl @Inject constructor(
val repo: EnvironmentRepo
) : EnvironmentUseCase {
override fun observeEnvironment()
= repo.observe().filterNonEmpty()
}
20. Repo
• Encapsulate Access to data
class FirebaseAuthModelRepo(
db: FirebaseDatabase
) : AuthModelRepo,
SingleValueRepo<AuthModel> by FirebaseSingleValueRepo(db, AUTH_MODEL)
interface AuthModelRepo
: SingleValueRepo<AuthModel> {
fun push(value: UserLoginModel) = LoginAction(value).asSingle()
}