How do I wait one minute in my Android application without stopping the thread? I need to play a sound every minute for X rounds. I have all the code working except the waiting code.
public void startRounds(View v)
{
MediaPlayer mp = MediaPlayer.create(this, R.raw.ding);
mp.start();
EditText txtRounds = (EditText) findViewById(R.id.txtRounds);
rounds = Integer.parseInt(txtRounds.getText().toString());
oneSession();
}
private void oneSession()
{
//this needs to be replaced with my new wait one minute function
SystemClock.sleep(60000);
MediaPlayer mp2 = MediaPlayer.create(this, R.raw.ding);
mp2.start();
if (rounds != 1) {
rounds--;
oneSession();
}
}
Solved:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do something
}
}, 60 * 1000);
I am not sure if this is what you really want but it here do something will run after 60 * 1 seconds
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do something
}
}, 60 * 1000);
You can use Handler which will get executed without blocking thread.eg
handler.postDelayed(new Runnable() {
#Override
public void run() {
/**put your code inside this
* this method will get exceuted after 1 min without stopping thread
* same thing can be recursive based on your requirement*/
}
},60000);
Run the minute in another thread because on the UI Thread de sound will stop:
new Thread(new Runnable() {
#Override
public void run() {
try{
Thread.sleep(60000)
}catch(InterruptedExcpetion e){
}
}).start();
Related
I created a thread in Oncreate of an activity and then after the task ends then it makes changes to the UI of the activity. The task takes 5-6 seconds that's why I used the thread.
Here is the code:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
final String folderSize = calculateFolderSize(); // my work
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(folderSize + " GB");
}
});
}
});
thread.start();
Everything works fine, I start the activity then the size is calculated and then the textView gets updated and shows the size. It takes 6 seconds on average.
The problem - when I open the activity then the thread starts in the OnCreate method. If I press the back button before the thread completes then my application crashes in 6 seconds (when the thread completes its work).
What is the solution to this problem, is there any alternative or I need to stop the thread in back pressed in that activity.
It appears that your runOnUiThread code invokes after activity gets destroyed.
You should check if activity is destroyed:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
final String folderSize = calculateFolderSize(); // my work
runOnUiThread(new Runnable() {
#Override
public void run() {
if (!isDestroyed())
textView.setText(folderSize + " GB");
}
});
}
});
thread.start();
I want my Android app to do an auto demo, so after user clicks on a "Auto Demo" button, it will switch to a view and delay a second and click on a button on that view, then 2 seconds later click on another button on that screen .. so on, my java code looks like this :
private class AutoDemoListener implements View.OnClickListener
{
public void onClick(View v)
{
Is_AutoDemo_B=true;
Out("AutoDemoListener");
switchView(demoView, registrationView);
startRegistration();
Thread t = new Thread(new Runnable()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
try
{
registrationView.symbolButton[2][8].performClick();
Thread.sleep(1000);
registrationView.symbolButton[4][13].performClick();
Thread.sleep(2000);
registrationView.symbolButton[0][1].performClick();
Thread.sleep(1000);
registrationView.symbolButton[6][18].performClick();
}
catch (InterruptedException e) { e.printStackTrace(); }
}
});
}
});
t.start();
Is_AutoDemo_B=false;
}
}
But what it does now is : wait 4 seconds and simulate all 4 clicks at once, so there is no delay between each click, what's the right way to do it ?
You have to perform the delay in the background and post the results back to the UI each time.
You can do this using a Handler. The UI thread already comes with a prepared Looper that will allow you to easily use the Handler (other threads do not and require more setup).
The nesting of runnables would look nasty, so here it is with just adding increasing delays:
private class AutoDemoListener implements View.OnClickListener
{
public void onClick(View v)
{
Is_AutoDemo_B=true;
Out("AutoDemoListener");
switchView(demoView, registrationView);
startRegistration();
final Handler handler = new Handler();
registrationView.symbolButton[2][8].performClick();
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[4][13].performClick();
}
}, 1000);
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[0][1].performClick();
}
}, 3000);
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[6][18].performClick();
}
}, 5000);
handler.postDelayed(new Runnable() {
public void run() {
Is_AutoDemo_B=false;
}
}, 5100);
}
}
In Kotlin this could be much cleaner using a coroutine:
val autoDemoListener = View.OnClickListener {
Is_AutoDemo_B = true
Out("AutoDemoListener")
switchView(demoView, registrationView)
startRegistration()
CoroutineScope(Job() + Dispatchers.Main).launch {
registrationView.symbolButton[2][8].performClick()
delay(1000)
registrationView.symbolButton[4][13].performClick()
delay(2000)
registrationView.symbolButton[0][1].performClick()
delay(1000)
registrationView.symbolButton[6][18].performClick()
Is_AutoDemo_B=false
}
}
TimeUnit.SECONDS.sleep(1); see How do I make a delay in Java? is also in Android https://developer.android.com/reference/java/util/concurrent/TimeUnit
Maybe spawn new threads, sleep in these child threads and block the main threads until the child thread returns. #Tenfour04's answer is a similar concept to spawning threads i think ...
I need a thread to start after 3 seconds of a button being idle, is there a simple way of doing it?
I'm building a counter app, the button triggers two counters, the total counter and the "tapping counter", the tapping counter helps keep track of the actual change of values, showing how many taps the user did, I need it to vanish after some seconds so the user can tap again.
for stuffs like that I usually use a Handler with a Runnable in order to do stuff after X milliseconds the user isn't doing a specific action.
First, create a runnable and a handler
final android.os.Handler handler = new android.os.Handler();
private Runnable runnable;
private final long DELAY = 3000; // how many milliseconds you want to wait
Then add the onClickListener:
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
Then, inside onClick event, remove callbacks and istantiate the handler again as follows:
if(runnable != null) {
// in this case the user already clicked once at least
handler.removeCallbacks(runnable);
}
runnable = new Runnable() {
#Override
public void run() {
//this code will run when user isn't clicking for the time you set before.
}
};
handler.postDelayed(runnable, DELAY);
Final result:
final android.os.Handler handler = new android.os.Handler();
private Runnable runnable;
private final long DELAY = 3000; // how many milliseconds you want to wait
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// all your previous stuffs
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(runnable != null) {
// in this case the user already clicked once at least
handler.removeCallbacks(runnable);
}
runnable = new Runnable() {
#Override
public void run() {
//this code will run when user isn't clicking for the time you set before.
}
};
handler.postDelayed(runnable, DELAY);
}
});
}
I hope this helps, for any question feel free to ask
Handler may work in this scenario, with a 3000 milisecond delay.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// do action
}
}, 3000);
At first, you create a Timer with a TimerTask(with your Thread) and schedule it to run after 3 seconds.
Every time the button is pressed, you reset the timer.
public class MyClass{
private Timer timer=new Timer()
private TimerTask task=new TimerTask(){
public void run(){
//your action
}
};
public void init(){
timer.schedule(task,3000);
}
public void onButtonClick(){
task.cancel();
timer.schedule(task,3000);
}
}
I want to repeatedly call a method after every 5-seconds and whenever I wish to to stop the repeated call of the method I may stop or restart the repeated call of the method.
Here is some sample code that whats really I want to implement. Please help me in this respect I would be very thankful to you.
private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handler m_handler;
#Override
protected void onCreate(Bundle bundle)
{
...
m_handler = new Handler();
}
Runnable m_statusChecker = new Runnable()
{
#Override
public void run() {
updateStatus(); //this function can change value of m_interval.
m_handler.postDelayed(m_statusChecker, m_interval);
}
};
public void startRepeatingTask()
{
m_statusChecker.run();
}
public void stopRepeatingTask()
{
m_handler.removeCallbacks(m_statusChecker);
}
Set repeated task using this:
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
and if you wanted to cancel the task simply call t.cancel() here t is your Timer object
and you can also check comment placed below your answer they have given brief information about that.
Use a Handler in the onCreate() method. Its postDelayed() method causes the Runnable to be added to the message queue and to be run after the specified amount of time elapses (that is 0 in given example). Then this will queue itself after fixed rate of time (1000 milliseconds in this example).
Refer this code :
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
android.os.Handler customHandler = new android.os.Handler();
customHandler.postDelayed(updateTimerThread, 0);
}
private Runnable updateTimerThread = new Runnable()
{
public void run()
{
//write here whaterver you want to repeat
customHandler.postDelayed(this, 1000);
}
};
use TimerTask to call after specific time interval
Timer timer = new Timer();
timer.schedule(new UpdateTimeTask(),1, TimeInterval);
and
class UpdateTimeTask extends TimerTask {
public void run()
{
// do stufff
}
}
Do it in Android's way with the help of Handler.
Declare a Handler which does not leak Memory
/**
* Instances of static inner classes do not hold an implicit
* reference to their outer class.
*/
private static class NonLeakyHandler extends Handler {
private final WeakReference<FlashActivity> mActivity;
public NonLeakyHandler(FlashActivity activity) {
mActivity = new WeakReference<FlashActivity>(activity);
}
#Override
public void handleMessage(Message msg) {
FlashActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
Declare a runnable which handle your task
private Runnable repeatativeTaskRunnable = new Runnable() {
public void run() {
new Handler(getMainLooper()).post(new Runnable() {
#Override
public void run() {
//DO YOUR THINGS
}
};
Initialize handler object in your Activity/Fragment
//Task Handler
private Handler taskHandler = new NonLeakyHandler(FlashActivity.this);
Repeat task after fix time interval
taskHandler.postDelayed(repeatativeTaskRunnable , DELAY_MILLIS);
Stop repetition
taskHandler .removeCallbacks(repeatativeTaskRunnable );
You have to put this code inside the activity you want to call every 5 seconds
final Runnable tarea = new Runnable() { public void run() {
hola_mundo();//the operation that you want to perform }};
ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();
timer.scheduleAtFixedRate(tarea, 5, 5, TimeUnit.SECONDS);
I want to run the same functions in onCreate() and onResume(). The functions basically record in 10 seconds and then stop and play the recorded sound.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new CountDownTimer(
10000, // 10 second countdown
9999) { // onTick time, not used
public void onTick(long millisUntilFinished) {
// Not used
}
public void onFinish() {
isRecording = false;
}
}.start();
Thread thread = new Thread(new Runnable() {
public void run() {
isRecording = true;
record(); // starts to record
}
});
thread.start(); // thread start
// thread to start
play();
}
If I hit the Home button, then the app got put into the background. Now if I hit the app's icon button again, I'd like to call the same recording and playing functions.
Can I do same thing like this in onResume()? Basically duplicate the same thing.
public void onResume() {
super.onResume();
new CountDownTimer(
10000, // 10 second countdown
9999) { // onTick time, not used
public void onTick(long millisUntilFinished) {
// Not used
}
public void onFinish() {
isRecording = false;
}
}.start();
Thread thread = new Thread(new Runnable() {
public void run() {
isRecording = true;
record(); // starts to record
}
});
thread.start(); // thread start
play();
}
Just put the stuff you want to run in onResume(). onResume() will get called after onCreate() the first time then it will get called each time the application comes out of the background.
Activity lifecycle can be found (visually) here:
http://developer.android.com/reference/android/app/Activity.html