Bolu Okunaiya
Bolu Okunaiya

Reputation: 17

Room Database Query

I'm new to Room and i'm trying to query my database to get a row from it. I attempted doing so by querying it with the primary key which is id but the problem is i don't know how to return the target object from the repository.

This is the Dao

@Query("SELECT * FROM targets WHERE id = :id LIMIT 1")
Targets findTargetById(int id);

THis is the Repository class

 public Targets findTarget (int id) {
    new findTargetByIDAsyncTask(mTargetsDao).execute(id);

}

   private static class findTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {

    private TargetsDao mAsyncTaskDao;

    findTargetByIDAsyncTask(TargetsDao dao) {
        mAsyncTaskDao = dao;
    }


    @Override
    protected Targets doInBackground(Integer... integers) {

        return mAsyncTaskDao.findTargetById(integers[0]);
    }

    @Override
    protected void onPostExecute(Targets targets) {
        super.onPostExecute(targets);
    }
}

Upvotes: 1

Views: 856

Answers (2)

Rajarshi
Rajarshi

Reputation: 2509

The point is to get the data/object from a background thread. You can use Android's AsyncTask or a ExecutorService. A simple example is if you want to get a String of a user name the method will be:

private String getName() {
    String name = null;
    try {
        name = Executors.newSingleThreadExecutor().submit(() ->
                userDao.fetchUserName()).get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return name;
}

Upvotes: 1

Oleg Sokolov
Oleg Sokolov

Reputation: 1143

You have two ways to return a result.

The first way is to call AsyncTask.get() method, but it will still hold a MainThread what leads to ANR if a task will longer than 5 seconds:

public Targets findTarget (int id) {
    return new findTargetByIDAsyncTask(mTargetsDao).execute(id).get();
}

The second way is more complicated but it will not hold the MainThread. You should add a Callback class:

public interface Callback {
        void onSuccess(Targets targets);
    }

Each method of your repository will look like that:

public void findTarget (Callback callback, int id) {
        new findTargetByIDAsyncTask(mTargetsDao, callback).execute(id);
    }

And AsynTask will look like that:

private static class FindTargetByIDAsyncTask extends AsyncTask<Integer, Void, Targets> {

    private final TargetsDao mAsyncTaskDao;
    private final Callback callback;

    FindTargetByIDAsyncTask(TargetsDao dao, Callback callback) {
        mAsyncTaskDao = dao;
        this.callback = callback;
    }


    @Override
    protected Targets doInBackground(Integer... integers) {
        return mAsyncTaskDao.findTargetById(integers[0]);
    }

    @Override
    protected void onPostExecute(Targets targets) {
        callback.onSuccess(targets);
    }
}

Upvotes: 2

Related Questions