Are Co-Routines in Android Development only for Kotlin? Retrieval from android room using MVVM, way to get id returned to activity immediately?

Marek Canavan :

This is a general question regarding android development and the use of co-routines. I am relatively new to developing in android and have created an application using the MVVM architecture model.

I am currently having a problem where I insert into a table and retrieve an ID back in an observer with LiveData. I then need to use this ID immediately to insert into another table to act as a foreign key. One table defines the entry and the other the fields associated to that entry.

My issue is that the insertion of the initial ID is happening in the background, so by the time the ID is returned to the activity an error has already been thrown up.

I need some way of:

  • either waiting for the ID to be returned
  • or have the insertion run in the foreground (but am unsure how to do this).

I have seen one solution is to use co-routines but this seems to just be a Kotlin solution.

Does anyone know of a solution that would work in android java to immediately retrieve the ID of insertion in the activity to use for the next insert?

*I am using a room SQL Database.

Thomas Cook :

Ok, correct me if I'm wrong, but what I think you want is a way to chain asynchronous operations together in a synchronous way.

So you have one operation which needs to insert into a table asynchronously, and another operation which needs to use the id from the result of the first operation to insert into another table.

So your second operation requires the first operation to have finished before it runs. But your first operation is running in the background so the question arises; "How do I make sure not to fire the second operation until the first one has finished?".

This is the concept of "chaining" asynchronous calls. Or, in other words, performing asynchronous calls in a synchronous fashion.

Because you need to use Java you won't be able to use Kotlin coroutines (because that's a Kotlin language feature). Fortunately, there are several methods for achieving this in Java.

I personally would recommend the use of RX Java. There are loads of operators for combining asynchronous operations. The one you'd probably want for this use case is called flatMap, which is an operator which blocks on the first operations result before invoking the second operation, with the results of the first one as argument(s).

However, RX is quite a big dependency to add and also has quite a learning curve. So, choosing to use this tool will depend on how prevelant this kind of problem is in your code base.

Another option, is to set up a shared single thread executor which would be used to issue both operations on the same background thread. Because it is a single background thread, as long as you issue the commands into the executor sequentially, they will execute sequentially, but on a background thread. So, assuming your Room DB functions are blocking (i.e. when you issue them, the current thread waits for the operation to complete) then you can have a chained operation like so:

// Create a shared single threaded executor to run both operations on the same background thread
private Executor sharedSingleThreadExecutor = Executors.newSingleThreadExecutor();

private void doThingAThenThingB() {
    // Sequentially call thing A on shared background thread
    sharedSingleThreadExecutor.execute(() -> {    
        // Do thing A
        doThingA();
    });

    // Sequentially call thing B on shared background thread
    sharedSingleThreadExecutor.execute(() -> {
        // Do thing b
        doThingB();
    });
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=217101&siteId=1