Livedata, ViewModel, Retrofit Android Architecture Component
MVVM is one of the architectural patterns which enhances separation of concerns, and it allows separating the user interface logic from the business logic. Its target is to achieve Keeping UI code free and straightforward of app logic to make it easier to manage.
MVVM has mainly divided into three parts:
Model —
A model represents the data and business logic of the app. One of the recommended implementations of this is to expose its data through observable. Unlike a regular observable, LiveData respects the lifecycle of other app components, such as activities and fragments. We are using LiveData in Repository class that are listed below.
Since LiveData respects Android Lifecycle, this means it will not invoke its observer callback unless activity or fragment is in received onStart() but did not accept onStop() Adding to this, LiveData will also automatically remove the observer when its host receives onDestroy()
ViewModel —
ViewModel interacts with model and also prepares observable that can be observed by a View. One of the essential implementation strategies of this layer is to decouple it from the View. ViewModel should not be aware of the view which is interacting. ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations. We are using ViewModel in HeadLineViewModel class that are listed below.

View —
The view role in this pattern is to observe a ViewModel observable to get data to update UI elements accordingly. This part is implemented in our MainActivity class where we are observing data from ViewModel and set observed data on the adapter.
Here i am tried to explain about android architecture component LiveData, ViewModel with Retrofit2. In this post, I am simply hit an API using Retrofit and show data on activity using RecyclerView.
1- Add Dependency in build.gradle file these are the required dependency for using LiveData, ViewModel and Retrofit
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'android.arch.lifecycle:extensions:1.1.1'
2- Model class for API response
public class NewsResponse {
@SerializedName("status")
@Expose
private String status;
@SerializedName("totalResults")
@Expose
private Integer totalResults;
@SerializedName("articles")
@Expose
private List<Article> articles = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getTotalResults() {
return totalResults;
}
public void setTotalResults(Integer totalResults) {
this.totalResults = totalResults;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
3- Implement Retrofit part
public interface APIRequest{
@GET("v2/top-headlines")
Call<NewsResponse> getHeadLine(@Query("country") String country,
@Query("apikey") String apiKey);
}—
public class RetrofitRequest{addConverterFactory(GsonConverterFactory.create()
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com")
.
.build();
}
4- Make a Repository class- This class provide Singleton network request for hitting API and using LiveData for observing api response. LiveData is an observable data holder class. Unlike a regular observable, LiveData respects the lifecycle of other app components, such as activities and fragments.
public class HeadLineRepository {private APIService apiService;
private static class SingletonHelper
{
private static final HeadLineRepository INSTANCE = new HeadLineRepository();
}
public static HeadLineRepository getInstance()
{
return SingletonHelper.INSTANCE;
}
public HeadLineRepository()
{
apiService=RetrofitRequest.createService(APIRequest.class);
}
public LiveData<NewsResponse> getHeadLine(String country,
String key)
{
final MutableLiveData<NewsResponse> data = new MutableLiveData<>();
apiService.getHeadLine(country, key)
.enqueue(new Callback<NewsResponse>()
{
@Override
public void onResponse(Call<NewsResponse> call, Response<NewsResponse> response)
{
if (response.isSuccessful())
{
data.setValue(response.body());
}
}
@Override
public void onFailure(Call<NewsResponse> call, Throwable t) {
data.setValue(null);
}
});
return data;
}
}
5- Make a ViewModel class — The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
public class HeadLineViewModel extends AndroidViewModel {
private static final MutableLiveData MUTABLE_LIVE_DATA = new MutableLiveData();
{
MUTABLE_LIVE_DATA.setValue(null);
}
public final ObservableField<NewsResponse> project = new ObservableField<>();
public HeadLineViewModel(@NonNull HeadLineRepository headLineRepository,
@NonNull Application application)
{super(application);
newsResponseObservable = HeadLineRepository.getInstance()
.getHeadLine("in","84a7decf3110498ea372bd16dd0601e8");
}
public LiveData<NewsResponse> getNewsResponseObservable()
{
return newsResponseObservable;
}
}
6- MainActivity class where we use ViewModel for observing data
public class MainActivity extends AppCompatActivity
{
ArrayList<Article> articleArrayList = new ArrayList<>();
HeadLineAdapter headLineAdapter;
RecyclerView rvHeadline;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rvHeadline = findViewById(R.id.rvHeadline);
setupRecyclerView();
final HeadLineViewModel viewModel = ViewModelProviders
.of(this).get(HeadLineViewModel.class);
}
private void setupRecyclerView()
{
layoutManager = new LinearLayoutManager
(this, LinearLayoutManager.VERTICAL,false);
if (headLineAdapter == null)
{
headLineAdapter = new
HeadLineAdapter(articleArrayList, this);
rvHeadline.setLayoutManager(layoutManager);
rvHeadline.setAdapter(headLineAdapter);
rvHeadline.setItemAnimator(new DefaultItemAnimator());
rvHeadline.setNestedScrollingEnabled(true);
} else {
headLineAdapter.notifyDataSetChanged();
}
}
/// Here i am observing data from ViewModel and setting in adapter
private void observeViewModel(HeadLineViewModel viewModel)
{
viewModel.getNewsResponseObservable()
.observe(this, newsResponse -> {
if (newsResponse != null)
{
List<Article> articles = newsResponse.getArticles();
articleArrayList.addAll(articles);
headLineAdapter.notifyDataSetChanged();
}
});
}
}