在Android Room数据库中从runInTransaction()返回值 [英] Returning value from runInTransaction() In Android Room database
问题描述
没有太多文档可以了解runInTransaction()方法的工作原理.如果不返回任何值,则在不同的DAO上执行多个操作时,如果可以得到任何结果,则可以使用 runInTransaction(Runnable body)
或 runInTransaction(Callable< V> body)
返回.
查询我是否拥有:如果事务中的所有查询都成功,那么我想返回一个需要在成功事务中上载到服务器的图像对象如果发生任何异常或交易未成功,我需要返回一个带false的布尔值,以指示用户发生了一些错误.
以下是方法:
public boolean userCheckedIn(final User user){尝试 {appDatabase.runInTransaction(new Callable< Object>(){@Override公共对象call()引发异常{如果(用户!= null){//在表A中添加条目appDatabase.UserDao().add(user);//更新表B中的条目//从表C中删除一个条目事件图片= updateUserAction(action);返回图像;}返回null;}});} catch(Exception e){返回false;}返回true;}
在上面的方法中,我打算做的是,如果所有数据库执行成功,我需要返回一个图像,该图像将被上载到服务器.如果在执行db事务时发生任何异常或发生任何错误,我需要返回 false
,以使用户知道发生了错误.不知道我是否正确.另外,我应该将runInTransaction放在try catch块中吗?
runInTransaction(Callable)
的代码等效于 runInTransaction(Runnable)
版本:>
- 如果交易成功(这是不会引发任何异常),它将交易设置为成功(通过调用
setTransactionSuccessful()
,如果没有成功则将被回退). li> - 在任何情况下都结束事务(此时,如果将其设置为成功,则整个事务都将提交,否则将回滚).
- 如果在
Callable
或Runnable
中引发了异常,则不会处理该异常(在Callable
情况下,是,但是是重新抛出).这意味着您需要在调用runInTransaction(Callable)
或runInTransaction(Runnable)
的代码中进行处理.
主要功能差异在于 runInTransaction(Callable)
返回由 Callable
返回的值.
因此,您的代码可以做两件事:
- 成功返回图像或失败返回
null
,然后将图像上传到调用userCheckedIn(User)
的方法中,或者 - 在
userCheckedIn(User)
方法中上传图像
第二种解决方案(如果我没有调用 userCheckedIn(User)
的方法的代码,可以让我更轻松地向您显示代码)将类似于以下内容:
public boolean userCheckedIn(final User user){尝试 {事件图像= appDatabase.runInTransaction(new Callable< Object>(){@Override公共对象call()引发异常{如果(用户!= null){//在表A中添加条目appDatabase.UserDao().add(user);//更新表B中的条目//从表C中删除一个条目事件图片= updateUserAction(action);返回图像;}返回null;}});if(image!= null){//将图片上传到服务器} 别的 {//没有可用的图片(可能是因为"if(user!= null)"//在Callable中).我假设您想在这种情况下返回false.返回false;}} catch(Exception e){返回false;}返回true;}
There is not much documentation to understand how exactly does runInTransaction() method works.
While executing multiple operations on different DAO's if no value is to be returned I could use runInTransaction(Runnable body)
OR runInTransaction(Callable<V> body)
if any result is to be returned.
Query that I have: If all the queries in the transaction are successful, then I want to return an image object that needs to be uploaded to a server on successful transaction If any exception occurred or the transaction was not successful I need to return a boolean with false to indicate the user that some error occurred.
Here is the method:
public boolean userCheckedIn(final User user) {
try {
appDatabase.runInTransaction(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (user != null) {
//Add entry in table A
appDatabase.UserDao().add(user);
//Update entry in table B
//Delete an entry from table C
Event image = updateUserAction(action);
return image;
}
return null;
}
});
} catch (Exception e) {
return false;
}
return true;
}
In the above method, what I intend to do is, if all the database executions are a success I need to return an image which will be uploaded to the server. If there is any exception that occurred or any error occurred while doing the db transaction I need to return false
to let user know an error occurred. Not sure if I got it right. Also, should I be putting the runInTransaction in try catch block ?
The code for runInTransaction(Callable)
is equivalent to the runInTransaction(Runnable)
version:
- if the transaction succeeds (this is, no exceptions are thrown) it sets the transaction as successful (by calling
setTransactionSuccessful()
, without this is considered failed and will be rolled back). - ends the transaction in any case (at this point, if it was set as successful the whole transaction is committed, else is rolled back).
- if an exception is thrown inside the
Callable
orRunnable
, the exception is not handled (in theCallable
case it is, but is rethrown). This means you need to handle it in the code calling eitherrunInTransaction(Callable)
orrunInTransaction(Runnable)
.
The main functional difference is that runInTransaction(Callable)
returns the value returned by the Callable
.
So, your code can do two things:
- either return the image on success or
null
on failure, and upload the image in the method calling touserCheckedIn(User)
or, - upload the image inside your
userCheckedIn(User)
method
The second solution (easier for me to show you the code given I don't have the code for the method calling to userCheckedIn(User)
) will look similar to this:
public boolean userCheckedIn(final User user) {
try {
Event image = appDatabase.runInTransaction(new Callable<Object>() {
@Override
public Object call() throws Exception {
if (user != null) {
//Add entry in table A
appDatabase.UserDao().add(user);
//Update entry in table B
//Delete an entry from table C
Event image = updateUserAction(action);
return image;
}
return null;
}
});
if (image != null) {
// Upload the image to the server
} else {
// No image available (probably because of the "if (user != null)"
// inside Callable). I assume you want to return false in this case.
return false;
}
} catch (Exception e) {
return false;
}
return true;
}
这篇关于在Android Room数据库中从runInTransaction()返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!