Here is my Method i want to check a that a circle lies on the button for five seconds for this i have used a runnable.but a problem is that i want to check it every second that the position of the circle changes or not if the circle position have been changes then start the handler timer from start for the new position otherwise call the method
private Runnable createRunnable(int paramPosition)
{
Runnable aRunnable = new Runnable()
{
public void run()
{
handler.postDelayed(this, 1000);
if (numOfSeconds == 5)
{
handler.removeCallbacks(this);
numOfSeconds = 0;
if (paramPosition == circlePosition)
{
methodCall(paramPosition);
handler.removeCallbacks(this);
}
else
{
if (paramPosition == circlePosition)
{
numOfSeconds++;
}
else
{
numOfSeconds = 0;
}
handler.postDelayed(this, 5000);
}
}
}
return aRunnable;
};
}
so how i can perform this work please suggest a method to solve this problem.
thanks
Related
I have a code that plays 5 sounds with 1 second delay between the sounds and I want this part of code to be executed every 5 seconds (so it will run in a row so far as a boolean variable is true, and when it becomes false the tread run stopped - I have a button to both start and stop this executions). Everything works perfectly, but the issue is that I can't get rid of the 5 seconds delay in the first time I click the button, so when I first click, the sounds beggins only after 5 seconds. How can I make it start right away and only after the first time start taking the delays?
Here is the button onClick code:
public void clickHandlerStartTempo(final View view) {
if (!tempoOn) {
Toast toast = Toast.makeText(getApplicationContext(), "Start Tempo!", Toast
.LENGTH_SHORT);
toast.show();
tempoOn = true;
final Handler handler = new Handler();
final int delay = 5000; //milliseconds
handler.postDelayed(new Runnable() {
public void run() {
if (tempoOn) {
runCode(view);
handler.postDelayed(this, delay);
}
}
}, delay);
} else {
Toast toast = Toast.makeText(getApplicationContext(), "Stop Tempo!", Toast
.LENGTH_SHORT);
toast.show();
tempoOn = false;
}
}
And here is the runCode method:
public void runCode(View view) {
Runnable runnable = new Runnable() {
#Override
public void run() {
playSound(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 4; i++) {
if (tempoOn) {
playSound(1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
return;
}
}
}
};
Thread thread = new Thread(runnable);
Log.i(TAG, "runCode: Thread id = " + thread.getId());
thread.start();
}
I'm new to android development and any help would be very much appreciated.
Thanks.
First you need to playsound without thread after that you will execute your reaming 5 second logic stop thread after 4 count.
public void onStartPress(){
playSound();
someMethod();
}
public void someMethod(){
Handler uiHandler = new Handler(Looper.getMainLooper());
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
playSound();
someMethod();
}
},1000);
}
Don't use actual Threads unless you really want to do something off the Ui thread. Most of the time you do want to keep things on the Ui thread.
For simple repeating tasks, you can easily repurpose the CountDownTimer class. Often with an (almost) infinite run time or Long.MAX_VALUE (292 million years). The fist onTick happens immediately after starting.
private CountDownTimer mTimer;
private void start() {
if (mTimer == null) {
mTimer = new CountDownTimer(Long.MAX_VALUE, 5000) {
#Override
public void onTick(long millisUntilFinished) {
// start a beeping countdown
new CountDownTimer(5000, 1000) {
private int state = 1;
#Override
public void onTick(long millisUntilFinished) {
playSound(state);
state = state + 1 % 2;
}
#Override
public void onFinish() {
playSound(0);
}
}.start();
}
#Override
public void onFinish() { /* ignore, never happens */ }
};
mTimer.start();
}
}
private void stop() {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
It is a basic app where you click the shoot button when a picture appears. A picture appears once every 5 seconds. However, all of my images are loading at the same time using the code below.
I call loadImage to load an image, and then shootHandler to remove it after 5 seconds. I'm not sure if I need to use AsyncTask or something like that.
void run() {
int i;
for(i = 0; i < imageList.length; i++) {
loadImage(i);
shootHandler(i);
}
}
private void shootHandler(final int trialNumber) {
loadImage(trialNumber);
handler.postDelayed(new Runnable() {
public void run() {
resetButtons(trialNumber);
}
}, 5000);
}
private void loadImage(int trialNumber) {
Glide.with(getApplicationContext()).load(R.drawable.red_btn).into(shoot);
int resID = getApplication().getResources().getIdentifier(imageList[trialNumber].name, "drawable", getApplicationContext().getPackageName());
Glide.with(getApplicationContext()).load(resID).into(imageList[trialNumber].image);
}
You seem to expect that postDelayed blocks the calling thread, but that is false.
If you want to call these one after another, each call should schedule the next one. See https://stackoverflow.com/a/5996270/4388512
i couldn't figure out what is your point but to load Images in the prettiest way you can use this:
final Handler handler = new Handler();
new Runnable(){
int counter = 0;
#Override
public void run() {
counter++;
if(counter == list.size()){
return;
}
Picasso.with(context).load(list.get(counter - 1)).into(imageView);
handler.postDelayed(this, 5000);
}
}.run();
I'm designing a game and have a problem with countdowntimer not stopping. The timer starts normally as it should, and should stop in the end() method. It works well when ENEMY_HULL is checked as 0 or less, which is calulated seperatly when the users presses a button, and checkEnemyDefeat() is called, but it does not work when ENEMY_CREW is 0. On both situations the message in log cat that the timer is stopped appears, so my guess is that .cancel() is called. I've included all code that seems relevant.
NOTE: All variables including CountDownTimer are global variables
Here is the method containing the timer:
private void BadGameLoop() {
if (GAME_PAUSED == true && !GAME_TIME_STARTED) {
Log.d(" -------- ", "TIMER STARTED");
GAME_PAUSED = false;
GAME_TIME_STARTED = true;
gameTimer = new CountDownTimer(GAME_TIME, UPDATE_RATE) {
#Override
public void onTick(long millisUntilFinished) {
TICKS++;
timer.setText(String.valueOf(GAME_TIME / 1000 - TICKS / 10));
if((CREW_BOARDING > 0 || ENEMY_CREW_BOARDING > 0) && TICKS%10 == 0){
crewFightCalculator();
}
updateViews();
}
#Override
public void onFinish() {
TICKS=0;
GAME_TIME_STARTED = false;
GAME_PAUSED = true;
end();
}
};gameTimer.start();
}
}
Next is the crewFightCalculator method:
private void crewFightCalculator(){
// this just changes the values of ENEMY_CREW (global variable) and then
//calls checkEnemyDefeat() to verify if it should end the timer or not
checkEnemyDefeat();
}
The checkEnemyDefeat and end methods:
private void checkEnemyDefeat(){
if(ENEMY_HULL <= 0){
updateViews();
end();
}else if ( ENEMY_CREW < 1){
updateViews();
end();
}
}
private void end(){
if(GAME_TIME_STARTED){
GAME_TIME_STARTED = false;
gameTimer.cancel();
Log.d("---------"," TIMER STOPPED !");
}
// do more stuff
}
It is simply bizzare to me why it dosen't work. My only guess is that it has something to do with the fact that .cancel() is not triggered by a chain of functions started by user input .
The only solution to this problem that I found, was to modify the onTick method, so that it should check every time if it should run or stop the timer like this:
private void BadGameLoop() {
if (GAME_PAUSED == true && !GAME_TIME_STARTED) {
Log.d(" -------- ", "TIMER STARTED");
GAME_PAUSED = false;
GAME_TIME_STARTED = true;
gameTimer = new CountDownTimer(GAME_TIME, UPDATE_RATE) {
#Override
public void onTick(long millisUntilFinished) {
if(GAME_TIME_STARTED) {
TICKS++;
timer.setText(String.valueOf(GAME_TIME / 1000 - TICKS / 10));
if((CREW_BOARDING > 0 || ENEMY_CREW_BOARDING > 0) && TICKS%10 == 0){
crewFightCalculator();
}
updateViews();
}else{
gameTimer.cancel();
}}
#Override
public void onFinish() {
TICKS=0;
GAME_TIME_STARTED = false;
GAME_PAUSED = true;
end();
}
};gameTimer.start();
}
}
Still, i can't figure out why it didn't work properly before.
First, I used animation to hide and show TextView. I saw that using animation costing memory. So I used another way:
SetVisibility(VISIBLE) and SetVisibility(INVISIBLE) with TaskTimer
it works well and it performs better considering the memory.
The main issue is that after a restarting the timer for many times, the TextView disappear.
I need to restart the app to get it back again!
this is the code snippet:
myTimerForAnimation = new Timer();
myTimerForAnimation.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() // run on ui thread
{
public void run() {
counter++;
if (counter < 7) {
if (counter % 2 == 1) {
list_textView[x].setVisibility(View.INVISIBLE);
} else {
list_textView[x].setVisibility(View.VISIBLE);
}
} else {
myTimerForAnimation.cancel();
myTimerForAnimation.purge();
list_textView[x].setVisibility(View.VISIBLE);
}
}
});
}
}, 1000, 600);
Dont use Timer use handler,something like this:
// init the runnables
// the runnable should be members
Handler hanlder = new Handler();//If you arent on the UI thread pass a correct looper
for (int i=1; i<7 ; i++){
long delay = i * 1000;
if (i%2==0)
{
handler.postDelayed(mVisibleRunnable,delay);
}else{
handler.postDelayed(mInVisibleRunnable,delay);
}
}
Whereas the get runnablebs should be memebers because if u choose to cancel the callbacks then call
handler.removeCallbacks(runnable);
Play with it. It should fix your issue.
thanks to #EE66 for the loop idea, I used this code to solve my problem:
private void animateView(final View view){
for (int counter = 0; counter < 7; counter++) {
long delay = counter * 1000;
if (counter % 2 == 0) {
view.postDelayed(new Runnable() {
public void run() {
view.setVisibility(View.VISIBLE);
}
;
}, delay);
} else {
view.postDelayed(new Runnable() {
public void run() {
view.setVisibility(View.INVISIBLE);
}
;
}, delay);
}
}
}
I have used Countdown Timer like this
new CountDownTimer(15000, 15) {
public void onTick(long millisUntilFinished) {
long seconds=millisUntilFinished/1000;
long min=millisUntilFinished%100;
timeleft=(int) (seconds*1000+min);
if(millisUntilFinished>=10000)
{
changeText.setTextColor(Color.GREEN);
}
else if(millisUntilFinished>=5000)
{
changeText.setTextColor(Color.MAGENTA);
}
else
{
changeText.setTextColor(Color.RED);
}
changeText.setText(String.format("%02d", seconds )+ "."+String.format("%02d", min )+" sec");
}
public void onFinish() {
timeleft=0;
missed++;
nametext.setTextColor(Color.RED);
nametext.setText("Time Up!");
bottombutton.setVisibility(View.INVISIBLE);
globalflag=13;
changeText.setTextColor(Color.RED);
changeText.setText("0.00 Sec");
Handler myHandler = new Handler();
myHandler.postDelayed(mMyRunnablecif, 3000);
}
}.start();
On a button click I have called cancel() but it stops counting for a while and then calls onFinish(). I need not to call onFinish() after calling cancel(). Is there any solution for this. Any help will be highly appreciated.
Inside your onClick set a Boolean (buttonPressed for example) to true.
In your onFinish check this Boolean:
if (buttonPressed == true)
{
//do nothing
}
else
{
//run code
}
You could use Timer instead and do something like this:
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
// do your updates here
mUpdateTimeHandler.postDelayed(this, 1000);
}
};
Handler mUpdateTimeHandler = new Handler();
mUpdateTimeHandler.postDelayed(mUpdateTimeTask, 100);
When cancelling the task:
mUpdateTimeHandler.removeCallbacks(mUpdateTimeTask);
I also don't understand why the onFinish gets called despite calling cancel(). I guess the only workaround for this is to just null check your calls in onFinish to prevent any NPE's.
public void onFinish() {
if (nametext == null || bottombutton == null || changeText == null || ... ) {
return;
}
...