0

As discussed here Android Room - Get the id of new inserted row with auto-generate it is possible to get the ID from the newly inserted object.

But how do I get this ID all the way from the DAO to my Activity class in an MVVM pattern?

Some answers on there suggest using rxjava and something like this:
return Single.fromCallable<Long> { recipesDao.insertManual(cookingRecipes) }
But does it make sense to implement two whole Gradle dependencies just to have one method call?

Isn't there a way to make this work with my current structure?

Activity - ViewModel - Repository ( - AsyncTask) - Dao


The only problem is getting the return value from the insert statement, which is called from an AsyncTask:

private static class UpdateChallengeInfosAsyncTask extends AsyncTask<ChallengeInfos, Void, Void> {

        private ChallengeInfosDao mAsyncTaskDao;

        UpdateChallengeInfosAsyncTask(ChallengeInfosDao dao) {
            mAsyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(ChallengeInfos... challengeInfos) {
            mAsyncTaskDao.insert(challengeInfos[0]);
            return null;
        }
    }

Maybe it's possible with a onPostExecute() + Interface combo like here?
How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

Big_Chair
  • 2,781
  • 3
  • 31
  • 58
  • AsyncTask is deprecated. Use Concurrency in Java or Coroutines in Kotlin. And you can return data from AsyncTask. https://stackoverflow.com/questions/6053602/what-arguments-are-passed-into-asynctaskarg1-arg2-arg3 – Sourav Bagchi Aug 29 '20 at 16:29

2 Answers2

0

Just make the AsyncTask a nested class within your Activity. Then you can just call a method belonging to your Activity from onPostExecute() to pass the ID value.

Disclaimer: AsyncTasks are bad and you should use something else.

Disclaimer 2: If you're following MVVM, the ViewModel should be dealing with the ID and not the Activity.

Gavin Wright
  • 3,124
  • 3
  • 14
  • 35
  • Well the problem is that on creating a new object, it has an ID of 0. Only after retrieving it again (by closing and opening the activity) it receives the actual ID it has in the DB. So the issue is, I create the object and then want to update it, which fails because Room can't find the ID "0". That is why I need that ID to assign it to my object, which I am creating in the Activity. – Big_Chair Aug 29 '20 at 17:58
  • And any specific reason why AsyncTasks are bad or what I could use instead? – Big_Chair Aug 29 '20 at 18:01
  • Well, seeing the relatively long implementation of Concurrency [here](https://stackoverflow.com/a/58767934/1972372), I don't think it is necessary to rewrite my logic just for some DB writes, as they shouldn't be at risk of memory leaks or similar stuff, which seem to be the reason why people fear the use of `AsynkTask` – Big_Chair Aug 29 '20 at 18:24
0

Okay so what I ended up doing and what seems to be working pretty well is this:

Basically used the structure from this answer:
https://stackoverflow.com/a/12575319/1972372

And implemented the AsynTask callback-interface in my ViewModel with a MutableLiveData object for the Activity to call once in the beginning and hang on to until it is updated once:


public class ChallengeViewModel extends AndroidViewModel implements ChallengesRepository.UpdateChallengeInfosAsyncTask.AsyncResponse {
    
    private MutableLiveData<Integer> insertedChlgInfoID;

....
....

    public void insertChallengeInfos(ChallengeInfos challengeInfos) {
        mRepository.insertChallengeInfos(challengeInfos, this);
    }

    public LiveData<Integer> getInsertedChlgInfoID() {
        return insertedChlgInfoID;
    }

    @Override
    public void processFinish(Long result) {
        insertedChlgInfoID.setValue(Ints.checkedCast(result));
    }
}

I understand the reasons why AsyncTask may be called bad in certain scenarios, but I think in my case it really works fine and doesn't really have any potential risks of memory leaks or similar, since it's only very basic write operations. And rewriting the whole logic doesn't seem to be of any benefit for my case.

Big_Chair
  • 2,781
  • 3
  • 31
  • 58