Waiting for SingleThreadExecutor to deliver result to UI thread (RunOnUIThread) before continuing UI Thread...
I am using android Room and I have a boolean method that querys a DB through an Executor to see if an ID provided by the user is already used. everything works fine but sometimes the ansewer from the DB call arrives to late to the main thread meaning that my code doesnt know if the id is new or old. I want to make the code in the method wait until the runOnUiThread inside the executor has delivered a result for the rest of the method to work with.
//check id validity with two different error messages
int isNew=-1;
void setIsNewId(int result){
isNew=result;
}
private boolean checkId(){
String id=mId.getText().toString().trim();
try{
final int parseId=Integer.parseInt(id);
AppExecutors.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
final int result=mDb.clientDao().isIdNew(parseId);
runOnUiThread(new Runnable() {
@Override
public void run() {
setIsNewId(result);//<--THIS ARRIVES TOO LATE TO MAIN THREAD
}
});
}
});
//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE
if (isNew==1 && !id.isEmpty()){
ilId.setErrorEnabled(false);
return true;
}else if(isNew==0){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be new");
mId.setError("Id needs to be new");
Toast.makeText(this,"Id needs to be new", Toast.LENGTH_LONG).show();
return false;
}else{
Toast.makeText(this,"its taking too long", Toast.LENGTH_LONG).show();
return false;
}
}catch(Exception e){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be numeric");
mId.setError("Id has to be numeric");
Toast.makeText(this,"Id needs to be numeric", Toast.LENGTH_LONG).show();
return false;
}
}
I have already tried synchronizing on an object, using a mutex, a CountDownLatch,a sleep call. but all seem to freeze my UI and make my App crash. I know that executors have a submit() method but I have not been able to find an example about how to use it in the context of my nested thread. I am rather new to android and this is my first encounter with synchronization issues. maybe the solution is simple and i am just doing something wrong. any help is much appreciated
java android multithreading nested synchronization
add a comment |
I am using android Room and I have a boolean method that querys a DB through an Executor to see if an ID provided by the user is already used. everything works fine but sometimes the ansewer from the DB call arrives to late to the main thread meaning that my code doesnt know if the id is new or old. I want to make the code in the method wait until the runOnUiThread inside the executor has delivered a result for the rest of the method to work with.
//check id validity with two different error messages
int isNew=-1;
void setIsNewId(int result){
isNew=result;
}
private boolean checkId(){
String id=mId.getText().toString().trim();
try{
final int parseId=Integer.parseInt(id);
AppExecutors.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
final int result=mDb.clientDao().isIdNew(parseId);
runOnUiThread(new Runnable() {
@Override
public void run() {
setIsNewId(result);//<--THIS ARRIVES TOO LATE TO MAIN THREAD
}
});
}
});
//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE
if (isNew==1 && !id.isEmpty()){
ilId.setErrorEnabled(false);
return true;
}else if(isNew==0){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be new");
mId.setError("Id needs to be new");
Toast.makeText(this,"Id needs to be new", Toast.LENGTH_LONG).show();
return false;
}else{
Toast.makeText(this,"its taking too long", Toast.LENGTH_LONG).show();
return false;
}
}catch(Exception e){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be numeric");
mId.setError("Id has to be numeric");
Toast.makeText(this,"Id needs to be numeric", Toast.LENGTH_LONG).show();
return false;
}
}
I have already tried synchronizing on an object, using a mutex, a CountDownLatch,a sleep call. but all seem to freeze my UI and make my App crash. I know that executors have a submit() method but I have not been able to find an example about how to use it in the context of my nested thread. I am rather new to android and this is my first encounter with synchronization issues. maybe the solution is simple and i am just doing something wrong. any help is much appreciated
java android multithreading nested synchronization
Why u dont useAsync
? And put your db code insidedoInBackground
, even u can show progressbar before start reaching to db and at the end youronPostExecute
part will be called which u can remove progressbar and run code block which needs execute after checking id (//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE) example: journaldev.com/9708/android-asynctask-example-tutorial
– Vasif
Nov 11 '18 at 21:52
@Vasif I understand I should use an executer as it will guarantee that there is always only one thread accessing the DB, which is important because of race conditions. I found this very enlightening post stackoverflow.com/questions/5999100/… but I cant seem to make it work
– quealegriamasalegre
Nov 12 '18 at 0:58
I am thinking about just circumventing the problem by setting an onChangeListener on the field where the id is entered but it feels like a patch and i am sure there is a proper way to do it. besides I am definitely running into this issue again in the future
– quealegriamasalegre
Nov 12 '18 at 1:03
You can use special flag likeisInProgress
to force used only one thread
– Vasif
Nov 12 '18 at 11:48
add a comment |
I am using android Room and I have a boolean method that querys a DB through an Executor to see if an ID provided by the user is already used. everything works fine but sometimes the ansewer from the DB call arrives to late to the main thread meaning that my code doesnt know if the id is new or old. I want to make the code in the method wait until the runOnUiThread inside the executor has delivered a result for the rest of the method to work with.
//check id validity with two different error messages
int isNew=-1;
void setIsNewId(int result){
isNew=result;
}
private boolean checkId(){
String id=mId.getText().toString().trim();
try{
final int parseId=Integer.parseInt(id);
AppExecutors.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
final int result=mDb.clientDao().isIdNew(parseId);
runOnUiThread(new Runnable() {
@Override
public void run() {
setIsNewId(result);//<--THIS ARRIVES TOO LATE TO MAIN THREAD
}
});
}
});
//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE
if (isNew==1 && !id.isEmpty()){
ilId.setErrorEnabled(false);
return true;
}else if(isNew==0){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be new");
mId.setError("Id needs to be new");
Toast.makeText(this,"Id needs to be new", Toast.LENGTH_LONG).show();
return false;
}else{
Toast.makeText(this,"its taking too long", Toast.LENGTH_LONG).show();
return false;
}
}catch(Exception e){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be numeric");
mId.setError("Id has to be numeric");
Toast.makeText(this,"Id needs to be numeric", Toast.LENGTH_LONG).show();
return false;
}
}
I have already tried synchronizing on an object, using a mutex, a CountDownLatch,a sleep call. but all seem to freeze my UI and make my App crash. I know that executors have a submit() method but I have not been able to find an example about how to use it in the context of my nested thread. I am rather new to android and this is my first encounter with synchronization issues. maybe the solution is simple and i am just doing something wrong. any help is much appreciated
java android multithreading nested synchronization
I am using android Room and I have a boolean method that querys a DB through an Executor to see if an ID provided by the user is already used. everything works fine but sometimes the ansewer from the DB call arrives to late to the main thread meaning that my code doesnt know if the id is new or old. I want to make the code in the method wait until the runOnUiThread inside the executor has delivered a result for the rest of the method to work with.
//check id validity with two different error messages
int isNew=-1;
void setIsNewId(int result){
isNew=result;
}
private boolean checkId(){
String id=mId.getText().toString().trim();
try{
final int parseId=Integer.parseInt(id);
AppExecutors.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
final int result=mDb.clientDao().isIdNew(parseId);
runOnUiThread(new Runnable() {
@Override
public void run() {
setIsNewId(result);//<--THIS ARRIVES TOO LATE TO MAIN THREAD
}
});
}
});
//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE
if (isNew==1 && !id.isEmpty()){
ilId.setErrorEnabled(false);
return true;
}else if(isNew==0){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be new");
mId.setError("Id needs to be new");
Toast.makeText(this,"Id needs to be new", Toast.LENGTH_LONG).show();
return false;
}else{
Toast.makeText(this,"its taking too long", Toast.LENGTH_LONG).show();
return false;
}
}catch(Exception e){
ilId.setErrorEnabled(true);
ilId.setError("Id has to be numeric");
mId.setError("Id has to be numeric");
Toast.makeText(this,"Id needs to be numeric", Toast.LENGTH_LONG).show();
return false;
}
}
I have already tried synchronizing on an object, using a mutex, a CountDownLatch,a sleep call. but all seem to freeze my UI and make my App crash. I know that executors have a submit() method but I have not been able to find an example about how to use it in the context of my nested thread. I am rather new to android and this is my first encounter with synchronization issues. maybe the solution is simple and i am just doing something wrong. any help is much appreciated
java android multithreading nested synchronization
java android multithreading nested synchronization
edited Nov 12 '18 at 0:53
DaFois
1,89341418
1,89341418
asked Nov 11 '18 at 20:07
quealegriamasalegre
12
12
Why u dont useAsync
? And put your db code insidedoInBackground
, even u can show progressbar before start reaching to db and at the end youronPostExecute
part will be called which u can remove progressbar and run code block which needs execute after checking id (//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE) example: journaldev.com/9708/android-asynctask-example-tutorial
– Vasif
Nov 11 '18 at 21:52
@Vasif I understand I should use an executer as it will guarantee that there is always only one thread accessing the DB, which is important because of race conditions. I found this very enlightening post stackoverflow.com/questions/5999100/… but I cant seem to make it work
– quealegriamasalegre
Nov 12 '18 at 0:58
I am thinking about just circumventing the problem by setting an onChangeListener on the field where the id is entered but it feels like a patch and i am sure there is a proper way to do it. besides I am definitely running into this issue again in the future
– quealegriamasalegre
Nov 12 '18 at 1:03
You can use special flag likeisInProgress
to force used only one thread
– Vasif
Nov 12 '18 at 11:48
add a comment |
Why u dont useAsync
? And put your db code insidedoInBackground
, even u can show progressbar before start reaching to db and at the end youronPostExecute
part will be called which u can remove progressbar and run code block which needs execute after checking id (//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE) example: journaldev.com/9708/android-asynctask-example-tutorial
– Vasif
Nov 11 '18 at 21:52
@Vasif I understand I should use an executer as it will guarantee that there is always only one thread accessing the DB, which is important because of race conditions. I found this very enlightening post stackoverflow.com/questions/5999100/… but I cant seem to make it work
– quealegriamasalegre
Nov 12 '18 at 0:58
I am thinking about just circumventing the problem by setting an onChangeListener on the field where the id is entered but it feels like a patch and i am sure there is a proper way to do it. besides I am definitely running into this issue again in the future
– quealegriamasalegre
Nov 12 '18 at 1:03
You can use special flag likeisInProgress
to force used only one thread
– Vasif
Nov 12 '18 at 11:48
Why u dont use
Async
? And put your db code inside doInBackground
, even u can show progressbar before start reaching to db and at the end your onPostExecute
part will be called which u can remove progressbar and run code block which needs execute after checking id (//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE) example: journaldev.com/9708/android-asynctask-example-tutorial– Vasif
Nov 11 '18 at 21:52
Why u dont use
Async
? And put your db code inside doInBackground
, even u can show progressbar before start reaching to db and at the end your onPostExecute
part will be called which u can remove progressbar and run code block which needs execute after checking id (//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE) example: journaldev.com/9708/android-asynctask-example-tutorial– Vasif
Nov 11 '18 at 21:52
@Vasif I understand I should use an executer as it will guarantee that there is always only one thread accessing the DB, which is important because of race conditions. I found this very enlightening post stackoverflow.com/questions/5999100/… but I cant seem to make it work
– quealegriamasalegre
Nov 12 '18 at 0:58
@Vasif I understand I should use an executer as it will guarantee that there is always only one thread accessing the DB, which is important because of race conditions. I found this very enlightening post stackoverflow.com/questions/5999100/… but I cant seem to make it work
– quealegriamasalegre
Nov 12 '18 at 0:58
I am thinking about just circumventing the problem by setting an onChangeListener on the field where the id is entered but it feels like a patch and i am sure there is a proper way to do it. besides I am definitely running into this issue again in the future
– quealegriamasalegre
Nov 12 '18 at 1:03
I am thinking about just circumventing the problem by setting an onChangeListener on the field where the id is entered but it feels like a patch and i am sure there is a proper way to do it. besides I am definitely running into this issue again in the future
– quealegriamasalegre
Nov 12 '18 at 1:03
You can use special flag like
isInProgress
to force used only one thread– Vasif
Nov 12 '18 at 11:48
You can use special flag like
isInProgress
to force used only one thread– Vasif
Nov 12 '18 at 11:48
add a comment |
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252733%2fwaiting-for-singlethreadexecutor-to-deliver-result-to-ui-thread-runonuithread%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252733%2fwaiting-for-singlethreadexecutor-to-deliver-result-to-ui-thread-runonuithread%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Why u dont use
Async
? And put your db code insidedoInBackground
, even u can show progressbar before start reaching to db and at the end youronPostExecute
part will be called which u can remove progressbar and run code block which needs execute after checking id (//THIS SHOULD WAIT UNTIL RESULT IS AVAILABLE) example: journaldev.com/9708/android-asynctask-example-tutorial– Vasif
Nov 11 '18 at 21:52
@Vasif I understand I should use an executer as it will guarantee that there is always only one thread accessing the DB, which is important because of race conditions. I found this very enlightening post stackoverflow.com/questions/5999100/… but I cant seem to make it work
– quealegriamasalegre
Nov 12 '18 at 0:58
I am thinking about just circumventing the problem by setting an onChangeListener on the field where the id is entered but it feels like a patch and i am sure there is a proper way to do it. besides I am definitely running into this issue again in the future
– quealegriamasalegre
Nov 12 '18 at 1:03
You can use special flag like
isInProgress
to force used only one thread– Vasif
Nov 12 '18 at 11:48