[英]Are Co-Routines in Android Development only for Kotlin? Retrieval from android room using MVVM, way to get id returned to activity immediately?
This is a general question regarding android development and the use of co-routines.这是关于 android 开发和协程使用的一般问题。 I am relatively new to developing in android and have created an application using the MVVM architecture model.我对在 android 中进行开发比较陌生,并且已经使用 MVVM 架构模型创建了一个应用程序。
I am currently having a problem where I insert into a table and retrieve an ID back in an observer with LiveData.我目前遇到了一个问题,我插入到一个表中,并用 LiveData 在观察者中检索一个 ID。 I then need to use this ID immediately to insert into another table to act as a foreign key.然后我需要立即使用这个 ID 插入到另一个表中作为外键。 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.我的问题是初始 ID 的插入是在后台进行的,因此当 ID 返回到活动时,错误已经抛出。
I need some way of:我需要某种方式:
I have seen one solution is to use co-routines but this seems to just be a Kotlin solution.我见过一种解决方案是使用协程,但这似乎只是一个 Kotlin 解决方案。
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?有谁知道可以在 android java 中立即检索活动中插入的 ID 以用于下一次插入的解决方案?
*I am using a room SQL Database. *我正在使用一个房间 SQL 数据库。
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.因此,您有一个操作需要异步插入到表中,另一个操作需要使用第一个操作结果中的 id 插入到另一个表中。
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).因为您需要使用 Java,所以您将无法使用 Kotlin 协程(因为这是 Kotlin 语言的特性)。 Fortunately, there are several methods for achieving this in Java.幸运的是,在 Java 中有几种方法可以实现这一点。
I personally would recommend the use of RX Java.我个人会推荐使用 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).对于这个用例,您可能想要的称为flatMap
,它是一个运算符,它在调用第二个操作之前阻塞第一个操作的结果,第一个操作的结果作为参数。
However, RX is quite a big dependency to add and also has quite a learning curve.然而,RX 是一个相当大的依赖项,并且也有相当长的学习曲线。 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 (ie when you issue them, the current thread waits for the operation to complete) then you can have a chained operation like so:因此,假设您的 Room DB 函数是阻塞的(即,当您发出它们时,当前线程等待操作完成),那么您可以有一个像这样的链式操作:
// 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();
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.