in my code I have a code inside a thread that first tries to update something from Database and if the update is not successful then an insert is tried. My problem is that this code is called twice (it's not ok I know but let's ignore this for now) and because of this the insert is called twice because the update is not finished (at least this is what I think). I searched on google I thought to use thread.join(). My question is if it's ok to use thread.join() in my case.
Thanks
public void persistChangesToDatabase() {
final Thread backThread = new Thread(new Runnable() {
#Override
public void run() {
try {
openDataBase();
<-- SOME CODE -->
//First, an UPDATE is tried
int rowsAffected = updateTable();
// If update fails an INSERT is tried
if (rowsAffected == 0) {
//Insert
insert();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
});
backThread.start();
try {
backThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Related
I am very new in Android, as a project, am doing a simon says game, and I'm having some problems representing the sequence to follow.
I tried to use a normal thread to make it follow a line (for example, the first button is lighten during X seconds, then turns off, then the yellow one....), but it didn't make it, because only the threads that created the view hierarchy can manipulate that view (in this case was the UI thread). So I had to load all the method in that thread with runOnUiThread, and at that point it worked almost perfect, because now the sequence is shown up but the frames don't. The Log tells me:
I/Choreographer: Skipped 116 frames! The application may be doing too much work on its main thread.
I have been looking for everywhere and I don't find alternatives for simulate the sequence. I leave here the code of the method.
public void createSequence(){
new Thread() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
sequence.clear();
for(byte i=0;i<rounds;i++){
add=r.nextInt((4 - 1) + 1) + 1;
if (add == 1) {
btn1.setBackgroundResource(R.drawable.button1_pressed);
try {
Log.i("Waiting for 1.","Waiting for 1.");
Thread.sleep(time);
btn1.setBackgroundResource(R.drawable.button1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("Value:", "1.");
} else if (add == 2) {
btn2.setBackgroundResource(R.drawable.button2_pressed);
try {
Log.i("Waiting for 2.","Waiting for 2.");
Thread.sleep(time);
btn2.setBackgroundResource(R.drawable.button2);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("Value:", "2.");
} else if (add == 3) {
btn3.setBackgroundResource(R.color.colorpressedbutton3);
try {
Log.i("Waiting for 3.","Waiting for 3.");
Thread.sleep(time);
btn3.setBackgroundResource(R.drawable.button3);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("Value:", "3.");
} else {
btn4.setBackgroundResource(R.color.colorpressedbutton4);
try {
Log.i("Waiting for 4.","Waiting for 4.");
Thread.sleep(time);
btn4.setBackgroundResource(R.drawable.button4);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("Value:", "4.");
}
sequence.add(add);
}
}
});
}
}.start();
}
You almost got it.
You need to implement the timing logic in a separate thread, but the update (UI) logic on the UI thread.
Something like this:
void setState(final Button b, final int state) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
b.setBackgroundResource(state);
}
});
}
void runSequence() {
new Thread() {new Runnable() {
#Override
public void run() {
sequence.clear();
for(byte i=0;i<rounds;i++){
add=r.nextInt((4 - 1) + 1) + 1;
if (add == 1) {
setState(btn1,R.drawable.button1_pressed);
try {
Log.i("Waiting for 1.","Waiting for 1.");
Thread.sleep(time);
setState(btn1, R.drawable.button1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("Value:", "1.");
} else if (add == 2) {
....
}
}).start();
}
i am trying to display a Toast on the screen and when Toast fades off then move to the next question. I have tried with Thread but cannot seem to manage.
My code:
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (getUserSelection()){
position = position + 3;
if (position < questionsArray.size()) {
curName = questionsArray.get(position).getName();
curArray = questionsArray.get(position).getAnswers();
curIscorrect = questionsArray.get(position).getIscorrect();
setupQuestionView(curName, curArray, curIscorrect);
} else {
StringGenerator.showToast(QuestionsActivity.this, "Your score : " + score + "/" + (questionsArray.size() / 3));
}
}else {
StringGenerator.showToast(QuestionsActivity.this, getString(R.string.noanswerselected));
}
}
});
and the getUserSelectionMethod:
private boolean getUserSelection() {
correct = (RadioButton)findViewById(group.getCheckedRadioButtonId());
if (correct == null){
return false;
}else {
correctAnswerText = correct.getText().toString();
if (map.get(correctAnswerText).equals(Constants.CORRECTANSWER)) {
score++;
setCorrectMessage();
return true;
} else {
setWrongMessage();
return true;
}
}
}
private void setCorrectMessage() {
correctToast = new Toast(QuestionsActivity.this);
correctToastView = getLayoutInflater().inflate(R.layout.correct, (ViewGroup) findViewById(R.id.correctRootLayout));
correctText = (TextView)correctToastView.findViewById(R.id.correctTextView);
correctText.setText(getString(R.string.correctAnswer));
correctToast.setDuration(Toast.LENGTH_SHORT);
correctToast.setView(correctToastView);
correctToast.show();
correctThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
correctToast.cancel();
}
});
correctThread.start();
}
private void setWrongMessage() {
wrongToast = new Toast(QuestionsActivity.this);
wrongToastView = getLayoutInflater().inflate(R.layout.wrong, (ViewGroup) findViewById(R.id.wrongRootLayout));
wrongText = (TextView)wrongToastView.findViewById(R.id.wrongTextView);
wrongText.setText(getString(R.string.wrongAnswer));
wrongToast.setDuration(Toast.LENGTH_SHORT);
wrongToast.setView(wrongToastView);
wrongToast.show();
wrongThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
wrongToast.cancel();
}
});
wrongThread.start();
}
Any suggestion on how to do this?
You can determine the toast visibility:
toast.getView().getWindowToken()
If the result is null, than your toast isn't visible anymore, and than you can run any code you want.
as stated in this answer you can start a thread that waits the duration of the Toast:
Thread thread = new Thread(){
#Override
public void run() {
try {
Thread.sleep(3500); // 3.5seconds!
// Do the stuff you want to be done after the Toast disappeared
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Toast.LENGTH_SHORT and Toast.LENGTH_LONG are only flags so you have to either hard code the duration or keep them in a constant. The durations are 3.5s (long) and 2s (short).
If you want to manipulate some of your views, you cannot do this in another thread than the "main" UI thread. So you have to implement a kind of callback/polling mechanism to get notified when the SleepThread has finished.
Check this answer to read about a couple of ways to do this. Probably the easiest of them to understand and implement is this:
After you started your Thread you can check if it is still alive and running by calling thread.isAlive(). In this way you can do a while loop that runs while the thread is running:
// start your thread
while(thread.isAlive()){}
// continue the work. The other thread has finished.
Please note that this is NOT the most elegant way to do this! Check the other possibilities in the answer I've mentioned above for more elegant solutions (especially the last one with the listeners is very interesting and worth reading!)
That's because the Thread class is purely executed in the background and you need to manipulate the view in the Main thread. To solve your issue just replace the Thread with AsynTask.
AsyncTask<Void,Void,Void> a = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
correctToast.cancel();
}
};
a.execute();
If you look at my code you can see my onPostExecute, this method is called in the Main Thread.
My Error was because i was trying to acess UI Elements through another Thread so modifying the code like this:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
QuestionsActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
moveToNextQuestion();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
did the trick. I hope my answer helps someone!!!
i want the AsyncTask to wait till it finishes. so i wrote the below code and i used .get() method as follows and as shown below in the code
mATDisableBT = new ATDisableBT();
but at run time the .get() doesnt force ATDisableBT to wait, becuase in the logcat i receive mixed order of messages issued from ATDisableBT and ATEnableBT
which means .get() on ATDisableBT did not force it to wait
how to force the AsyncTask to wait
code:
//preparatory step 1
if (this.mBTAdapter.isEnabled()) {
mATDisableBT = new ATDisableBT();
try {
mATDisableBT.execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
//enable BT.
this.mATEnableBT = new ATEnableBT();
this.mATEnableBT.execute();
You can do this way:
doInBackground of AsyncTask
#Override
protected Void doInBackground(String... params) {
Log.i("doInBackground", "1");
synchronized (this) {
try {
mAsyncTask.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i("doInBackground", "2");
return null;
}
Outside this function from where you have to nstrong textotify AsyncTask to release from wait state:
new CountDownTimer(2000, 2000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
synchronized (mAsyncTask) {
mAsyncTask.notify();
}
}
}.start();
Here I have notified AsyncTask by CountDownTimer after 2 seconds.
Hope this will help you.
You should execute AsyncTask on UI thread, so using get() - which will block it makes no sense - it might get you ANR error.
If you are on HONEYCOMB and up, then AsyncTasks are executed on single executor thread, serially - so your mATEnableBT should get executed after mATDisableBT. For more see here:
http://developer.android.com/reference/android/os/AsyncTask.html#execute(Params...)
You might also switch from AsyncTask to Executors. AsyncTask is implemented using executors. By creating single threaded executor you make sure tasks will get executed serially:
ExecutorService executor = Executors.newSingleThreadExecutor();
//...
executor.submit(new Runnable() {
#Override
public void run() {
// your mATDisableBT code
}
});
executor.submit(new Runnable() {
#Override
public void run() {
// your mATEnableBT code
}
});
I'm doing an app that displays various yoga poses for 60 seconds. I've been pulling my hair out trying to get a countdown timer to work the way I want. I need the timer to be able to pause, and restart automatically after 15 seconds. The CountDownTimer from Android didn't work because it had no pause. I tried 2 different versions of rewritten Android CountDownTimers and the classic version (Android CountDownTimer) and they all seem to have the same bug because they are using Handlers.
I've tried this version: http://www.java2s.com/Open-Source/Android/Timer/multitimer-android/com/cycleindex/multitimer/CountDownTimerWithPause.java.htm
I've tried this version: Android: CountDownTimer skips last onTick()! - I added an onFinish method to it.
I'm trying to do a Thread.sleep in the onFinish method for 15 seconds, and it is not updating the UI past the last second before moving into the Thread.sleep mode. In the following code, the TextView isn't getting updated to be set to empty string until after the Thread.sleep call.
cdt = new CountDownTimerWithPause(60000,1000,true) {
#Override
public void onTick(long millisUntiFinished) {
tvClock.setText("Remaining:" + millisUntiFinished/1000);
}
#Override
public void onFinish() {
tvClock.setText("");
bell.start();
if (bAutoPlayIsOn) {
tvClock.setText("waiting for next pose...");
try {
//15 second pauses between poses
Thread.sleep(15000);
//start over
listener.onForwardItemSelected();
ResetClocktoMaxTime(60000);
resume();
} catch (InterruptedException e) {
Log.d("Sleep Interrupted", e.toString());
e.printStackTrace();
}
catch (Exception e) {
Log.d("Timer", e.toString());
}
}
else {
tvClock.setText("Done");
btnStart.setText("Start ");
bClockIsTicking = false;
btnStart.setCompoundDrawablesWithIntrinsicBounds(null, playBtn, null, null);
}
}
};
Anyone have any ideas how to do this (restart after 15 seconds) differently?
The onFinish method is being called from the interface thread, so any interface changes you make won't actually redraw until onFinish returns. Try something like this:
cdt = new CountDownTimerWithPause(60000,1000,true) {
#Override
public void onTick(long millisUntiFinished) {
tvClock.setText("Remaining:" + millisUntiFinished/1000);
}
#Override
public void onFinish() {
tvClock.setText("");
bell.start();
if (bAutoPlayIsOn) {
tvClock.setText("waiting for next pose...");
(
new Thread() {
public void run() {
try {
//15 second pauses between poses
Thread.sleep(15000);
getActivity().runOnUiThread
(
new Runnable() {
public void run() {
//start over
listener.onForwardItemSelected();
ResetClocktoMaxTime(60000);
resume();
}
}
);
}
catch (InterruptedException e) {
Log.d("Sleep Interrupted", e.toString());
e.printStackTrace();
}
catch (Exception e) {
Log.d("Timer", e.toString());
}
}
}
).start();
}
else {
tvClock.setText("Done");
btnStart.setText("Start ");
bClockIsTicking = false;
btnStart.setCompoundDrawablesWithIntrinsicBounds(null, playBtn, null, null);
}
}
};
Can wait/notify be used within one thread?
I'm mean I have a listener and in the moment when that listener gets called I wanna enable a thread to do his work.How could I do that?
UPDATE:My data is written in a database...and is written each time the listener is called.Now the thread that I've created reads that data and sends it somewhere....
Next...I get some other data and do the same thing....The other thread needs to know what was the last data he read it so he can start reading from where he left....
Take a look in here:
using wait and notify within one thread
This is how my problem looks like.Thx
I have the following:
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
in MyThread....so when I do
MyThread t = new MyThread(syncToken);
t.start();
I put my thread on waiting...yes?
And when I do this:
syncToken.notify();
I get my thread back on track....but the execution of the next line is the one after wait()?
I mean this: System.out.println("MyThread: " + s); ????
When u notify a thred does he continues his execution with the line after wait()???Thx
The following is a simple example of concurrency between two different threads. In the example the main thread start a MyThread thread and every 3 seconds it sets a data to the MyThread instance and then MyThread prints it. The idea is to have a synchronized object that you wait on it and notify in the end of the usage to other threads that they can use it:
Test.java:
package stack;
public class Test {
public static void main (String args[])
{
Object syncToken = new Object();
MyThread t = new MyThread(syncToken);
t.start();
for (int i = 0; i < 10; i++)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(syncToken)
{
t.setText("Iteration " + i);
syncToken.notify();
}
}
}
}
MyThread.java:
package stack;
public class MyThread extends Thread{
String s;
Object syncToken;
public MyThread(Object syncToken)
{
this.s = "";
this.syncToken = syncToken;
}
public void run()
{
while(true) // you will need to set some condition if you want to stop the thread in a certain time...
{
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
}
}
public void setText(String s)
{
this.s = s;
}
}
In this example, the main thread sets a string (every 3 seconds) and the MyThread thread prints it.
Adapt it to your needs, it shouldn't be too hard.
I had similar problem. I created an arbiter used by two threads (in your case it can be listeners thread and your task thread):
listener:
arbiter.waitConsumer();
// prepare data
arbiter.dataLoaded();
task thread:
while(true){
arbiter.waitProducer();
// consume data
arbiter.dataConsumed();
}
arbiter:
public class Arbiter {
private boolean dataLoaded = false;
public synchronized void waitProducer(){
while(!dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void waitConsumer(){
while(dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void dataLoaded(){
dataLoaded = true;
notify();
}public synchronized void dataConsumed(){
dataLoaded = false;
notify();
}}
Listener and task will synchronize themselfes against arbiters monitor. Probably you can call your arbiter queue or pipe and store date for consuming in it?