Mukarram Ali
Mukarram Ali

Reputation: 427

Using Room without ViewModel

I just started using android room. Only problem is, It takes several layers for db interaction. Table Class -> Dao Interface -> Database Repo -> ViewModels

And in each layer, code repetition is there.

As if I directly call queries from Repo, without viewModels, it will not allow. Because call without viewModel observer becomes synchronous, which blocks main thread.

Either there must be standard way to call repo asynchronously, or some hacks. May be we can use some Async generic class, which lets you pass queries and return result to main thread.

Possible hack. Don't knwo if it is correct way.

    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            List<User> users = apiService.getAllUsers();
            if(users.size()>0)
            {
                System.out.println("Total users:"+users.size());
                System.out.println("Email:"+users.get(0).getEmail());
            }
        }
    });

Upvotes: 4

Views: 4267

Answers (3)

Suleyman
Suleyman

Reputation: 2943

The layers that you see explained here or in your app do not introduce code repetition, it may seem like so, but it makes your app modular. If your application scales and you need to reuse or change something it will be much easier.

And additionally, ViewModel does not make the calls asynchronous. What makes them work is LiveData (when you wrap you return type in LiveData in Dao class).
ViewModel serves to abstract away the non-view related logic from the View (Activity or Fragment), and lets the data survive configuration change, additionally with ViewModel you will avoid having a God Activity that handles everything.

You have several options:

1) You can use AsyncTask mentioned by @EarlOfEgo in order to perform insert. And when you query your database, just wrap the return type in LiveData and that's it. A small example of an AsyncTask, taken from the codelab page 8:

private static class insertAsyncTask extends AsyncTask<Word, Void, Void> {

    private WordDao mAsyncTaskDao; 

    insertAsyncTask(WordDao dao) {
        mAsyncTaskDao = dao;
    }

    @Override
    protected Void doInBackground(final Word... params) {
        mAsyncTaskDao.insert(params[0]);
        return null;
    }
}

2) If you don't need to observe the changes in your database then you can avoid LiveData altogether and handle the execution of all the queries and inserts manually on a separate thread. Or another option is to receive only one update from the LiveData and unregister the listener (or I believe there is an implementation of a LiveData that receives only a single update).

3) Or you can just .allowMainThreadQueries()

Upvotes: 4

Agon Avdijaj
Agon Avdijaj

Reputation: 225

If you are just testing Room then just call

.allowMainThreadQueries() 

If you are building a real app there is no point in skipping this Android Architecture.

Upvotes: 5

Stephan
Stephan

Reputation: 16749

You can use an AsyncTask for this without the need for ViewModels.

AsyncTask.execute {
            val entity = daoInterface.queryFunction()
            ...
        }

Upvotes: 6

Related Questions