Faizan Mir
Faizan Mir

Reputation: 310

Ways to caching online data fetched through Retrofit into Room for offline access

I am trying to design an application that can work online as well as offline ,I need to design a sort of local caching system,I have tried the MVVM implementation and am able to get data from the local data base using Room Persistence library but I am not sure about how to get the data from the server and make it behave as the data already stored in the database (ie in the local cache database ),Any help will be appreciated

I have tried implementing retrofit and getting data from it ...But my implementation would fetch the data from the server every time the database is opened ,Delete the pervious data and populate it with the database from the server ,I dont think this is a feasible implementation as it requires the data to be deleted and recreated

class Repository {
private LiveData<List<User>> allUsers;
private static final String TAG = "Repository";
private UserDao userDao;

Repository(Application application) {
    DatabaseClass database = DatabaseClass.getInstance(application);
    userDao = database.databaseDAO();
    allUsers = userDao.getAllUsers();
    Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
    RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
    Call<List<User>> userCall = retrofitApi.get();

    userCall.enqueue(new Callback<List<User>>() {
        @Override
        public void onResponse(Call<List<User>> call, Response<List<User>> response) {
            List<User> userList = response.body();
            for (User user: userList
                 ) {
                user = new User(user.title,user.title,user.userId);
                insert(user);

            }
        }

        @Override
        public void onFailure(Call<List<User>> call, Throwable t) {

        }
    });


}

public void insert(User user)
{
    new InsertIntoDatabase(userDao).execute(user);
}
public  void update(User user)
{
    new UpdateUser(userDao).execute(user);
}
public void delete(User user)
{
    new DeleteFromDatabase(userDao).execute(user);
}
public void deleteAllUser()
{
    new DeleteAllUsers(userDao).execute();
}
public LiveData<List<User>> getAllUsers()
{
    return allUsers;
}



static class InsertIntoDatabase extends AsyncTask<User,Void,Void>{
    public UserDao userDao;

    public InsertIntoDatabase(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(User... users) {
        userDao.insert(users[0]);
        return null;
    }
}

static class DeleteFromDatabase extends AsyncTask<User,Void,Void>{
    public UserDao userDao;

    public DeleteFromDatabase(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(User... users) {
        userDao.delete(users[0]);
        return null;
    }
}


static class DeleteAllUsers extends AsyncTask<Void,Void,Void>{
   UserDao userDao;

    public DeleteAllUsers(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(Void... voids) {
        userDao.deleteAllUsers();
        return null;
    }
}


static class UpdateUser extends AsyncTask<User,Void,Void>{
    UserDao userDao;

    public UpdateUser(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    protected Void doInBackground(User... users) {
        userDao.updateUser(users[0]);
        return null;
    }
}

}

What I would expect is as listed below 1) Only the updated data should be stored in room 2) Some sort of implementation that doesnt require to delete everything in the database and then recreates it

Upvotes: 1

Views: 3360

Answers (1)

a_local_nobody
a_local_nobody

Reputation: 8201

How to use room database as a cache consider having a look at my answer here. As I have told a lot of people (and I probably still will) when you are learning something new, worrying about the best way of doing something is almost pointless and you should start by getting something to work FOR YOU first.

the typical approach to using Room as a cache goes something like this, potentially:

  1. fetch data from an api
  2. insert it into room database
  3. fetch it from room in my app

Room allows you to store your data locally and retrieve this data with various different threads, making use of something like Rxjava, it also allows you to observe onto any changes with LiveData, Room is definitely a decent option to consider for caching in this situation, although it's one of several techniques available to you

Upvotes: 5

Related Questions