Android MVVM architecture
In modern Android development, maintaining a clear, testable, and modular code base has become crucial. The architectural practice recommended by Google is to use the MVVM (Model-View-ViewModel) pattern, which is the embodiment of responsive programming ideas in Android application development. In this article, we will delve into the MVVM architecture and demonstrate how to implement it in an Android application through a simple example.
MVVM architecture overview
The MVVM architecture is divided into three core components:
- Model – represents the application’s data and business logic, such as network requests, database interactions, etc.
- View – Represents the UI components of the application, such as Activities and Fragments.
- ViewModel – Acts as an intermediary between View and Model. It processes the data obtained from the Model, making it suitable for View display, and also responds to the View’s user interaction.
Here are the responsibilities of each component:
Model
The Model contains the data processing portion of the application. Typically, a Model can be further divided into several parts:
- Repository : An API that provides data, which determines whether to obtain data from a local database or the network.
- Local Data Source : Such as SQLite database or Room.
- Remote Data Source : Such as Retrofit or other network request libraries.
View
View is the screen that the user sees and interacts with. In Android, it usually refers to Activity
or Fragment
. View is only responsible for displaying data and notifying ViewModel of user operations. It should be as “dumb” as possible and not contain any business logic.
ViewModel
ViewModel is the data provider of the UI. It does not request data directly, but manages data through Repository. ViewModel does not directly reference View, it notifies UI data changes through LiveData or other observer patterns.
Implement MVVM architecture
Let’s understand the implementation of MVVM by building a simple user list interface. We will use the following Jetpack components:
- LiveData
- ViewModel
- View Binding
Step 1: Configure dependencies
First, add the following dependencies to your build.gradle (Module: app)
file:
dependencies {
// ViewModel 和 LiveData
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
// View Binding
buildFeatures {
viewBinding true
}
}
Step 2: Create Model
// User.java
public class User {
private int id;
private String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
// Getters and setters
public int getId() {
return id;
}
public String getName() {
return name;
}
}
Step 3: Create ViewModel
// MainViewModel.java
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import java.util.Arrays;
import java.util.List;
public class MainViewModel extends ViewModel {
private MutableLiveData<List<User>> users = new MutableLiveData<>();
public MainViewModel() {
loadUsers();
}
public MutableLiveData<List<User>> getUsers() {
return users;
}
private void loadUsers() {
//
List<User> dummyUsers = Arrays.asList(new User(1, "Alice"), new User(2, "Bob"));
users.setValue(dummyUsers);
}
}
Step 4: Create View
exist activity_main.xml
:
<!-- activity_main.xml -->
<LinearLayout ...>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.kt
Use View Binding and ViewModel in :
// MainActivity.kt
package com.example.myapp;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import com.example.myapp.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private MainViewModel mainViewModel;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// View Binding
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// ViewModel
mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
// ViewModel
mainViewModel.getUsers().observe(this, users -> {
// 更新 UI
StringBuilder userInfo = new StringBuilder();
for (User user : users) {
userInfo.append(user.getName()).append("\n");
}
binding.textView.setText(userInfo.toString());
});
}
}
Remember, LiveData
the observation mode ensures that UI components are only updated when Activity
or Fragment
is active.
Step 5: Test your app
Now you can run your application and see TextView
the list of users displayed. This example is very basic, but it shows how to pass data from the ViewModel to the View without requiring the View to know the complexity of the data source.
in conclusion
MVVM is a powerful and flexible architectural pattern that promotes code separation and modularization. By leveraging LiveData and ViewModel, we can create reactive applications that handle lifecycle events and data management gracefully. In addition, the use of View Binding further simplifies the UI code, allowing us to avoid findViewById
cumbersomeness and reduce the chance of errors.
In actual development, you may also need to introduce other Jetpack components such as Data Binding, Room, and Navigation to further improve the efficiency and functionality of the application architecture.
I hope this blog can help you understand and start using the MVVM architecture to build your Android applications.