Search code examples
javaandroid-studioandroid-asynctaskandroid-roomandroid-livedata

Selecting Data from Room without observing


I need to select data from a table, manipulate it and then insert it into another table. This only happens when the app is opened for the first time that day and this isn't going to be used in the UI. I don't want to use LiveData because it doesn't need to be observed but when I was looking into how to do it, most people say I should use LiveData. I've tried using AsyncTask but I get the error "Cannot access database on the main thread since it may potentially....". Here is the code for my AsyncTask

 public class getAllClothesArrayAsyncTask extends AsyncTask<ArrayList<ClothingItem>, Void, ArrayList<ClothingItem>[]> {

        private ClothingDao mAsyncDao;
        getAllClothesArrayAsyncTask(ClothingDao dao) { mAsyncDao = dao;}


        @Override
        protected ArrayList<ClothingItem>[] doInBackground(ArrayList<ClothingItem>... arrayLists) {

            List<ClothingItem> clothingList  = mAsyncDao.getAllClothesArray();
            ArrayList<ClothingItem> arrayList = new ArrayList<>(clothingList);
            return arrayLists;
        }
    }

And this is how I'm calling it in my activity

        mClothingViewModel = new ViewModelProvider(this).get(ClothingViewModel.class);
        clothingItemArray = mClothingViewModel.getClothesArray();

What is the best practice in this situation?


Solution

  • Brief summary:

    1. Room really doesn't allow to do anything (query|insert|update|delete) on main thread. You can switch off this control on RoomDatabaseBuilder, but you better shouldn't.
    2. If you don't care about UI, minimally you can just to put your ROOM-ish code (Runnable) to one of - Thread, Executor, AsyncTask (but it was deprecated last year)... I've put examples below
    3. Best practices in this one-shot operation to DB I think are Coroutines (for those who use Kotlin at projects) and RxJava (for those who use Java, Single|Maybe as a return types). They give much more possibilities but you should invest your time to get the point of these mechanisms.
    4. To observe data stream from Room there are LiveData, Coroutines Flow, RxJava (Flowable).

    Several examples of using Thread-switching with lambdas enabled (if you on some purpose don't want to learn more advanced stuff):

    • Just a Thread

      new Thread(() -> { List<ClothingItem> clothingList = mAsyncDao.getAllClothesArray(); // ... next operations });

    • Executor

      Executors.newSingleThreadExecutor().submit(() -> { List<ClothingItem> clothingList = mAsyncDao.getAllClothesArray(); // ... next operations });

    • AsyncTask

      AsyncTask.execute(() -> { List<ClothingItem> clothingList = mAsyncDao.getAllClothesArray(); // ... next operations });

    If you use Repository pattern you can put all this thread-switching there

    Another useful link to read about life after AsyncTask deprecation