How to use LiveData and ViewModel as Async Task Loader
We often required to load some data which take a long time to load. For this, we use the Async Task Loader to load the data in the background. But now we have an alternative for this work and we can use the LiveData and ViewModel as Async Task Loader. In this article, I am going to explain how to use the LiveData and ViewModel as Async Task Loader.
LiveData and ViewModel as Async Task Loader
Here to explain the use of LiveData and ViewModel to load the data like Async Task Loader we will create an app to list all installed package on a device. Below is the sample of the app which we are going to develop in this article of How to use LiveData and ViewModel as Async Task Loader.
In this Article, I am going to create a demo app to list all app installed on your device. We will create four class and will go with each of the class one by one.
AppData.java: It is the POJO to store the details of the apps like AppName, Package Name, Icon. AppDataModel.java:It is the main class in which we will implement the ViewModel and LiveData toretrieve and store the information of Apps. MainActivity.java:MainActivity is our main class or only one activity of this demo App to list all apps from android device. AppsAdapter.java:AppsAdapter class is our adapter of recyclerview.
Create POJO Class to Store the detail of the all installed app
AppData.java is the POJO class which contains four field appName, packageName, Icon, and mFile. Apart from this, we have getter and setter of the variable. Below is the full code of AppData class. AppData.java
package com.nplix.applist;
import android.graphics.drawable.Drawable;
import java.io.File;
public class AppData { private String appName; private String packageName; private Drawable Icon;
public File getFile() { return mFile; }
public void setFile(File mFile) { this.mFile = mFile; }
private File mFile;
public String getAppName() { return appName; }
public void setAppName(String appName) { this.appName = appName; }
public String getPackageName() { return packageName; }
public void setPackageName(String packageName) { this.packageName = packageName; }
public Drawable getIcon() { return Icon; }
public void setIcon(Drawable icon) { Icon = icon; } }
There is nothing special in above POJO class it is a normal POJO that we use in our day to day task as a developer. The real magic is in our next class that is AppDataModel, so let's create the AppDataModel class.
Create AppDataModel class with ViewModel and LiveData
Let me explain more about our ViewModel and LiveData class. We have to create our AppDataModel class by extending the ViewModel.In the normal scenario, we can't store context or activity in ViewModel, but as we are going to extract the information about the installed app so we must require the context if we want to retrieve the information from our AppDataModel class. If you want to learn about the LiveData and ViewModel you can check out the article on LiveData and ViewModel which we published recently.
As we described above we can't use the context inside the ViewModel. So for the solution of this the AndroidViewModel so we will extend the AndroidViewModel instead of ViewModel as given below.
public class AppDataModel extends AndroidViewModel { private AppLiveData appLiveData; public AppLiveData getAppLiveData() { return appLiveData; } public AppDataModel(@NonNull Application application) { super(application); } }
Difference between ViewModel and AndroidViewModel
The major difference between both classes is context. In normal ViewModel, we can't use the context and activity due to the chance of memory leakage issue, but in AndroidViewModel we can use the context. For using the context its mandatory to create a default constructor with Application as the argument.
public AppDataModel(@NonNull Application application) { super(application); }
Create LiveData class to retrieve the Apps details
LiveData is the class which can be observed and notifies the bound activity and fragment in case data has been changed. Even LiveData observer can update the UI of the app on data change. If you want are not familiar with it, then check my recent article on LiveData.
Below is the full code of our LiveData class.
public class AppLiveData extends MutableLiveData<List<AppData>>{ private PackageManager packageManager; List<AppData> appList;
private final Context context;
public AppLiveData(Context context){ this.context=context; packageManager=context.getPackageManager(); LoadAppInfo(); }
private void LoadAppInfo() { // Retrieve all known applications. List<ApplicationInfo> apps = packageManager.getInstalledApplications( PackageManager.GET_UNINSTALLED_PACKAGES); if (apps == null) { apps = new ArrayList<ApplicationInfo>(); } appList = new ArrayList<AppData>(apps.size()); //Loop to get the info for all installed app and store the information in live data for (int i=0; i<apps.size(); i++) { AppData entry = new AppData(); entry.setPackageName(apps.get(i).packageName); entry.setAppName(apps.get(i).loadLabel(context.getPackageManager()).toString()); entry.setFile(new File(apps.get(i).sourceDir)); //Check if file exist then get the icon and store into the POJO if(entry.getFile().exists()){ entry.setIcon(apps.get(i).loadIcon(context.getPackageManager())); } //Add the indviual app information into the List appList.add(entry); Log.d("LiveData",entry.getAppName()); } //Set the value into LiveData setValue(appList);
}
}
Using below code we are declaring some variable that we required to retrieve and store the information of the installed app.
private PackageManager packageManager; List<AppData> appList; private final Context context;
In below code we are creating the constructor of our LiveData class and calling the LoadAppInfo() method to retrieve the app information.
public AppLiveData(Context context){ this.context=context; packageManager=context.getPackageManager(); LoadAppInfo(); }
It is important to remind that from where context is LiveData constructor. So the answer to this is that it is coming from the ViewModel constructor call using the below code.
appLiveData=new AppLiveData(application);
You can check the code above for our LoadAppInfo() method it self-explanatory along with the comment. But still, if have any question then put in the comment section below.
Linking the ViewModel, LiveData, and Activity with help of observer
So far we have created the POJO and ViewModel for our demo app. Now we have to put the observer on LiveData so that whenever any change happens into stored data. Then observer notifies the Main Activity to update the UI.
So now we need to modify our main class. In Main class, first of all, we have to define our RecyclerView as given below. Here we are declaring the RecyclerView and assigning a simple LinearLayout.
appDataModel.getAppLiveData().observe(this, new Observer<List<AppData>>() { @Override public void onChanged(@Nullable List<AppData> appData) { //this is not required here but just for reference we can do any thing with this data. appsList=appData; //Update the data to adapter appsAdapter.setData(appData); //Update to the UI with latest data appsAdapter.notifyDataSetChanged(); Log.d("MainActivity:", "Data has updated"); } });
In above code, we are retrieving the data using getAppLiveData() method declared in our ViewModel class and set the observer on same.
Adapter for RecyclerView of LiveData and ViewModel
The complete source code of the Adapter class is as given below. AppAdapter.java
/** * Created by Pawan on 1/18/2018. */ public class AppsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0; private static final int TYPE_ITEM = 1; private static final int TYPE_FOOTER = 2; private String TAG="LoadImage";
We have already given the complete code of the POJO and Adapter class above. Here we are giving the source code of the AppViewModel and MainActivity Class. MainActivity.java
appDataModel.getAppLiveData().observe(this, new Observer<List<AppData>>() { @Override public void onChanged(@Nullable List<AppData> appData) { //this is not required here but just for reference we can do any thing with this data. appsList=appData; //Update the data to adapter appsAdapter.setData(appData); //Update to the UI with latest data appsAdapter.notifyDataSetChanged(); Log.d("MainActivity:", "Data has updated"); } });
We have completed this article and you can see that it is very simple to use the LiveData and ViewModel as Async Task Loader. It's time to note some important point form this article. We have to use AndroidViewModel instead of ViewModel as it provides the context. LiveData can be observed so that we are storing our POJO data inside LiveData class. You can also download the complete source code of How to use LiveData and ViewModel as Async Task Loader from GitHub.
[…] Components Library for MVC app development. Architecture Components Library includes ViewModel, LiveData, RoomDatabase and Paging Library. In this article, we will create a TODO app that loads the paged […]
Flutter and Dart is an excellent combination for creating the UI, but for accessing the platform-specific service we need to open platform-specific activity. So lets in this article we will explore how to start an android activity and access the service from Flutter View. Create a Project for this Android Activity Flutter View Demo Create a Project From File menu select the New Flutter Project Enter the project name Select the AndroidX support and click on next After the above, we step click on Finish We will have the following project structure created. Create the Second Activity in Android Just go to the android folder and open it in separate windows. We will have the following project structure. Create the Activity Just right-click on the Kotlin folder and create a blank activity from the menu. If you create the activity then you may be required to upgrade the Gradle and do some import. So Just click on update and wait for the project s...
Kotlin is now official language for Android development and it is well supported in Android Studio. So here in this tutorial, we are going to learn about how to read and write JSON data in Kotlin using GSON. If you would like to learn the java version of this tutorial check out the last tutorial " How to Read and Write JSON data using GSON ". Introduction In this tutorial, we will write two methods. In the first method, we will create a JSON file and in second method we will read the file and print in a text box. If you like to know more about the basic entity of JSON you can check out Basic JSON entity here . What is JSON? JSON stands for J ava S cript O bject N otation JSON is a lightweight data-interchange format It is "self-describing" and easy to understand JSON is language independent and can we used in any language JSON Syntax Rules Data is in name/value pairs Data is separated by commas Curly braces hold objects Square brackets hold ...
In this tutorial, we learn how to connect to a WiFi hotspot in android by code. In this Demo we will create an as small app which will scan the all available network or Hotspot and list down the network when you select specific network, the application will connect that particular network. You May Like Below Topic: How to Read and Write JSON data using GSON WP Android App using REST and volley WP Android App using REST and volley part2 Implementation of SwipeRefreshLayout in RecyclerView Create Amazing Bottom Navigation Bar Without Any External Library Introduction In this tutorial, we learn how to connect to a WiFi hotspot in android by code. In this Demo we will create an as small app which will scan the all available network or Hotspot and list down the network when you select specific network, the application will connect that particular network. We will add this functionality to our existing Demo app " Video Gallery ". If you would like to check out t...
[…] How to use LiveData and ViewModel as Async Task Loader […]
ReplyDelete[…] Components Library for MVC app development. Architecture Components Library includes ViewModel, LiveData, RoomDatabase and Paging Library. In this article, we will create a TODO app that loads the paged […]
ReplyDeleteNo Async load found in any code !?
ReplyDelete