I don't get this :
In a ShakeListener class, I execute a routine in the containing class.
The routine is :
public void showWord(){
myShakeListener.stop();
flipper.showNext();
v.vibrate(countdown5, -1);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myShakeListener.start();
}
Strange thing (to me, still a beginner), is that the thread sleeps BEFORE the next view is shown. Why is that?
What I want to accomplish : user shakes phone -> viewflipper flips to next -> Phone is unresponsive to shaking for 5 seconds -> user shakes phone -> viewflipper flips to next...
thnx
The problem is that the viewflipper is probably another thread. You're hitting a race condition. Better option is to spawn a thread for 5 seconds that sets a boolean called something like "noshake" to true when it starts and sets it false it when it's done. Check if noshake == false before allowing another shake.
Does that makes sense?
It's because your code is blocking the UI thread. You should do something like this:
Handler mHandler = new Handler();
public void showWord(){
myShakeListener.stop();
flipper.showNext();
v.vibrate(countdown5, -1);
mHandler.postAtTime(new Runnable() {
#Override
public void run() {
myShakeListener.start();
}
}, 5000);
}
Related
Visually, I'm expecting my app to show four Toasts in the following order:
createToast("start of delayed RandomCue Method");
createToast("start of delay");
createToast("end of delay");
createToast("end of delayed RandomCue Method");
However, the resulting order is:
createToast("start of delayed RandomCue Method");
createToast("end of delayed RandomCue Method");
createToast("end of delay");
createToast("start of delay");
My overall goal is to have a program that displays an image and changes ever 3 seconds. The player can press a button and the image changes for 1.5 seconds. Therefore, there are two methods, one to change picture using countdowntimer and another to change picture using onClick method corresponding to imagebutton.
The problem I'm running into is the code provided in the link (method called from within an onclick method) is supposed to change the image, set a bool value to false, wait 1.5 seconds, and then change the same bool value back to true.
While the bool value is true, the method that changes the pictures is supposed to be skipped but that's not the case and I don't know why but I think it's something to do with the code in the gists I created below.
So the issue I have is when the button is clicked, the image changes as expected but it sometimes changes again too quickly due to the first method not recognizing that the player responded and thus shouldn't change image yet.
public void delayedRandomCue(final long a){
didPlayerRespond = true;
createToast("start of delayed RandomCue Method");
randomCue();
Thread delay = new Thread() {
public void run() {
try {
createToast("start of delay");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
createToast("end of delay");
didPlayerRespond = false;
}
}
};delay.start();
createToast("end of delayed RandomCue Method");
}
https://gist.github.com/cjayem13/d32446ceb8c6d9626c68#file-easyfragment-Java
https://gist.github.com/cjayem13/d32446ceb8c6d9626c68
https://gist.github.com/cjayem13/d0a0b124dfe17666be25#file-easyfragment-Java
https://gist.github.com/cjayem13/d0a0b124dfe17666be25
onclick(){
delayedRandomCue(final long a)
}
randomCue();
Thread cueThread = new Thread(){
public void run() {
try {
while (fComm.fragmentGetTimerBool()) {
if(!didPlayerRespond) {
if (decTime > 1000) {
Thread.sleep(decTime);
} else {
Thread.sleep(1000);
}
decTime -= 50;
randomCue();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
saveScore();
}
// turn into end of all pics triggers bonus sTimerOn = false; fComm.fragmentScoreResponse(100);
//createToast("Bonus for completing all possible answers");
}
}; cueThread.start();
public void delayedRandomCue(final long a){
didPlayerRespond = true;
this happens first
createToast("start of delayed RandomCue Method");
randomCue();
Thread delay = new Thread() {
public void run() {
This happens in the background, asynchronously.
try {
createToast("start of delay");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
This happens in the background, after asynchronously running and completing
createToast("end of delay");
didPlayerRespond = false;
}
}
};delay.start();
This comes second because it is executed synchronously with the rest of the method.
createToast("end of delayed RandomCue Method");
}
This doesn't answer you question about the order of the toasts, but are you sure , when you say
The problem I'm running into is the code provided in the link (method
called from within an onclick method) is supposed to change the image,
set a bool value to false,wait 1.5 seconds, and then change the same
bool value back to true.
While the bool value is true, the method that changes the pictures is
supposed to be skipped but that's not the case and I don't know why
but i think it's something to do with the code in the gists I created
below.
that this is the case?
It looks more like , if the boolean is set to false, the other method that changes the pictures needs to be skipped, and as long as it is true, it needs to periodically change the pictures.
Try that, and maybe your image won't change very quickly after the user did trigger the onClick.
In my button execution, I am calling 2 methods.
plotButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
startPrinterListOperation();
showAplotPlotterDialog();
}
});
The startPrinterListOperation(); takes some time to complete its task. But I do not want the method showAplotPlotterDialog(); to run until the first one has completed. So I am trying to use thread management to achieve this. Here is what I have tried.
plotButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Thread t = new Thread() {
public void run() {
startPrinterListOperation();
}
};
t.start();
try {
t.join();
}
catch (InterruptedException e1) {
e1.printStackTrace();
}
showAplotPlotterDialog();
}
});
But the second method stills starts before the first one has finished.
Extending on my comment: Seems like startPrinterListOperation launches an asynchronous operation and finishes instantly, evidented by the join succeeding.
If the launched async op is out of your control, then you might be able to observe it finishing via some callback, polling, etc. Then you may employ something like the following in startPrinterListOperation:
void startPrinterListOperation() {
final CountDownLatch c1 = new CountDownLatch(1);
launchTheAsyncOp(new SomeCallback() {
void x() {
c1.countDown();
}
});
try {
c1.await(999, TimeUnit.SECONDS)
}
catch (InterruptedException e) {
throw new MyRuntimeException("user didn't finish the op in 999 seconds, fail");
}
}
I would not bother with threads, this will just make your program overly complicated.
Can you edit the startPrinterListOperation() method?
I would instead add showAplotPlotterDialog(); to the end of the startPrinter method, and the last last thing the method does.
Answering your general question in the title, you have a master thread that calls your two methods directly, so that the second method waits for the first method to complete.
I understand that in your specific case, the first method runs for a while, and you would prefer that the user not have to wait.
You should call a generatePrinterList() method in a separate thread while you're constructing the GUI. You do this because your GUI users are very likely to print or plot, and the printer list is not likely to change while the user is using your GUI.
Odds are that the generatePrinterList() thread will finish long before your user has to print or plot. But just to be sure, the thread has to have a way of reporting back that the thread is completed. I use a boolean isCompleted that can be read with a public isCompleted() method.
The isCompleted() method could have a thread sleep loop if you want, so it always returns true. In this case the method doesn't have to return anything.
I have a long process running inside AsyncTask but it might need to confirm something from user while processing. I know how I can show a confirm dialog but how can I retrieve the output and keep wait till use confirms?
this.runOnUiThread(new Runnable() {
public void run() {
boolean output = ConfirmUser(message);
}
});
I will say that it is bad idea. If you need a confirmation from user, you better split your AsyncTask in two parts: do some part first, then inside onPostExecute() you can show dialog (because it is running on ui thread) and, depending on user action, launch second AsyncTask.
If you still want to do it one AsyncTask, you can do it like this:
final BlockingQueue<Boolean> queue = new ArrayBlockingQueue<Boolean>(1);
this.runOnUiThread(new Runnable() {
public void run() {
// Assuming you have ConfirmUser method which returns boolean
queue.add(ConfirmUser(message));
}
});
Boolean result = null;
try {
// This will block until something will be added to the queue
result = queue.take();
} catch (InterruptedException e) {
// deal with it
}
This is my first post here so sorry if I don't format my question correctly.
I am developing my first Android app and it is a card game. I've developed the same card game in C# using visual studio. In C#, in order to simulate action and delay when dealing, etc, I slept the thread for a given amount of time, then called the method Application.DoEvents() which forced the UI to update. However, in java, I cannot seem to find an answer to this problem.
I'll post some code from my deal() method, which I need to delay so it looks like the cards are actually being dealt in a circle, and not all at once since the computer goes so fast:
private void dealHelper()
{
Hand pCards = Referee.getHumanHand();
//show all cards in rotating order
for(int i=0; i<CARD_COUNT; i++)
{
///////////////////////////////////////////////////////////////////////
// load each card into their appropriate ImageViews and make visible //
///////////////////////////////////////////////////////////////////////
//human player
LoadCard(playerCards.get(i), pCards.getCard(i));
playerCards.get(i).setVisibility(View.VISIBLE);
playerCards.get(i).setPadding(1, 1, 1, 1);
// allow discarded cards to be clickable
discardCardImages.get(i).setPadding(1, 1, 1, 1);
//computer 1
computer1Cards.get(i).setImageResource(R.drawable.cardskin);
computer1Cards.get(i).setVisibility(View.VISIBLE);
//computer 2
computer2Cards.get(i).setImageResource(R.drawable.cardskin);
computer2Cards.get(i).setVisibility(View.VISIBLE);
//computer 3
computer3Cards.get(i).setImageResource(R.drawable.cardskin);
computer3Cards.get(i).setVisibility(View.VISIBLE);
}
}
I need a slight delay of about 500ms between each card that is displayed on the screen to simulate action. I've searched and searched and haven't a solution that works (or I understand). Any help would be much appreciated.
Thank You,
Daniel
Use a Handler with a Runnable (which does one iteration of the loop in its run()) and postDelayed(Runnable r, long delayMillis) for the delay. Count the iterations so you know when to stop and use the last one to removeCallbacks() and call a method to do whatever needs to be once the dealing is done.
Something like
private final Handler mHandler = new Handler();
private int iLoopCount = 0;
private final Runnable rDealAndWait = new Runnable()
{
public void run()
{
if (dealtAHand())
{
++iLoopCount;
mHandler.postAtTime(this, SystemClock.uptimeMillis() + DEAL_DELAY);
}
else
{
doAfterAllHandsDealt();
}
}
};
private boolean dealtAHand()
{
if (i == CARD_COUNT) return false;
//human player
LoadCard(playerCards.get(iLoopCount), pCards.getCard(i));
playerCards.get(iLoopCount).setVisibility(View.VISIBLE);
playerCards.get(iLoopCount).setPadding(1, 1, 1, 1);
// etc
return true;
}
And then in the onCreate or wherever
dealtAHand();
mHandler.postAtTime(rDealAndWait, SystemClock.uptimeMillis() + DEAL_DELAY);
}
Try out Thread.sleep(long millis). You'll have to put it in a try/catch block.
If nothing works out for you from above solutions, then give a try to CountDownTimer here,
http://developer.android.com/reference/android/os/CountDownTimer.html
please check my answer here it may help you. dont know its proper way or not but it worked for me very fine.
#Override
public void run() {
for(int i = 0;i<diceNum;i++){
runOnUiThread(new Runnable() {
#Override
public void run() {
//do your Ui task here
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
First off I've been working with Java's Concurrency package quite a bit lately but I have found an issue that I am stuck on. I want to have and Application and the Application can have a SplashScreen with a status bar and the loading of other data. So I decided to use SwingUtilities.invokeAndWait( call the splash component here ). The SplashScreen then appears with a JProgressBar and runs a group of threads. But I can't seem to get a good handle on things. I've looked over SwingWorker and tried using it for this purpose but the thread just returns. Here is a bit of pseudo code. and the points I'm trying to achieve.
Have an Application that has a SplashScreen that pauses while loading info
Be able to run multiple threads under the SplashScreen
Have the progress bar of the SplashScreen Update-able yet not exit until all threads are done.
Launching splash screen
try {
SwingUtilities.invokeAndWait( SplashScreen );
} catch (InterruptedException e) {
} catch (InvocationTargetException e) { }
Splash screen construction
SplashScreen extends JFrame implements Runnable{
public void run() {
//run threads
//while updating status bar
}
}
I have tried many things including SwingWorkers, Threads using CountDownLatch's, and others. The CountDownLatch's actually worked in the manner I wanted to do the processing but I was unable to update the GUI. When using the SwingWorkers either the invokeAndWait was basically nullified (which is their purpose) or it wouldn't update the GUI still even when using a PropertyChangedListener. If someone else has a couple ideas it would be great to hear them. Thanks in advance.
I actually got ready to post better code to help out and found my solution. I thank you for all who helped.
For running a series of operations in the background and reporting progress, use SwingWorker.
The background method does the background processing.
Use the publish method to post periodic status updates.
Override the process method to handle the updates (process always executes on the EDT).
progressBar = new JProgressBar();
sw = new SwingWorker<Boolean,Integer>() {
protected Boolean doInBackground() throws Exception {
// If any of the operations fail, return false to notify done()
// Do thing 1
publish(25); // 25% done
// Do thing 2
publish(50); // 50% done
// Do thing 3
publish(75); // 75% done
// Do thing 4
return true;
}
protected void process(List<Integer> chunks) {
for (Integer i : chunks)
progressBar.setValue(i);
}
protected void done() {
try {
boolean b = get();
if (b)
progressBar.setValue(100); // 100% done
else
// Notify the user processing failed
}
catch (InterruptedException ex) {
// Notify the user processing was interrupted
}
catch (ExecutionException ex) {
// Notify the user processing raised an exception
}
}
};
Addendum:
This can be extended to multiple tasks, it just requires changing how you approach setting the progress bar. Here's what comes to mind:
Have an array of completion counter, one per task.
int[] completions = new int[numTasks];
Arrays.fill(completions,0);
Start the SwingWorkers, each passed an index number. The process or done methods then call something like this to update the overall progress bar.
void update(int index, int percComplete) {
completions[index] = percComplete;
int total = 0;
for(int comp: completions)
total += comp/numTasks;
overallPB.setValue(total);
}
Optionally, display a JProgressBar per task.
Addendum 2:
If the tasks vary in completion time (eg, cache hit vs cache miss), you may want to investigate ProgressMonitor. It's a progress dialog that only appears if the task takes more than some (configurable, default 500ms) amount of time.
No need to call the frame inside invokeAndWait but you should update progress bar state like this.
try {
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
//update state of the progress bar here
}
});
} catch (InterruptedException e) {
} catch (InvocationTargetException e) { }