architecture-samples
A collection of samples to discuss and showcase different architectural tools and patterns for Android apps.
Top Related Projects
The Google I/O Android App
Samples for Android Architecture Components.
This is a sample app that is part of a series of blog posts I have written about how to architect an android application using Uncle Bob's clean architecture approach.
Do's and Don'ts for Android development, by Futurice developers
Architecture and code guidelines we use at ribot when developing for Android
A gardening app illustrating Android development best practices with migrating a View-based app to Jetpack Compose.
Quick Overview
The android/architecture-samples repository is a collection of samples demonstrating different architectural approaches to developing Android apps. It showcases various implementations of the same app using different architectural patterns and Android Jetpack libraries. This project serves as a reference for developers to understand and compare different app architectures.
Pros
- Provides multiple implementations of the same app, allowing easy comparison between different architectures
- Demonstrates best practices and modern Android development techniques
- Regularly updated to reflect the latest Android development trends and libraries
- Includes comprehensive documentation and explanations for each architecture
Cons
- May be overwhelming for beginners due to the variety of architectures presented
- Some older architecture samples might not reflect the most current Android development practices
- Focuses primarily on architecture, potentially overlooking other important aspects of app development
- Limited to a single app example, which may not cover all real-world scenarios
Code Examples
Here are a few code examples from the project, demonstrating different architectural approaches:
- ViewModel with LiveData (MVVM):
class TasksViewModel(
private val tasksRepository: TasksRepository
) : ViewModel() {
private val _items = MutableLiveData<List<Task>>().apply { value = emptyList() }
val items: LiveData<List<Task>> = _items
fun loadTasks(forceUpdate: Boolean = false) {
viewModelScope.launch {
val tasksResult = tasksRepository.getTasks(forceUpdate)
if (tasksResult is Success) {
_items.value = tasksResult.data
} else {
_items.value = emptyList()
}
}
}
}
- Compose UI implementation:
@Composable
fun TasksScreen(
viewModel: TasksViewModel,
modifier: Modifier = Modifier
) {
val tasks by viewModel.tasks.collectAsState(initial = emptyList())
LazyColumn(modifier = modifier) {
items(tasks) { task ->
TaskItem(
task = task,
onTaskClick = { viewModel.openTask(task.id) },
onCheckboxClick = { viewModel.completeTask(task, !task.isCompleted) }
)
}
}
}
- Repository pattern implementation:
class DefaultTasksRepository(
private val tasksRemoteDataSource: TasksDataSource,
private val tasksLocalDataSource: TasksDataSource,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) : TasksRepository {
override suspend fun getTasks(forceUpdate: Boolean): Result<List<Task>> {
if (forceUpdate) {
try {
updateTasksFromRemoteDataSource()
} catch (ex: Exception) {
return Result.Error(ex)
}
}
return tasksLocalDataSource.getTasks()
}
}
Getting Started
To get started with the android/architecture-samples project:
- Clone the repository:
git clone https://github.com/android/architecture-samples.git
- Open the project in Android Studio.
- Choose the desired sample from the different branches available.
- Build and run the app on an emulator or physical device.
For more detailed instructions and explanations of each architecture, refer to the project's README and documentation.
Competitor Comparisons
The Google I/O Android App
Pros of iosched
- Real-world application: iosched is a fully functional app used for Google I/O, providing a comprehensive example of app architecture and features
- Extensive use of Jetpack libraries: Demonstrates implementation of various Jetpack components in a production environment
- Multi-module architecture: Showcases a modular app structure, promoting better separation of concerns and reusability
Cons of iosched
- Complexity: The large-scale nature of the app may be overwhelming for beginners or those looking for simpler examples
- Specific use case: Being tailored for a conference app, some features might not be directly applicable to other types of applications
- Frequent updates: Regular changes to match the latest Google I/O event can make it challenging to follow long-term
Code Comparison
iosched (Kotlin):
@Composable
fun SessionItem(
session: Session,
onSessionClick: (String) -> Unit,
modifier: Modifier = Modifier
) {
// Session item implementation
}
architecture-samples (Kotlin):
@Composable
fun TaskItem(
task: Task,
onCheckboxClicked: (Task, Boolean) -> Unit,
onTaskClicked: (Task) -> Unit
) {
// Task item implementation
}
Both repositories use Jetpack Compose for UI, but iosched tends to have more complex composables due to its larger scope and feature set.
Samples for Android Architecture Components.
Pros of architecture-components-samples
- Focuses specifically on Architecture Components, providing more in-depth examples
- Includes a wider variety of sample apps demonstrating different use cases
- More frequently updated with the latest Android development practices
Cons of architecture-components-samples
- May be overwhelming for beginners due to the large number of samples
- Less emphasis on overall app architecture patterns compared to architecture-samples
- Some samples may be more complex than necessary for learning basic concepts
Code Comparison
architecture-components-samples:
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAll(): List<User>
@Insert
fun insertAll(vararg users: User)
}
architecture-samples:
@Dao
interface TasksDao {
@Query("SELECT * FROM Tasks")
fun getTasks(): LiveData<List<Task>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertTask(task: Task)
}
Both repositories demonstrate similar DAO (Data Access Object) implementations, but architecture-components-samples tends to showcase more specific use cases of Architecture Components, while architecture-samples focuses on integrating these components into a complete app architecture.
This is a sample app that is part of a series of blog posts I have written about how to architect an android application using Uncle Bob's clean architecture approach.
Pros of Android-CleanArchitecture
- Focuses on implementing Clean Architecture principles, promoting better separation of concerns
- Provides a more detailed example of dependency injection using Dagger
- Demonstrates advanced testing techniques, including integration and end-to-end tests
Cons of Android-CleanArchitecture
- Less frequently updated compared to architecture-samples
- May be more complex for beginners to understand and implement
- Fewer architecture variants showcased
Code Comparison
Android-CleanArchitecture:
class GetUserDetails @Inject constructor(
private val userRepository: UserRepository
) : UseCase<GetUserDetails.Params, UserDetails>() {
override suspend fun run(params: Params) = userRepository.getUserDetails(params.userId)
data class Params(val userId: Int)
}
architecture-samples:
@Inject
class GetTaskUseCase @Inject constructor(
private val tasksRepository: TasksRepository
) {
suspend operator fun invoke(taskId: String): Result<Task> {
return tasksRepository.getTask(taskId)
}
}
Both repositories demonstrate the implementation of use cases, but Android-CleanArchitecture uses a more generic approach with a base UseCase
class, while architecture-samples opts for a simpler, more direct implementation.
Do's and Don'ts for Android development, by Futurice developers
Pros of android-best-practices
- Provides a comprehensive guide covering various aspects of Android development
- Offers practical tips and best practices for real-world scenarios
- Regularly updated with community contributions
Cons of android-best-practices
- Less focused on specific architectural patterns
- Lacks detailed code examples for complex implementations
- May not cover the latest Android features as extensively
Code Comparison
architecture-samples:
class TasksViewModel @Inject constructor(
private val tasksRepository: TasksRepository
) : ViewModel() {
private val _items = MutableLiveData<List<Task>>().apply { value = emptyList() }
val items: LiveData<List<Task>> = _items
}
android-best-practices:
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
}
}
The architecture-samples repository focuses on demonstrating different architectural patterns with detailed implementations, while android-best-practices provides general guidelines and best practices for Android development. The code examples reflect this difference, with architecture-samples showcasing a ViewModel implementation using Kotlin and Dependency Injection, and android-best-practices presenting a basic Activity structure in Java.
Architecture and code guidelines we use at ribot when developing for Android
Pros of android-guidelines
- More comprehensive coverage of Android development best practices
- Includes guidelines for project structure, code style, and architecture
- Provides detailed explanations and rationale for each guideline
Cons of android-guidelines
- Less focused on specific architectural patterns
- May not be as up-to-date with the latest Android development trends
- Lacks concrete code examples for some guidelines
Code Comparison
architecture-samples:
class TasksViewModel @Inject constructor(
private val tasksRepository: TasksRepository
) : ViewModel() {
private val _items = MutableLiveData<List<Task>>().apply { value = emptyList() }
val items: LiveData<List<Task>> = _items
}
android-guidelines:
public class UserPresenter extends BasePresenter<UserMvpView> {
@Inject
public UserPresenter(DataManager dataManager) {
mDataManager = dataManager;
}
}
The architecture-samples repository focuses on demonstrating various architectural patterns using Kotlin and modern Android development practices. It provides multiple sample implementations of the same app using different architectures.
On the other hand, android-guidelines offers a broader set of guidelines covering various aspects of Android development, including project structure, coding style, and architectural considerations. It aims to provide a comprehensive guide for Android developers to follow best practices.
While both repositories are valuable resources for Android developers, they serve different purposes. architecture-samples is more hands-on with concrete implementations, while android-guidelines provides a broader set of recommendations for overall Android development practices.
A gardening app illustrating Android development best practices with migrating a View-based app to Jetpack Compose.
Pros of Sunflower
- Demonstrates modern Android development practices with Jetpack Compose
- Includes more advanced features like data binding and WorkManager
- Offers a more complete and realistic app example
Cons of Sunflower
- May be more complex for beginners to understand
- Focuses primarily on Jetpack Compose, which might not be suitable for all projects
- Less variety in architectural approaches compared to Architecture Samples
Code Comparison
Sunflower (Jetpack Compose):
@Composable
fun PlantListItem(plant: Plant, onClick: () -> Unit) {
Surface(
shape = MaterialTheme.shapes.medium,
modifier = Modifier
.padding(horizontal = 16.dp, vertical = 8.dp)
.clickable(onClick = onClick)
) {
// Item content
}
}
Architecture Samples (XML-based layout):
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="task" type="com.example.android.architecture.blueprints.todoapp.data.Task" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Item content -->
</LinearLayout>
</layout>
The code comparison highlights the difference between Jetpack Compose's declarative UI approach in Sunflower and the traditional XML-based layouts used in Architecture Samples.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Android Architecture Samples
These samples showcase different architectural approaches to developing Android apps. In its different branches you'll find the same app (a TODO app) implemented with small differences.
In this branch you'll find:
- User Interface built with Jetpack Compose
- A single-activity architecture, using Navigation Compose.
- A presentation layer that contains a Compose screen (View) and a ViewModel per screen (or feature).
- Reactive UIs using Flow and coroutines for asynchronous operations.
- A data layer with a repository and two data sources (local using Room and a fake remote).
- Two product flavors,
mock
andprod
, to ease development and testing. - A collection of unit, integration and e2e tests, including "shared" tests that can be run on emulator/device.
- Dependency injection using Hilt.
Variations
This project hosts each sample app in separate repository branches. For more information, see the README.md
file in each branch.
Stable samples - Kotlin
Sample | Description |
---|---|
main | This branch |
service-locator | A simple setup that removes Hilt in favor of a service locator |
livedata | Uses LiveData instead of StateFlow as the data stream solution |
usecases | Adds a new domain layer that uses UseCases for business logic (not using Compose yet) |
views | Uses Views instead of Jetpack Compose to render UI elements on the screen |
views-hilt | Uses Views and Hilt instead together |
Screenshots
Why a to-do app?
The app in this project aims to be simple enough that you can understand it quickly, but complex enough to showcase difficult design decisions and testing scenarios. For more information, see the app's specification.
What is it not?
- A template. Check out the Architecture Templates instead.
- A UI/Material Design sample. The interface of the app is deliberately kept simple to focus on architecture. Check out the Compose Samples instead.
- A complete Jetpack sample covering all libraries. Check out Android Sunflower or the advanced GitHub Browser Sample instead.
- A real production app with network access, user authentication, etc. Check out the Now in Android app instead.
Who is it for?
- Intermediate developers and beginners looking for a way to structure their app in a testable and maintainable way.
- Advanced developers looking for quick reference.
Opening a sample in Android Studio
To open one of the samples in Android Studio, begin by checking out one of the sample branches, and then open the root directory in Android Studio. The following series of steps illustrate how to open the usecases sample.
Clone the repository:
git clone git@github.com:android/architecture-samples.git
This step checks out the master branch. If you want to change to a different sample:
git checkout usecases
Note: To review a different sample, replace usecases
with the name of sample you want to check out.
Finally open the architecture-samples/
directory in Android Studio.
License
Copyright 2022 Google, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
Top Related Projects
The Google I/O Android App
Samples for Android Architecture Components.
This is a sample app that is part of a series of blog posts I have written about how to architect an android application using Uncle Bob's clean architecture approach.
Do's and Don'ts for Android development, by Futurice developers
Architecture and code guidelines we use at ribot when developing for Android
A gardening app illustrating Android development best practices with migrating a View-based app to Jetpack Compose.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot