I'm new in android programming. I have a problem in postDelayed wherein the delay only execute once inside a loop even if the value that I want to call is more than 1.
here is my code
protected void managerOfSound() {
int size = tempq.size();
for (int i = 0; i < tempq.size(); i++) {
String u =tempq.get(i);
//WHOLE
if (u.equals("a4")){
mp = MediaPlayer.create(this, R.raw.a4);
handler.postDelayed(new Runnable(){
#Override
public void run() {
mp.start();
}
},2000);
}else if (u.equals("b4")){
mp = MediaPlayer.create(this, R.raw.b4);
handler.postDelayed(new Runnable(){
#Override
public void run() {
mp.start();
}
},2000);
}
}
}
For example
before playing the mediaplayer, i want a delay of 2 seconds and another 2 seconds so on and so forth depending on how many values i want to call... like for example the values are a4, a4 and a4. i want a delay of 2 seconds everytime the values are called. Is there anyone who can help mo with this? thanks in advance! :)
well your problem is that you are running postDelayedfrom inside a for loop. you do run the handler n times BUT simultaneously. you start all of them at the same time (because it takes less than a milli to finish the foor loop). you should
put a counter on the amount of time. something like
handler.postDelayed(new Runnable(){
#Override
public void run() {
mp.start();
}
},countr += 2000);
Here is a working sample of a runnable with delay timer.
public Runnable timedTask = new Runnable()
{
#Override
public void run()
{
// type code here which will loop with the given delay
//if you want to end the runnable type this in the condition
if(condition) {
handler.removeCallbacks(this);
return;
}
//delay for the runnable
handler.postDelayed(timedTask, 2000);
}
};
and you can call this method from anywhere by typing:
handler.post(timedTask);
hope it helps!
Related
I want to print the current second using a handler. I record a video for exactly 10 seconds and want to set the text of a TextView every second.
Recording 10 seconds works like that:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
stopRecordingVideo();
}
}, 11000); // don't know why 11000 but it only works this way
After the 10 seconds the method stopRecordingVideo() gets executed. So how can I change the text every second of the TextView?
Working answer:
int t = 0;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
t++;
textView.setText(getString(R.string.formatted_time, t));
if(t<10) {
handler.postDelayed(this, 1000);
}
}
}, 1000);
Where formatted_time is something like that:
<string android:name="formatted_time">%d seconds</string>
To print text every second, you can use CountDownTimer. But if you want to achieve this with try below code:
void startTime(){
//Post handler after 1 second.
handler.postDelayed(runnable, 1000);
}
int totalDelay=0;
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
totalDelay++;
if(totalDelay<=10){
//If total time is less then 10 second execute handler again after 1 second
handler.postDelayed(runnable, 1000);
}
textView.setText(totalDelay+" Second");
}
};
Try this, basically do the increment in a worker thread, but updating the text view is done by main's thread handler.
Thread worker= new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// stop recording after 10 seconds
if (i == 9) {
handler.post(new Runnable() {
#Override
public void run() {
stopRecordingVideo();
}
});
}
else{
// set text for each second
handler.post(new Runnable() {
#Override
public void run() {
textView.setText(String.valueOf(i+1));
}
});
}
}//ends for()
worker.start()
Handler handler = new Handler();
if (v.getId() == R.id.play){
handler.postDelayed(new Runnable() {
public void run() {
play.setBackgroundResource(R.drawable.ilk);
}
}, 2000);
play.setText("Play");
}
I want to set background first and then after 2 seconds later, code will continue next line which is play.setText("Play"); and goes like that. Instead of this, first text appears. 2 seconds later background changes.
Handler.postDelayed returns immediately. And next line is executed.
After indicated milliseconds, the Runnable will be executed.
So your code should be like this:
void doFirstWork() {
Handler handler = new Handler();
if (v.getId() == R.id.play){
handler.postDelayed(new Runnable() {
public void run() {
play.setText("Play");
doNextWork();
}
}, 2000);
play.setBackgroundResource(R.drawable.ilk);
}
}
void doNextWork() {
...
}
Set the background first. After that set the text within Handler. As you've put delays at the end of postDelayed so it'll fire right after that stated delays or in your case after 2 sec.
if (v.getId() == R.id.play){
play.setBackgroundResource(R.drawable.ilk);
new Handler().postDelayed(new Runnable() {
public void run() {
play.setText("Play");
}
}, 2000);
}
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 am updating a counter in thread and its working fine.
But when the phone is in sleep and activity runs after aquiring wakelock, the thread not updates the UI using counter.
Here is my function where I am updating the view value.
private void updateTimeInBackground() {
new Thread(new Runnable() {
#Override
public void run() {
startAlarm();
int counter = MINUTE;
// in this function Im using the runOnUiThread(...) to update the view and also used TextView.post(...)
updateTextViewValue(counter);
if (isDismissed)
return;
updateOverlayForAlert();
counter = 0;
int minutes = 1;
vibrator.vibrate(1000);
// in this function Im using the runOnUiThread(...) to update the view and also used TextView.post(...)
updateTextViewValue(counter, minutes);
}
}).start();
Any suggestions? or hint?
Use TimerTask which will continue to run in the background.
Hope this helps.
Use Handler and Runnable instead of Thread
final Handler handler=new Handler();
runnable=new Runnable() {
#Override
public void run() {
handler.postDelayed(runnable, 5000);
// your code
}
};
runnable.run();
I am working on a Testing Project for me , just so I could learn more , so now I need to update the text of a TextView constantly every 250 milliseconds through a for(;;) loop , it happens after a Button click ... My problem is that whenever I press that button my app freezes (Yes my button is totally working , verified through previous testings) , I am using a handler to the Main thread doesn't get affected while the Runnable is up ... Here is my code of the Button and Handler ...
final Handler handler = new Handler();
B3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
for(;;){
String a = Shells.sendSingleCommand("free");//Here I send a command "free" and it returns its output
text.setText(a);//text is my TextView which is used through my experimentations ...
synchronized(this){
try{
wait(250);
}catch(Exception e){
}
}
}
}
});
}
});
If you need anymore info ask please :)
use handler.postDelayed for updating textview constantly every 250 milliseconds instead of using for loop to avoid freeze current Activity as :
Handler handler=new Handler();
B3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(runnable);
}
});
Runnable runnable=new Runnable(){
#Override
public void run() {
String a = Shells.sendSingleCommand("free");
text.setText(a);
handler.postDelayed(runnable, 250);
}
};
Android doesnt allow you to do long tasks in the main thread. If you need to do something like this I recommend moving the for loop and depdendent code into a separate thread..